Files
pepperOS/src/io/term/term.c

142 lines
3.1 KiB
C

/*
* @author xamidev <xamidev@riseup.net>
* @brief Framebuffer-based terminal driver
* @license GPL-3.0-only
*/
// Terminal output
/*
There are a couple of bugs here and there but for now I don't care too much
because this shitty implementation will be replaced one day by Flanterm
(once memory management is okay: paging & kernel malloc)
*/
#include <stddef.h>
#include <kernel.h>
#include <io/term/term.h>
#include <config.h>
#include <io/term/flanterm.h>
#include <io/term/flanterm_backends/fb.h>
#include <mem/kheap.h>
#include <limine.h>
#include <stdarg.h>
#include <sched/spinlock.h>
#include <io/serial/serial.h>
#define NANOPRINTF_IMPLEMENTATION
#include <io/term/nanoprintf.h>
extern struct flanterm_context* ft_ctx;
extern struct init_status init;
struct spinlock_t term_lock = {0};
struct spinlock_t printf_lock = {0};
extern int panic_count;
/*
* internal_putc - Internal putchar function
* @c: char to print
* @_: (unused, for nanoprintf)
*
* Prints a character to the terminal if it's ready,
* and also to the serial interface if it's ready.
*/
void internal_putc(int c, void *_)
{
(void)_;
char ch = (char)c;
if (init.terminal) {
if (panic_count == 0) {
spinlock_acquire(&term_lock);
flanterm_write(ft_ctx, &ch, 1);
spinlock_release(&term_lock);
} else {
flanterm_write(ft_ctx, &ch, 1);
}
}
if (init.serial) {
if (ch == '\n') {
skputc('\r');
}
skputc(ch);
}
}
/*
* printf - Fromatted printing
* @fmt: format string
* @...: variadic arguments
*
* Wrapper for nanoprintf
*
* Return:
* <ret> - number of characters sent to the callback
* %-1 - error
*/
int printf(const char* fmt, ...)
{
if (panic_count == 0) {
spinlock_acquire(&printf_lock);
va_list args;
va_start(args, fmt);
int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
va_end(args);
spinlock_release(&printf_lock);
return ret;
} else {
va_list args;
va_start(args, fmt);
int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
va_end(args);
return ret;
}
return -1;
}
/*
* kputs - Kernel puts
* @str: String to write
*
* Writes a non-formatted string to terminal
*/
void kputs(const char* str)
{
size_t i=0;
while (str[i] != 0) {
internal_putc(str[i], NULL);
i++;
}
}
extern struct flanterm_context* ft_ctx;
extern struct boot_context boot_ctx;
/*
* term_init - Video output/terminal initialization
*
* Uses Flanterm and the framebuffer given by Limine.
*/
void term_init()
{
uint32_t bgColor = 0x252525;
ft_ctx = flanterm_fb_init(
NULL,
NULL,
boot_ctx.fb->address, boot_ctx.fb->width, boot_ctx.fb->height, boot_ctx.fb->pitch,
boot_ctx.fb->red_mask_size, boot_ctx.fb->red_mask_shift,
boot_ctx.fb->green_mask_size, boot_ctx.fb->green_mask_shift,
boot_ctx.fb->blue_mask_size, boot_ctx.fb->blue_mask_shift,
NULL,
NULL, NULL,
&bgColor, NULL,
NULL, NULL,
NULL, 0, 0, 1,
0, 0,
0,
0
);
init.terminal = true;
}