331 lines
10 KiB
C
331 lines
10 KiB
C
|
|
#include <blue/term/tty.h>
|
||
|
|
#include <blue/core/hash.h>
|
||
|
|
#include "tty.h"
|
||
|
|
#include "printf.h"
|
||
|
|
|
||
|
|
#define MOD_HASH_BLACK 0x4b5dd0abbc6fc1e4
|
||
|
|
#define MOD_HASH_RED 0x89e9be1960f4c21c
|
||
|
|
#define MOD_HASH_GREEN 0x0f40f029637fecbc
|
||
|
|
#define MOD_HASH_YELLOW 0x8346a574925e75a9
|
||
|
|
#define MOD_HASH_BLUE 0xc5ccd29bc2dda64d
|
||
|
|
#define MOD_HASH_MAGENTA 0x6c90e772edbc8708
|
||
|
|
#define MOD_HASH_CYAN 0x70ae2e90c1bce27a
|
||
|
|
#define MOD_HASH_WHITE 0xced973885856e206
|
||
|
|
|
||
|
|
#define MOD_HASH_DARK_GREY 0x55a19de854654d99
|
||
|
|
#define MOD_HASH_BRIGHT_RED 0xbad8e3fe841b9385
|
||
|
|
#define MOD_HASH_BRIGHT_GREEN 0x11cc5e579bdd2fb9
|
||
|
|
#define MOD_HASH_BRIGHT_YELLOW 0xfd579007fe8579f6
|
||
|
|
#define MOD_HASH_BRIGHT_BLUE 0x57c76bf18badb6d6
|
||
|
|
#define MOD_HASH_BRIGHT_MAGENTA 0xf6ecc6d3fdfec129
|
||
|
|
#define MOD_HASH_BRIGHT_CYAN 0x03df73fd4e12ec6d
|
||
|
|
#define MOD_HASH_BRIGHT_WHITE 0xb5ebc3323f57d7fb
|
||
|
|
|
||
|
|
#define MOD_HASH_BG_BLACK 0xd87a8f2d9d394432
|
||
|
|
#define MOD_HASH_BG_RED 0x145b1e4366c7d7aa
|
||
|
|
#define MOD_HASH_BG_GREEN 0xa00b8541d3b1e55a
|
||
|
|
#define MOD_HASH_BG_YELLOW 0x98b030fd86e3b3cf
|
||
|
|
#define MOD_HASH_BG_BLUE 0xa15529109506b5df
|
||
|
|
#define MOD_HASH_BG_MAGENTA 0x86dbda99bcc86222
|
||
|
|
#define MOD_HASH_BG_CYAN 0xf16a3104cf61a098
|
||
|
|
#define MOD_HASH_BG_WHITE 0x3408c46ab5836674
|
||
|
|
|
||
|
|
#define MOD_HASH_BG_DARK_GREY 0x820d2e77568eec47
|
||
|
|
#define MOD_HASH_BRIGHT_BG_RED 0x144f5dc138087701
|
||
|
|
#define MOD_HASH_BRIGHT_BG_GREEN 0xc4d88c6426ffe355
|
||
|
|
#define MOD_HASH_BRIGHT_BG_YELLOW 0xf7bb000a4a792602
|
||
|
|
#define MOD_HASH_BRIGHT_BG_BLUE 0x9b5c16d6807a1002
|
||
|
|
#define MOD_HASH_BRIGHT_BG_MAGENTA 0xc59fb2196cdba3fd
|
||
|
|
#define MOD_HASH_BRIGHT_BG_CYAN 0x46feb6dc999a6f09
|
||
|
|
#define MOD_HASH_BRIGHT_BG_WHITE 0xa3e7d1da08826f5f
|
||
|
|
|
||
|
|
#define MOD_HASH_BOLD 0xcd32ea9bc6b26ff6
|
||
|
|
#define MOD_HASH_ULINE 0x141fe741e9f8c22a
|
||
|
|
#define MOD_HASH_ITALIC 0x69d5e5f057d8992d
|
||
|
|
#define MOD_HASH_INVERT 0xab4ab85ddd6232e1
|
||
|
|
#define MOD_HASH_RESET 0x0f136ff2c086b760
|
||
|
|
|
||
|
|
#define COMPARE_MOD_NAME(ss, sd, hs, hd) ((hs) == (hd) && !strcmp(ss, sd))
|
||
|
|
|
||
|
|
static void apply_code_to_vmode(struct tty_format_buf *fmt)
|
||
|
|
{
|
||
|
|
const char *modifier = fmt->buf;
|
||
|
|
uint64_t mod_hash = b_hash_string(modifier);
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "black", mod_hash, MOD_HASH_BLACK)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BLACK;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "red", mod_hash, MOD_HASH_RED)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_RED;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "green", mod_hash, MOD_HASH_GREEN)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_GREEN;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "yellow", mod_hash, MOD_HASH_YELLOW)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_YELLOW;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "blue", mod_hash, MOD_HASH_BLUE)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BLUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "magenta", mod_hash, MOD_HASH_MAGENTA)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_MAGENTA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "cyan", mod_hash, MOD_HASH_CYAN)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_CYAN;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "white", mod_hash, MOD_HASH_WHITE)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_WHITE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "dark_grey", mod_hash, MOD_HASH_DARK_GREY)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLACK;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_red", mod_hash, MOD_HASH_BRIGHT_RED)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_RED;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_green", mod_hash, MOD_HASH_BRIGHT_GREEN)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_GREEN;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_yellow", mod_hash, MOD_HASH_BRIGHT_YELLOW)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_YELLOW;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_blue", mod_hash, MOD_HASH_BRIGHT_BLUE)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_magenta", mod_hash, MOD_HASH_BRIGHT_MAGENTA)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_MAGENTA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_cyan", mod_hash, MOD_HASH_BRIGHT_CYAN)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_CYAN;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_white", mod_hash, MOD_HASH_BRIGHT_WHITE)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_WHITE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bg_black", mod_hash, MOD_HASH_BG_BLACK)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BLACK;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bg_red", mod_hash, MOD_HASH_BG_RED)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_RED;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bg_green", mod_hash, MOD_HASH_BG_GREEN)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_GREEN;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bg_yellow", mod_hash, MOD_HASH_BG_YELLOW)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_YELLOW;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bg_blue", mod_hash, MOD_HASH_BG_BLUE)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BLUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bg_magenta", mod_hash, MOD_HASH_BG_MAGENTA)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_MAGENTA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bg_cyan", mod_hash, MOD_HASH_BG_CYAN)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_CYAN;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bg_white", mod_hash, MOD_HASH_BG_WHITE)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_WHITE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bg_dark_grey", mod_hash, MOD_HASH_BG_DARK_GREY)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLACK;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_bg_red", mod_hash, MOD_HASH_BRIGHT_BG_RED)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_RED;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_bg_green", mod_hash, MOD_HASH_BRIGHT_BG_GREEN)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_GREEN;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_bg_yellow", mod_hash, MOD_HASH_BRIGHT_BG_YELLOW)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_YELLOW;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_bg_blue", mod_hash, MOD_HASH_BRIGHT_BG_BLUE)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_bg_magenta", mod_hash, MOD_HASH_BRIGHT_BG_MAGENTA)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_MAGENTA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_bg_cyan", mod_hash, MOD_HASH_BRIGHT_BG_CYAN)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_CYAN;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bright_bg_white", mod_hash, MOD_HASH_BRIGHT_BG_WHITE)) {
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_WHITE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "bold", mod_hash, MOD_HASH_BOLD)) {
|
||
|
|
fmt->vmode.v_attrib |= B_TTY_ATTRIB_BOLD;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "uline", mod_hash, MOD_HASH_ULINE)) {
|
||
|
|
fmt->vmode.v_attrib |= B_TTY_ATTRIB_UNDERLINE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "italic", mod_hash, MOD_HASH_ITALIC)) {
|
||
|
|
fmt->vmode.v_attrib |= B_TTY_ATTRIB_ITALIC;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "invert", mod_hash, MOD_HASH_INVERT)) {
|
||
|
|
fmt->vmode.v_attrib |= B_TTY_ATTRIB_INVERT;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (COMPARE_MOD_NAME(modifier, "reset", mod_hash, MOD_HASH_RESET)) {
|
||
|
|
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16;
|
||
|
|
|
||
|
|
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_WHITE;
|
||
|
|
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BLACK;
|
||
|
|
fmt->vmode.v_attrib = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void format_buffer_putc(struct tty_format_buf* fmt, int c)
|
||
|
|
{
|
||
|
|
if (fmt->ptr < TTY_TMPBUF_SIZE - 1) {
|
||
|
|
fmt->buf[fmt->ptr++] = c;
|
||
|
|
fmt->buf[fmt->ptr] = '\0';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void format_buffer_clear(struct tty_format_buf* fmt)
|
||
|
|
{
|
||
|
|
fmt->ptr = 0;
|
||
|
|
fmt->buf[fmt->ptr] = '\0';
|
||
|
|
}
|
||
|
|
|
||
|
|
static void flush_vmode(struct b_tty* tty, struct tty_format_buf* fmt)
|
||
|
|
{
|
||
|
|
b_tty_set_vmode(tty, &fmt->vmode);
|
||
|
|
}
|
||
|
|
|
||
|
|
int b_tty_putc(struct b_tty *tty, enum b_tty_print_flags flags, char c)
|
||
|
|
{
|
||
|
|
if (flags & B_TTY_DISABLE_FORMATTING) {
|
||
|
|
z__b_tty_putc(tty, c);
|
||
|
|
return c;
|
||
|
|
}
|
||
|
|
|
||
|
|
struct tty_format_buf *fmt = z__b_tty_get_format_buf(tty);
|
||
|
|
|
||
|
|
if (c == '[') {
|
||
|
|
if (!fmt->in_format) {
|
||
|
|
fmt->in_format = true;
|
||
|
|
return c;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (fmt->ptr == 0) {
|
||
|
|
fmt->in_format = false;
|
||
|
|
z__b_tty_putc(tty, '[');
|
||
|
|
return c;
|
||
|
|
}
|
||
|
|
|
||
|
|
format_buffer_putc(fmt, c);
|
||
|
|
|
||
|
|
return c;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (fmt->in_format && c == ']') {
|
||
|
|
apply_code_to_vmode(fmt);
|
||
|
|
format_buffer_clear(fmt);
|
||
|
|
flush_vmode(tty, fmt);
|
||
|
|
fmt->in_format = false;
|
||
|
|
return c;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (fmt->in_format && c == ',') {
|
||
|
|
apply_code_to_vmode(fmt);
|
||
|
|
format_buffer_clear(fmt);
|
||
|
|
return c;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (fmt->in_format) {
|
||
|
|
format_buffer_putc(fmt, c);
|
||
|
|
} else {
|
||
|
|
z__b_tty_putc(tty, c);
|
||
|
|
}
|
||
|
|
|
||
|
|
return c;
|
||
|
|
}
|
||
|
|
|
||
|
|
int b_tty_puts(
|
||
|
|
struct b_tty* tty, enum b_tty_print_flags flags, const char* s)
|
||
|
|
{
|
||
|
|
int r = 0;
|
||
|
|
|
||
|
|
while (s[r]) {
|
||
|
|
b_tty_putc(tty, flags, s[r]);
|
||
|
|
r++;
|
||
|
|
}
|
||
|
|
|
||
|
|
return r;
|
||
|
|
}
|
||
|
|
|
||
|
|
int b_tty_printf(
|
||
|
|
struct b_tty* tty, enum b_tty_print_flags flags, const char* s, ...)
|
||
|
|
{
|
||
|
|
va_list arg;
|
||
|
|
va_start(arg, s);
|
||
|
|
int r = b_tty_vprintf(tty, flags, s, arg);
|
||
|
|
va_end(arg);
|
||
|
|
return r;
|
||
|
|
}
|