LF OS
Hobby operating system for amd64 with high ambitions
Loading...
Searching...
No Matches
fbconsole.c
Go to the documentation of this file.
1#include <fbconsole.h>
2#include <mm.h>
3#include <vm.h>
4#include <log.h>
5#include <scheduler.h>
6
7#include <string.h>
8#include <stdarg.h>
9
10#include <config.h>
11#include "font_acorn_8x8.c"
12
13bool fbconsole_active = false;
14
28
30
31void fbconsole_init(int width, int height, int stride, uint8_t* fb) {
35 fbconsole.fb = fb;
37
38 fbconsole.cols = width / (FONT_WIDTH + FONT_COL_SPACING);
39 fbconsole.rows = height / (FONT_HEIGHT + FONT_ROW_SPACING);
42
49
50 memcpy(fbconsole.palette, (int[16][3]){
51 { 0, 0, 0 },
52 { 170, 0, 0 },
53 { 0, 170, 0 },
54 { 170, 170, 0 },
55 { 0, 0, 170 },
56 { 170, 0, 170 },
57 { 0, 170, 170 },
58 { 170, 170, 170 },
59 { 85, 85, 85 },
60 { 255, 85, 85 },
61 { 85, 255, 85 },
62 { 255, 255, 85 },
63 { 85, 85, 255 },
64 { 255, 85, 255 },
65 { 85, 255, 255 },
66 { 255, 255, 255 },
67 }, sizeof(int) * 16 * 3);
68
69 fbconsole_active = true;
70
71 if(!fb) {
72 logi("fbconsole", "No framebuffer, will not actually render anything");
73 return;
74 }
75
77
78 logd("framebuffer", "framebuffer console @ 0x%x (0x%x) %dx%d (stride %d)",
79 fb,
82 );
83}
84
86 if(!fbconsole.fb) {
87 return;
88 }
89
90 size_t backbuffer_size = fbconsole.stride * fbconsole.height * 4;
91 size_t backbuffer_num_pages = (backbuffer_size + 4095) / 4096;
92
94
97
98 for(ptr_t page = (ptr_t)fbconsole.fb; page < (ptr_t)(fbconsole.fb + (fbconsole.stride * fbconsole.height * 4)); page += 4096) {
100 }
101}
102
103void fbconsole_clear(int r, int g, int b) {
104 if(!fbconsole_active) {
105 logd("fbconsole", "was in userspace control, fbconsole_clear gave it back to kernel");
106 fbconsole_active = true;
107 }
108
109 if(!fbconsole.fb) {
110 return;
111 }
112
113 memset32((uint32_t*)fbconsole.backbuffer, (r << 16) | (g << 8) | (b << 0), fbconsole.stride * fbconsole.height);
114
116 memset32((uint32_t*)fbconsole.fb, (r << 16) | (g << 8) | (b << 0), fbconsole.stride * fbconsole.height);
117 }
118
121}
122
124 if(!fbconsole.fb) {
125 return;
126 }
127
128 if(tx < 0) tx = fbconsole.width + tx;
129 if(ty < 0) ty = fbconsole.height + ty;
130
131 if(tx < 0) tx = 0;
132 if(ty < 0) ty = 0;
133
134 for(uint16_t y = 0; y < height; ++y) {
135 size_t imgRow = y * width * 4;
136 size_t fbRow = (ty + y) * fbconsole.stride * 4;
137 for(uint16_t x = 0; x < width && x + tx < fbconsole.width; ++x) {
138 size_t imgCol = imgRow + (x * 4);
139 size_t fbCol = fbRow + ((tx + x) * 4);
140
141 fbconsole.backbuffer[fbCol + 2] = image[imgCol + 0];
142 fbconsole.backbuffer[fbCol + 1] = image[imgCol + 1];
143 fbconsole.backbuffer[fbCol + 0] = image[imgCol + 2];
144 fbconsole.backbuffer[fbCol + 3] = 0;
145 }
146
148 memcpy(fbconsole.fb + fbRow + (tx * 4), fbconsole.backbuffer + fbRow + (tx * 4), width * 4);
149 }
150 }
151}
152
153void fbconsole_setpixel(const int x, const int y, const int r, const int g, const int b) {
154 if(!fbconsole.fb) {
155 return;
156 }
157
158 int index = ((y * fbconsole.stride) + x) * 4;
159 fbconsole.backbuffer[index + 2] = r;
160 fbconsole.backbuffer[index + 1] = g;
161 fbconsole.backbuffer[index + 0] = b;
162 fbconsole.backbuffer[index + 3] = 0;
163
165 index /= 4;
166 ((uint32_t*)fbconsole.fb)[index] = ((uint32_t*)fbconsole.backbuffer)[index];
167 }
168}
169
170void fbconsole_draw_char(int start_x, int start_y, char c) {
171 if(!fbconsole.fb) {
172 return;
173 }
174
175 for(int y = 0; y < FONT_HEIGHT && y + start_y < fbconsole.height; y++) {
176 for(int x = 0; x < FONT_WIDTH && x + start_x < fbconsole.width; x++) {
177 if(FONT_NAME[(c * FONT_HEIGHT) + y] & (0x80 >> x)) {
179 }
180 else {
182 }
183 }
184 }
185}
186
187void fbconsole_scroll(unsigned int scroll_amount) {
188 if(!fbconsole.fb) {
189 return;
190 }
191
192 size_t row_start = scroll_amount * (FONT_HEIGHT + FONT_ROW_SPACING);
193 size_t begin = row_start * fbconsole.stride * 4;
194 size_t end = fbconsole.stride * fbconsole.height * 4;
195
196 memcpy(fbconsole.backbuffer, fbconsole.backbuffer + begin, end - begin);
197
198 memset32(
199 (uint32_t*)(fbconsole.backbuffer + (end - (row_start * 4 * fbconsole.stride))),
201 row_start * fbconsole.stride
202 );
203
206 }
207}
208
210 if(!fbconsole.fb) {
211 return;
212 }
213
216
220 }
221}
222
223int fbconsole_write(char* string, ...) {
224 if(!fbconsole.fb) {
225 return 0;
226 }
227
228 va_list args;
229 char buffer[512];
230 memset((uint8_t*)buffer, 0, 512);
231
232 va_start(args, string);
233 int count = kvsnprintf(buffer, 512, string, args);
234 va_end(args);
235
236 int i = 0;
237 int inside_ansi_sequence = 0;
238 int ansi_command = 0;
239 int ansi_args[8] = {0, 0, 0, 0, 0, 0, 0, 0};
240 int ansi_parse_step = 0;
241
242 while(count-- && i < 512) {
243 char c = buffer[i++];
244
245 if(inside_ansi_sequence) {
246 if(c == ';') {
247 ++ansi_parse_step;
248 continue;
249 }
250 else if(c == 'm') {
251 inside_ansi_sequence = 0;
252
253 switch(ansi_command) {
254 case 38:
255 if(ansi_args[0] == 5) {
256 fbconsole.foreground_r = fbconsole.palette[ansi_args[1]][0];
257 fbconsole.foreground_g = fbconsole.palette[ansi_args[1]][1];
258 fbconsole.foreground_b = fbconsole.palette[ansi_args[1]][2];
259 }
260 else if(ansi_args[0] == 2) {
261 fbconsole.foreground_r = ansi_args[1];
262 fbconsole.foreground_g = ansi_args[2];
263 fbconsole.foreground_b = ansi_args[3];
264 }
265 break;
266 case 48:
267 if(ansi_args[0] == 5) {
268 fbconsole.background_r = fbconsole.palette[ansi_args[1]][0];
269 fbconsole.background_g = fbconsole.palette[ansi_args[1]][1];
270 fbconsole.background_b = fbconsole.palette[ansi_args[1]][2];
271 }
272 else if(ansi_args[0] == 2) {
273 fbconsole.foreground_r = ansi_args[1];
274 fbconsole.foreground_g = ansi_args[2];
275 fbconsole.foreground_b = ansi_args[3];
276 }
277 break;
278 }
279
280 continue;
281 }
282
283 if(ansi_parse_step == 0) {
284 ansi_command *= 10;
285 ansi_command += c - '0';
286 }
287 else {
288 ansi_args[ansi_parse_step-1] *= 10;
289 ansi_args[ansi_parse_step-1] += c - '0';
290 }
291
292 continue;
293 }
294
295 if(c == '\n') {
297 continue;
298 }
299 else if(c == '\r') {
301 continue;
302 }
303 else if(c == 0x1B && buffer[i] == '[') {
304 ++i;
305 inside_ansi_sequence = 1;
306
307 ansi_command = 0;
308 ansi_parse_step = 0;
309 memset((void*)ansi_args, 0, sizeof(int) * 8);
310 continue;
311 }
312 else if(c == 0) {
313 break;
314 }
315
316 fbconsole_draw_char(fbconsole.current_col++ * (FONT_WIDTH + FONT_COL_SPACING), fbconsole.current_row * (FONT_HEIGHT + FONT_ROW_SPACING), c);
317
320 }
321 }
322
323 return i;
324}
325
327 if(fbconsole_active) {
331 *colorFormat = 0; // to be specified
332
333 if(fbconsole.fb) {
335 fbconsole_clear(0, 0, 0);
336 fbconsole_active = false;
337
338 logd("fbconsole", "Gave up control of framebuffer, now process %d is in charge", scheduler_current_process);
339 } else {
340 *fb = 0;
341
342 logd("fbconsole", "Would have gave up control of framebuffer to process %d, but we don't have one", scheduler_current_process);
343 }
344
345 }
346}
347
349 // For now just set fbconsole_active again in future this might also unmap
350 // it from userspace programs or kill them.
351 // Used by panic to render them onto the screen, without using
352 // fbconsole_clear, which also removes all the maybe-helpful screen
353 // contents.
354 fbconsole_active = true;
355}
signed short int16_t
Definition arch.h:7
unsigned short uint16_t
Definition arch.h:8
uint64_t ptr_t
Definition arch.h:17
unsigned int uint32_t
Definition arch.h:11
unsigned long uint64_t
Definition arch.h:14
unsigned char uint8_t
Definition arch.h:5
uint8_t * fb
Definition fbconsole.c:19
void sc_handle_hardware_framebuffer(ptr_t *fb, uint16_t *width, uint16_t *height, uint16_t *stride, uint16_t *colorFormat)
Definition fbconsole.c:326
void fbconsole_next_line(void)
Definition fbconsole.c:209
uint8_t * backbuffer
Definition fbconsole.c:20
void fbconsole_init_backbuffer(void)
Definition fbconsole.c:85
void fbconsole_blt(const uint8_t *image, uint16_t width, uint16_t height, int16_t tx, int16_t ty)
Definition fbconsole.c:123
void fbconsole_scroll(unsigned int scroll_amount)
Definition fbconsole.c:187
bool fbconsole_active
Definition fbconsole.c:13
void fbconsole_back_to_kernel(void)
Definition fbconsole.c:348
void fbconsole_clear(int r, int g, int b)
Definition fbconsole.c:103
void fbconsole_draw_char(int start_x, int start_y, char c)
Definition fbconsole.c:170
int palette[16][3]
Definition fbconsole.c:26
int fbconsole_write(char *string,...)
Definition fbconsole.c:223
static struct fbconsole_data fbconsole
Definition fbconsole.c:29
void fbconsole_init(int width, int height, int stride, uint8_t *fb)
Definition fbconsole.c:31
void fbconsole_setpixel(const int x, const int y, const int r, const int g, const int b)
Definition fbconsole.c:153
#define ALLOCATOR_REGION_KERNEL_HEAP
Definition vm.h:25
void * memcpy(void *dest, void const *source, size_t size)
Definition string.c:80
void * memset(void *dest, int c, size_t size)
Definition string.c:72
void memset32(uint32_t *dest, uint32_t c, size_t size)
Definition string.c:66
size_t kvsnprintf(char *buffer, size_t buffer_size, const char *format, va_list args)
Definition string.c:224
#define logd(component, fmt,...)
Definition log.h:28
#define logi(component, fmt,...)
Definition log.h:36
ptr_t scheduler_map_hardware(ptr_t hw, size_t len)
Map a given memory area in the currently running userspace process at a random location.
Definition scheduler.c:605
volatile pid_t scheduler_current_process
Definition scheduler.c:50
#define va_start(ap, X)
Definition stdarg.h:6
#define va_end(ap)
Definition stdarg.h:8
__builtin_va_list va_list
Definition stdarg.h:4
static uint16_t uint16_t uint16_t uint16_t * colorFormat
Definition syscalls.h:104
static uint16_t uint16_t * height
Definition syscalls.h:104
static uint16_t * width
Definition syscalls.h:104
static uint16_t uint16_t uint16_t * stride
Definition syscalls.h:104
#define FONT_HEIGHT
Definition main.c:18
#define FONT_WIDTH
Definition main.c:17
ptr_t vm_context_alloc_pages(struct vm_table *context, region_t region, size_t num)
Definition vm.c:560
void vm_context_map(struct vm_table *pml4, ptr_t virtual, ptr_t physical, uint8_t pat)
Definition vm.c:406
ptr_t vm_context_get_physical_for_virtual(struct vm_table *context, ptr_t virtual)
Definition vm.c:475
struct vm_table * VM_KERNEL_CONTEXT
Definition vm.c:16