term: update module to work on linux and darwin

This commit is contained in:
2024-11-22 22:29:40 +00:00
parent 753d3ea9d3
commit d88b42f50e
6 changed files with 545 additions and 352 deletions

View File

@@ -1,37 +1,38 @@
#ifndef BLUELIB_TERM_TTY_H_ #ifndef BLUELIB_TERM_TTY_H_
#define BLUELIB_TERM_TTY_H_ #define BLUELIB_TERM_TTY_H_
#include <blue/core/status.h>
#include <blue/core/misc.h> #include <blue/core/misc.h>
#include <stdint.h> #include <blue/core/status.h>
#include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#define b_stdtty (z__b_tty_get_std()) #define b_stdtty (z__b_tty_get_std())
#define b_stderr (z__b_tty_get_err()) #define b_stderr (z__b_tty_get_err())
#define B_TTY_CTRL_KEY(c) ((c) | B_MOD_CTRL) #define B_TTY_CTRL_KEY(c) ((c) | B_MOD_CTRL)
#define B_MAKE_VMODE(fg, bg, a) \ #define B_MAKE_VMODE(fg, bg, a) \
{ \ { \
.v_fg = fg, .v_bg = bg, .v_attrib = (a) \ .v_fg = fg, .v_bg = bg, .v_attrib = (a) \
} }
#define B_MAKE_COLOUR_DEFAULT(v) \ #define B_MAKE_COLOUR_DEFAULT(v) \
{ \ { \
.c_mode = TTY_COLOUR_NONE, \ .c_mode = TTY_COLOUR_NONE, \
} }
#define B_MAKE_COLOUR_16(v) \ #define B_MAKE_COLOUR_16(v) \
{ \ { \
.c_mode = TTY_COLOUR_16, .c_16 = {.value = (v) } \ .c_mode = TTY_COLOUR_16, .c_16 = {.value = (v) } \
} }
#define B_MAKE_COLOUR_256(v) \ #define B_MAKE_COLOUR_256(v) \
{ \ { \
.c_mode = TTY_COLOUR_256, .c_256 = {.value = (v) } \ .c_mode = TTY_COLOUR_256, .c_256 = {.value = (v) } \
} }
#define B_MAKE_COLOUR_TRUE(cr, cg, cb) \ #define B_MAKE_COLOUR_TRUE(cr, cg, cb) \
{ \ { \
.c_mode = TTY_COLOUR_TRUE, .c_true \ .c_mode = TTY_COLOUR_TRUE, .c_true \
= {.r = (cr), \ = {.r = (cr), \
@@ -167,13 +168,13 @@ BLUE_API void b_tty_move_cursor_y(
struct b_tty *tty, enum b_tty_position_base base, int pos); struct b_tty *tty, enum b_tty_position_base base, int pos);
BLUE_API void b_tty_clear(struct b_tty *tty, enum b_tty_clear_mode mode); BLUE_API void b_tty_clear(struct b_tty *tty, enum b_tty_clear_mode mode);
BLUE_API int b_tty_putc( BLUE_API int b_tty_putc(struct b_tty *tty, enum b_tty_print_flags flags, char c);
struct b_tty *tty, enum b_tty_print_flags flags, char c);
BLUE_API int b_tty_puts( BLUE_API int b_tty_puts(
struct b_tty *tty, enum b_tty_print_flags flags, const char *s); struct b_tty *tty, enum b_tty_print_flags flags, const char *s);
BLUE_API int b_tty_printf( BLUE_API int b_tty_printf(
struct b_tty *tty, enum b_tty_print_flags flags, const char *s, ...); struct b_tty *tty, enum b_tty_print_flags flags, const char *s, ...);
BLUE_API int b_tty_vprintf( BLUE_API int b_tty_vprintf(
struct b_tty *tty, enum b_tty_print_flags flags, const char *s, va_list args); struct b_tty *tty, enum b_tty_print_flags flags, const char *s,
va_list args);
#endif #endif

View File

@@ -122,8 +122,7 @@ struct out_tty_args {
}; };
// output function type // output function type
typedef void (*out_fct_type)( typedef void (*out_fct_type)(char character, struct out_tty_args *args);
char character, struct out_tty_args *args);
// wrapper (used as buffer) for output function type // wrapper (used as buffer) for output function type
typedef struct { typedef struct {
@@ -149,17 +148,6 @@ static inline void _out_null(char character, void *buffer, size_t idx, size_t ma
(void)maxlen; (void)maxlen;
} }
// internal _putchar wrapper
static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen)
{
(void)buffer;
(void)idx;
(void)maxlen;
if (character) {
_putchar(character);
}
}
// internal output function wrapper // internal output function wrapper
static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen)
{ {
@@ -201,8 +189,8 @@ static unsigned int _atoi(const char **str)
// output the specified string in reverse, taking care of any zero-padding // output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev( static size_t _out_rev(
out_fct_type out, struct out_tty_args *args, out_fct_type out, struct out_tty_args *args, const char *buf,
const char *buf, size_t len, unsigned int width, unsigned int flags) size_t len, unsigned int width, unsigned int flags)
{ {
size_t idx = 0; size_t idx = 0;
@@ -231,9 +219,9 @@ static size_t _out_rev(
// internal itoa format // internal itoa format
static size_t _ntoa_format( static size_t _ntoa_format(
out_fct_type out, struct out_tty_args *args, char *buf, out_fct_type out, struct out_tty_args *args, char *buf, size_t len,
size_t len, bool negative, unsigned int base, unsigned int prec, bool negative, unsigned int base, unsigned int prec, unsigned int width,
unsigned int width, unsigned int flags) unsigned int flags)
{ {
// pad leading zeros // pad leading zeros
if (!(flags & FLAGS_LEFT)) { if (!(flags & FLAGS_LEFT)) {
@@ -289,9 +277,9 @@ static size_t _ntoa_format(
// internal itoa for 'long' type // internal itoa for 'long' type
static size_t _ntoa_long( static size_t _ntoa_long(
out_fct_type out, struct out_tty_args *args, out_fct_type out, struct out_tty_args *args, unsigned long value,
unsigned long value, bool negative, unsigned long base, bool negative, unsigned long base, unsigned int prec,
unsigned int prec, unsigned int width, unsigned int flags) unsigned int width, unsigned int flags)
{ {
char buf[PRINTF_NTOA_BUFFER_SIZE]; char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U; size_t len = 0U;
@@ -314,16 +302,16 @@ static size_t _ntoa_long(
} }
return _ntoa_format( return _ntoa_format(
out, args, buf, len, negative, out, args, buf, len, negative, (unsigned int)base, prec, width,
(unsigned int)base, prec, width, flags); flags);
} }
// internal itoa for 'long long' type // internal itoa for 'long long' type
#if defined(PRINTF_SUPPORT_LONG_LONG) #if defined(PRINTF_SUPPORT_LONG_LONG)
static size_t _ntoa_long_long( static size_t _ntoa_long_long(
out_fct_type out, struct out_tty_args *args, out_fct_type out, struct out_tty_args *args, unsigned long long value,
unsigned long long value, bool negative, unsigned long long base, bool negative, unsigned long long base, unsigned int prec,
unsigned int prec, unsigned int width, unsigned int flags) unsigned int width, unsigned int flags)
{ {
char buf[PRINTF_NTOA_BUFFER_SIZE]; char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U; size_t len = 0U;
@@ -346,8 +334,8 @@ static size_t _ntoa_long_long(
} }
return _ntoa_format( return _ntoa_format(
out, args, buf, len, negative, out, args, buf, len, negative, (unsigned int)base, prec, width,
(unsigned int)base, prec, width, flags); flags);
} }
#endif // PRINTF_SUPPORT_LONG_LONG #endif // PRINTF_SUPPORT_LONG_LONG
@@ -381,8 +369,7 @@ static size_t _ftoa(
return _out_rev(out, args, "fni-", 4, width, flags); return _out_rev(out, args, "fni-", 4, width, flags);
if (value > DBL_MAX) if (value > DBL_MAX)
return _out_rev( return _out_rev(
out, args, out, args, (flags & FLAGS_PLUS) ? "fni+" : "fni",
(flags & FLAGS_PLUS) ? "fni+" : "fni",
(flags & FLAGS_PLUS) ? 4U : 3U, width, flags); (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);
// test for very large values // test for very large values
@@ -582,7 +569,9 @@ static size_t _etoa(
} }
// output the floating part // output the floating part
size_t idx = _ftoa(out, args, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); size_t idx
= _ftoa(out, args, negative ? -value : value, prec, fwidth,
flags & ~FLAGS_ADAPT_EXP);
// output the exponent part // output the exponent part
if (minwidth) { if (minwidth) {
@@ -590,9 +579,8 @@ static size_t _etoa(
out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', args); out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', args);
// output the exponent value // output the exponent value
idx = _ntoa_long( idx = _ntoa_long(
out, args, out, args, (expval < 0) ? -expval : expval, expval < 0,
(expval < 0) ? -expval : expval, expval < 0, 10, 0, 10, 0, minwidth - 1, FLAGS_ZEROPAD | FLAGS_PLUS);
minwidth - 1, FLAGS_ZEROPAD | FLAGS_PLUS);
// might need to right-pad spaces // might need to right-pad spaces
if (flags & FLAGS_LEFT) { if (flags & FLAGS_LEFT) {
while (idx < width) { while (idx < width) {
@@ -606,13 +594,12 @@ static size_t _etoa(
#endif // PRINTF_SUPPORT_EXPONENTIAL #endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT #endif // PRINTF_SUPPORT_FLOAT
#define set_format_ch(args) ((args)->format_ch = true) #define set_format_ch(args) ((args)->format_ch = true)
#define unset_format_ch(args) ((args)->format_ch = false) #define unset_format_ch(args) ((args)->format_ch = false)
// internal vsnprintf // internal vsnprintf
static int _vsnprintf( static int _vsnprintf(
out_fct_type out, struct out_tty_args *args, const char *format, out_fct_type out, struct out_tty_args *args, const char *format, va_list va)
va_list va)
{ {
unsigned int flags, width, precision, n; unsigned int flags, width, precision, n;
size_t idx = 0U; size_t idx = 0U;
@@ -831,15 +818,14 @@ static int _vsnprintf(
const unsigned int value const unsigned int value
= (flags & FLAGS_CHAR) = (flags & FLAGS_CHAR)
? (unsigned char)va_arg( ? (unsigned char)va_arg(
va, unsigned int) va, unsigned int)
: (flags & FLAGS_SHORT) : (flags & FLAGS_SHORT)
? (unsigned short int)va_arg( ? (unsigned short int)va_arg(
va, unsigned int) va, unsigned int)
: va_arg(va, unsigned int); : va_arg(va, unsigned int);
idx = _ntoa_long( idx = _ntoa_long(
out, args, value, out, args, value, false, base,
false, base, precision, width, precision, width, flags);
flags);
} }
} }
format++; format++;
@@ -850,9 +836,9 @@ static int _vsnprintf(
case 'F': case 'F':
if (*format == 'F') if (*format == 'F')
flags |= FLAGS_UPPERCASE; flags |= FLAGS_UPPERCASE;
idx = _ftoa( idx
out, args, va_arg(va, double), = _ftoa(out, args, va_arg(va, double),
precision, width, flags); precision, width, flags);
format++; format++;
break; break;
#if defined(PRINTF_SUPPORT_EXPONENTIAL) #if defined(PRINTF_SUPPORT_EXPONENTIAL)
@@ -864,9 +850,9 @@ static int _vsnprintf(
flags |= FLAGS_ADAPT_EXP; flags |= FLAGS_ADAPT_EXP;
if ((*format == 'E') || (*format == 'G')) if ((*format == 'E') || (*format == 'G'))
flags |= FLAGS_UPPERCASE; flags |= FLAGS_UPPERCASE;
idx = _etoa( idx
out, args, va_arg(va, double), = _etoa(out, args, va_arg(va, double),
precision, width, flags); precision, width, flags);
format++; format++;
break; break;
#endif // PRINTF_SUPPORT_EXPONENTIAL #endif // PRINTF_SUPPORT_EXPONENTIAL
@@ -926,9 +912,8 @@ static int _vsnprintf(
const bool is_ll = sizeof(uintptr_t) == sizeof(long long); const bool is_ll = sizeof(uintptr_t) == sizeof(long long);
if (is_ll) { if (is_ll) {
idx = _ntoa_long_long( idx = _ntoa_long_long(
out, args, out, args, (uintptr_t)va_arg(va, void *),
(uintptr_t)va_arg(va, void *), false, false, 16U, precision, width, flags);
16U, precision, width, flags);
} else { } else {
#endif #endif
idx = _ntoa_long( idx = _ntoa_long(
@@ -983,14 +968,15 @@ static void out_tty(char c, struct out_tty_args *args)
b_tty_putc(args->tty, flags, c); b_tty_putc(args->tty, flags, c);
} }
int b_tty_vprintf(struct b_tty *tty, enum b_tty_print_flags flags, const char *format, va_list args) int b_tty_vprintf(
struct b_tty *tty, enum b_tty_print_flags flags, const char *format,
va_list args)
{ {
struct out_tty_args tty_args = { struct out_tty_args tty_args = {
.flags = flags, .flags = flags,
.tty = tty, .tty = tty,
}; };
const int ret = _vsnprintf( const int ret = _vsnprintf(out_tty, &tty_args, format, args);
out_tty, &tty_args, format, args);
return ret; return ret;
} }

View File

@@ -1,5 +1,6 @@
#include "../../../line-ed/tty.h" #include "../../tty.h"
#include <blue/term/tty.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -24,67 +25,78 @@
#define ANSI_TRUECOLOUR_BG "48;2" #define ANSI_TRUECOLOUR_BG "48;2"
enum tty_flags { enum tty_flags {
TTY_INIT = 0x01u, B_TTY_INIT = 0x01u,
TTY_INTERACTIVE = 0x02u, B_TTY_INTERACTIVE = 0x02u,
}; };
struct s_tty { struct b_tty {
FILE *t_in, *t_out; FILE *t_in, *t_out;
enum tty_flags t_flags; enum tty_flags t_flags;
struct termios t_ios_raw, t_ios_default; struct termios t_ios_raw, t_ios_default;
struct s_tty_vmode t_vmode; struct b_tty_vmode t_vmode;
unsigned char t_mcount; unsigned char t_mcount;
struct tty_format_buf t_format_buf;
}; };
static struct s_tty tty = {}; static struct b_tty std = {0};
static struct b_tty err = {0};
static const char *ansi_colour16_fg[] = { static const char *ansi_colour16_fg[] = {
[TTY_COLOUR16_BLACK] = "30", [B_TTY_COLOUR16_BLACK] = "30",
[TTY_COLOUR16_RED] = "31", [B_TTY_COLOUR16_RED] = "31",
[TTY_COLOUR16_GREEN] = "32", [B_TTY_COLOUR16_GREEN] = "32",
[TTY_COLOUR16_YELLOW] = "33", [B_TTY_COLOUR16_YELLOW] = "33",
[TTY_COLOUR16_BLUE] = "34", [B_TTY_COLOUR16_BLUE] = "34",
[TTY_COLOUR16_MAGENTA] = "35", [B_TTY_COLOUR16_MAGENTA] = "35",
[TTY_COLOUR16_CYAN] = "36", [B_TTY_COLOUR16_CYAN] = "36",
[TTY_COLOUR16_WHITE] = "37", [B_TTY_COLOUR16_WHITE] = "37",
[TTY_COLOUR16_GREY] = "90", [B_TTY_COLOUR16_BRIGHT_BLACK] = "90",
[TTY_COLOUR16_BRIGHT_RED] = "91", [B_TTY_COLOUR16_BRIGHT_RED] = "91",
[TTY_COLOUR16_BRIGHT_GREEN] = "92", [B_TTY_COLOUR16_BRIGHT_GREEN] = "92",
[TTY_COLOUR16_BRIGHT_YELLOW] = "93", [B_TTY_COLOUR16_BRIGHT_YELLOW] = "93",
[TTY_COLOUR16_BRIGHT_BLUE] = "94", [B_TTY_COLOUR16_BRIGHT_BLUE] = "94",
[TTY_COLOUR16_BRIGHT_MAGENTA] = "95", [B_TTY_COLOUR16_BRIGHT_MAGENTA] = "95",
[TTY_COLOUR16_BRIGHT_CYAN] = "96", [B_TTY_COLOUR16_BRIGHT_CYAN] = "96",
[TTY_COLOUR16_BRIGHT_WHITE] = "97", [B_TTY_COLOUR16_BRIGHT_WHITE] = "97",
}; };
static const char *ansi_colour16_bg[] = { static const char *ansi_colour16_bg[] = {
[TTY_COLOUR16_BLACK] = "40", [B_TTY_COLOUR16_BLACK] = "40",
[TTY_COLOUR16_RED] = "41", [B_TTY_COLOUR16_RED] = "41",
[TTY_COLOUR16_GREEN] = "42", [B_TTY_COLOUR16_GREEN] = "42",
[TTY_COLOUR16_YELLOW] = "43", [B_TTY_COLOUR16_YELLOW] = "43",
[TTY_COLOUR16_BLUE] = "44", [B_TTY_COLOUR16_BLUE] = "44",
[TTY_COLOUR16_MAGENTA] = "45", [B_TTY_COLOUR16_MAGENTA] = "45",
[TTY_COLOUR16_CYAN] = "46", [B_TTY_COLOUR16_CYAN] = "46",
[TTY_COLOUR16_WHITE] = "47", [B_TTY_COLOUR16_WHITE] = "47",
[TTY_COLOUR16_GREY] = "100", [B_TTY_COLOUR16_BRIGHT_BLACK] = "100",
[TTY_COLOUR16_BRIGHT_RED] = "101", [B_TTY_COLOUR16_BRIGHT_RED] = "101",
[TTY_COLOUR16_BRIGHT_GREEN] = "102", [B_TTY_COLOUR16_BRIGHT_GREEN] = "102",
[TTY_COLOUR16_BRIGHT_YELLOW] = "103", [B_TTY_COLOUR16_BRIGHT_YELLOW] = "103",
[TTY_COLOUR16_BRIGHT_BLUE] = "104", [B_TTY_COLOUR16_BRIGHT_BLUE] = "104",
[TTY_COLOUR16_BRIGHT_MAGENTA] = "105", [B_TTY_COLOUR16_BRIGHT_MAGENTA] = "105",
[TTY_COLOUR16_BRIGHT_CYAN] = "106", [B_TTY_COLOUR16_BRIGHT_CYAN] = "106",
[TTY_COLOUR16_BRIGHT_WHITE] = "107", [B_TTY_COLOUR16_BRIGHT_WHITE] = "107",
}; };
static void init_tty(struct s_tty *tty, FILE *in, FILE *out) static void init_tty(struct b_tty *tty, FILE *in, FILE *out)
{ {
tty->t_in = in; tty->t_in = in;
tty->t_out = out; tty->t_out = out;
int fd = fileno(in); int fd = -1;
if (in) {
fd = fileno(in);
} else if (out) {
fd = fileno(out);
}
if (fd == -1) {
return;
}
if (isatty(fd)) { if (isatty(fd)) {
tty->t_flags |= TTY_INTERACTIVE; tty->t_flags |= B_TTY_INTERACTIVE;
} }
tcgetattr(fd, &tty->t_ios_default); tcgetattr(fd, &tty->t_ios_default);
@@ -94,69 +106,124 @@ static void init_tty(struct s_tty *tty, FILE *in, FILE *out)
tty->t_ios_raw.c_oflag &= ~(OPOST); tty->t_ios_raw.c_oflag &= ~(OPOST);
tty->t_ios_raw.c_lflag &= ~(ECHO | ICANON | IEXTEN); tty->t_ios_raw.c_lflag &= ~(ECHO | ICANON | IEXTEN);
tty->t_flags |= TTY_INIT; tty->t_flags |= B_TTY_INIT;
} }
struct s_tty *s_get_tty(void) struct b_tty *z__b_tty_get_std(void)
{ {
if (!(tty.t_flags & TTY_INIT)) { if (!(std.t_flags & B_TTY_INIT)) {
init_tty(&tty, stdin, stdout); init_tty(&std, stdin, stdout);
} }
return &tty; return &std;
} }
bool s_tty_is_interactive(const struct s_tty *tty) struct b_tty *z__b_tty_get_err(void)
{ {
return (tty->t_flags & TTY_INTERACTIVE) == TTY_INTERACTIVE; if (!(err.t_flags & B_TTY_INIT)) {
init_tty(&err, NULL, stderr);
}
return &err;
} }
void s_tty_set_raw(struct s_tty *tty) struct tty_format_buf *z__b_tty_get_format_buf(struct b_tty *tty)
{ {
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tty->t_ios_raw); return &tty->t_format_buf;
} }
void s_tty_set_canon(struct s_tty *tty) void z__b_tty_putc(struct b_tty *tty, char c)
{ {
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tty->t_ios_default); fputc(c, tty->t_out);
} }
void s_tty_reset_vmode(struct s_tty *tty) bool b_tty_is_interactive(const struct b_tty *tty)
{ {
if (tty->t_vmode.v_fg.c_mode == TTY_COLOUR_NONE return (tty->t_flags & B_TTY_INTERACTIVE) == B_TTY_INTERACTIVE;
&& tty->t_vmode.v_bg.c_mode == TTY_COLOUR_NONE }
&& tty->t_vmode.v_attrib == TTY_ATTRIB_NORMAL) {
static void set_raw(struct b_tty *tty)
{
int fd = -1;
if (tty->t_in) {
fd = fileno(tty->t_in);
} else if (tty->t_out) {
fd = fileno(tty->t_out);
}
if (fd == -1) {
return; return;
} }
fprintf(tty->t_out, "\033[0;39;49m"); tcsetattr(fd, TCSAFLUSH, &tty->t_ios_raw);
}
static void set_canon(struct b_tty *tty)
{
int fd = -1;
if (tty->t_in) {
fd = fileno(tty->t_in);
} else if (tty->t_out) {
fd = fileno(tty->t_out);
}
if (fd == -1) {
return;
}
tcsetattr(fd, TCSAFLUSH, &tty->t_ios_default);
}
void b_tty_set_mode(struct b_tty *tty, enum b_tty_mode mode)
{
switch (mode) {
case B_TTY_CANONICAL:
set_canon(tty);
break;
case B_TTY_RAW:
set_raw(tty);
break;
default:
break;
}
}
void b_tty_reset_vmode(struct b_tty *tty)
{
if (tty->t_vmode.v_fg.c_mode == B_TTY_COLOUR_NONE
&& tty->t_vmode.v_bg.c_mode == B_TTY_COLOUR_NONE
&& tty->t_vmode.v_attrib == B_TTY_ATTRIB_NORMAL) {
return;
}
fprintf(tty->t_out, "\033[0m");
memset(&tty->t_vmode, 0x0, sizeof tty->t_vmode); memset(&tty->t_vmode, 0x0, sizeof tty->t_vmode);
tty->t_vmode.v_fg.c_mode = TTY_COLOUR_NONE; tty->t_vmode.v_fg.c_mode = B_TTY_COLOUR_NONE;
tty->t_vmode.v_bg.c_mode = TTY_COLOUR_NONE; tty->t_vmode.v_bg.c_mode = B_TTY_COLOUR_NONE;
tty->t_vmode.v_attrib = TTY_ATTRIB_NORMAL; tty->t_vmode.v_attrib = B_TTY_ATTRIB_NORMAL;
} }
static int compare_colour( static int compare_colour(
const struct s_tty_colour *a, const struct s_tty_colour *b) const struct b_tty_colour *a, const struct b_tty_colour *b)
{ {
if (a->c_mode != b->c_mode) { if (a->c_mode != b->c_mode) {
return -1; return -1;
} }
switch (a->c_mode) { switch (a->c_mode) {
case TTY_COLOUR_16: case B_TTY_COLOUR_16:
if (a->c_16.value != b->c_16.value) { if (a->c_16.value != b->c_16.value) {
return -1; return -1;
} }
break; break;
case TTY_COLOUR_256: case B_TTY_COLOUR_256:
if (a->c_256.value != b->c_256.value) { if (a->c_256.value != b->c_256.value) {
return -1; return -1;
} }
break; break;
case TTY_COLOUR_TRUE: case B_TTY_COLOUR_TRUE:
if (a->c_true.r != b->c_true.r) { if (a->c_true.r != b->c_true.r) {
return -1; return -1;
} }
@@ -176,7 +243,7 @@ static int compare_colour(
return 0; return 0;
} }
static int compare_vmode(const struct s_tty_vmode *a, const struct s_tty_vmode *b) static int compare_vmode(const struct b_tty_vmode *a, const struct b_tty_vmode *b)
{ {
if (a->v_attrib != b->v_attrib) { if (a->v_attrib != b->v_attrib) {
return -1; return -1;
@@ -193,7 +260,7 @@ static int compare_vmode(const struct s_tty_vmode *a, const struct s_tty_vmode *
return 0; return 0;
} }
static void put_ansi_attrib(struct s_tty *tty, const char *s) static void put_ansi_attrib(struct b_tty *tty, const char *s)
{ {
if (tty->t_mcount > 0) { if (tty->t_mcount > 0) {
fputs(";", tty->t_out); fputs(";", tty->t_out);
@@ -204,46 +271,46 @@ static void put_ansi_attrib(struct s_tty *tty, const char *s)
} }
static void set_attrib( static void set_attrib(
struct s_tty *tty, enum s_tty_attrib old, enum s_tty_attrib new) struct b_tty *tty, enum b_tty_attrib old, enum b_tty_attrib new)
{ {
if (old == new) { if (old == new) {
return; return;
} }
/* Bold ON */ /* Bold ON */
if (!(old & TTY_ATTRIB_BOLD) && new &TTY_ATTRIB_BOLD) { if (!(old & B_TTY_ATTRIB_BOLD) && new &B_TTY_ATTRIB_BOLD) {
put_ansi_attrib(tty, ANSI_BOLD_ON); put_ansi_attrib(tty, ANSI_BOLD_ON);
} }
/* Bold OFF */ /* Bold OFF */
if (old & TTY_ATTRIB_BOLD && !(new &TTY_ATTRIB_BOLD)) { if (old & B_TTY_ATTRIB_BOLD && !(new &B_TTY_ATTRIB_BOLD)) {
put_ansi_attrib(tty, ANSI_BOLD_OFF); put_ansi_attrib(tty, ANSI_BOLD_OFF);
} }
/* Underline ON */ /* Underline ON */
if (!(old & TTY_ATTRIB_UNDERLINE) && new &TTY_ATTRIB_UNDERLINE) { if (!(old & B_TTY_ATTRIB_UNDERLINE) && new &B_TTY_ATTRIB_UNDERLINE) {
put_ansi_attrib(tty, ANSI_UNDERLINE_ON); put_ansi_attrib(tty, ANSI_UNDERLINE_ON);
} }
/* Underline OFF */ /* Underline OFF */
if (old & TTY_ATTRIB_UNDERLINE && !(new &TTY_ATTRIB_UNDERLINE)) { if (old & B_TTY_ATTRIB_UNDERLINE && !(new &B_TTY_ATTRIB_UNDERLINE)) {
put_ansi_attrib(tty, ANSI_UNDERLINE_OFF); put_ansi_attrib(tty, ANSI_UNDERLINE_OFF);
} }
/* Italic ON */ /* Italic ON */
if (!(old & TTY_ATTRIB_ITALIC) && new &TTY_ATTRIB_ITALIC) { if (!(old & B_TTY_ATTRIB_ITALIC) && new &B_TTY_ATTRIB_ITALIC) {
put_ansi_attrib(tty, ANSI_ITALIC_ON); put_ansi_attrib(tty, ANSI_ITALIC_ON);
} }
/* Italic OFF */ /* Italic OFF */
if (old & TTY_ATTRIB_ITALIC && !(new &TTY_ATTRIB_ITALIC)) { if (old & B_TTY_ATTRIB_ITALIC && !(new &B_TTY_ATTRIB_ITALIC)) {
put_ansi_attrib(tty, ANSI_ITALIC_OFF); put_ansi_attrib(tty, ANSI_ITALIC_OFF);
} }
} }
static void set_fg( static void set_fg(
struct s_tty *tty, const struct s_tty_colour *old, struct b_tty *tty, const struct b_tty_colour *old,
const struct s_tty_colour *new) const struct b_tty_colour *new)
{ {
if (compare_colour(old, new) == 0) { if (compare_colour(old, new) == 0) {
return; return;
@@ -252,18 +319,18 @@ static void set_fg(
char buf[8]; char buf[8];
switch (new->c_mode) { switch (new->c_mode) {
case TTY_COLOUR_NONE: case B_TTY_COLOUR_NONE:
put_ansi_attrib(tty, ANSI_DEFAULTCOLOUR_FG); put_ansi_attrib(tty, ANSI_DEFAULTCOLOUR_FG);
break; break;
case TTY_COLOUR_16: case B_TTY_COLOUR_16:
put_ansi_attrib(tty, ansi_colour16_fg[new->c_16.value]); put_ansi_attrib(tty, ansi_colour16_fg[new->c_16.value]);
break; break;
case TTY_COLOUR_256: case B_TTY_COLOUR_256:
put_ansi_attrib(tty, ANSI_256COLOUR_FG); put_ansi_attrib(tty, ANSI_256COLOUR_FG);
snprintf(buf, sizeof buf, "%u", new->c_256.value); snprintf(buf, sizeof buf, "%u", new->c_256.value);
put_ansi_attrib(tty, buf); put_ansi_attrib(tty, buf);
break; break;
case TTY_COLOUR_TRUE: case B_TTY_COLOUR_TRUE:
put_ansi_attrib(tty, ANSI_TRUECOLOUR_FG); put_ansi_attrib(tty, ANSI_TRUECOLOUR_FG);
snprintf(buf, sizeof buf, "%u", new->c_true.r); snprintf(buf, sizeof buf, "%u", new->c_true.r);
put_ansi_attrib(tty, buf); put_ansi_attrib(tty, buf);
@@ -278,8 +345,8 @@ static void set_fg(
} }
static void set_bg( static void set_bg(
struct s_tty *tty, const struct s_tty_colour *old, struct b_tty *tty, const struct b_tty_colour *old,
const struct s_tty_colour *new) const struct b_tty_colour *new)
{ {
if (compare_colour(old, new) == 0) { if (compare_colour(old, new) == 0) {
return; return;
@@ -288,18 +355,18 @@ static void set_bg(
char buf[8]; char buf[8];
switch (new->c_mode) { switch (new->c_mode) {
case TTY_COLOUR_NONE: case B_TTY_COLOUR_NONE:
put_ansi_attrib(tty, ANSI_DEFAULTCOLOUR_BG); put_ansi_attrib(tty, ANSI_DEFAULTCOLOUR_BG);
break; break;
case TTY_COLOUR_16: case B_TTY_COLOUR_16:
put_ansi_attrib(tty, ansi_colour16_bg[new->c_16.value]); put_ansi_attrib(tty, ansi_colour16_bg[new->c_16.value]);
break; break;
case TTY_COLOUR_256: case B_TTY_COLOUR_256:
put_ansi_attrib(tty, ANSI_256COLOUR_BG); put_ansi_attrib(tty, ANSI_256COLOUR_BG);
snprintf(buf, sizeof buf, "%u", new->c_256.value); snprintf(buf, sizeof buf, "%u", new->c_256.value);
put_ansi_attrib(tty, buf); put_ansi_attrib(tty, buf);
break; break;
case TTY_COLOUR_TRUE: case B_TTY_COLOUR_TRUE:
put_ansi_attrib(tty, ANSI_TRUECOLOUR_BG); put_ansi_attrib(tty, ANSI_TRUECOLOUR_BG);
snprintf(buf, sizeof buf, "%u", new->c_true.r); snprintf(buf, sizeof buf, "%u", new->c_true.r);
put_ansi_attrib(tty, buf); put_ansi_attrib(tty, buf);
@@ -313,7 +380,7 @@ static void set_bg(
} }
} }
void s_tty_set_vmode(struct s_tty *tty, const struct s_tty_vmode *vmode) void b_tty_set_vmode(struct b_tty *tty, const struct b_tty_vmode *vmode)
{ {
if (compare_vmode(&tty->t_vmode, vmode) == 0) { if (compare_vmode(&tty->t_vmode, vmode) == 0) {
return; return;
@@ -332,7 +399,7 @@ void s_tty_set_vmode(struct s_tty *tty, const struct s_tty_vmode *vmode)
memcpy(&tty->t_vmode, vmode, sizeof *vmode); memcpy(&tty->t_vmode, vmode, sizeof *vmode);
} }
s_keycode s_tty_read_key(struct s_tty *tty) b_keycode b_tty_read_key(struct b_tty *tty)
{ {
char c; char c;
int v; int v;
@@ -341,19 +408,19 @@ s_keycode s_tty_read_key(struct s_tty *tty)
while (1) { while (1) {
v = read(fd, &c, 1); v = read(fd, &c, 1);
if (v < 1) { if (v < 1) {
return S_KEY_EOF; return B_KEY_EOF;
} }
if (c == '\r' || c == '\n') { if (c == '\r' || c == '\n') {
return S_KEY_RETURN; return B_KEY_RETURN;
} }
if (c == '\b' || c == 0x7F) { if (c == '\b' || c == 0x7F) {
return S_KEY_BACKSPACE; return B_KEY_BACKSPACE;
} }
if (c >= 1 && c <= 26) { if (c >= 1 && c <= 26) {
return S_TTY_CTRL_KEY(c + 'a' - 1); return B_TTY_CTRL_KEY(c + 'a' - 1);
} }
if (c != 0x1b) { if (c != 0x1b) {
@@ -362,7 +429,7 @@ s_keycode s_tty_read_key(struct s_tty *tty)
v = read(fd, &c, 1); v = read(fd, &c, 1);
if (v < 1) { if (v < 1) {
return S_KEY_EOF; return B_KEY_EOF;
} }
if (c != '[') { if (c != '[') {
@@ -371,18 +438,18 @@ s_keycode s_tty_read_key(struct s_tty *tty)
v = read(fd, &c, 1); v = read(fd, &c, 1);
if (v < 1) { if (v < 1) {
return S_KEY_EOF; return B_KEY_EOF;
} }
switch (c) { switch (c) {
case 'A': case 'A':
return S_KEY_ARROW_UP; return B_KEY_ARROW_UP;
case 'B': case 'B':
return S_KEY_ARROW_DOWN; return B_KEY_ARROW_DOWN;
case 'C': case 'C':
return S_KEY_ARROW_RIGHT; return B_KEY_ARROW_RIGHT;
case 'D': case 'D':
return S_KEY_ARROW_LEFT; return B_KEY_ARROW_LEFT;
default: default:
continue; continue;
} }
@@ -391,9 +458,9 @@ s_keycode s_tty_read_key(struct s_tty *tty)
return c; return c;
} }
void s_tty_move_cursor_x(struct s_tty *tty, enum s_tty_position_base base, int pos) void b_tty_move_cursor_x(struct b_tty *tty, enum b_tty_position_base base, int pos)
{ {
if (base == TTY_POS_CURSOR && pos < 0 && pos >= -4) { if (base == B_TTY_POS_CURSOR && pos < 0 && pos >= -4) {
for (int i = 0; i > pos; i--) { for (int i = 0; i > pos; i--) {
fputc('\b', tty->t_out); fputc('\b', tty->t_out);
} }
@@ -401,7 +468,7 @@ void s_tty_move_cursor_x(struct s_tty *tty, enum s_tty_position_base base, int p
return; return;
} }
if (base == TTY_POS_START) { if (base == B_TTY_POS_START) {
if (pos == 0) { if (pos == 0) {
fputs("\033[G", tty->t_out); fputs("\033[G", tty->t_out);
} else { } else {
@@ -420,9 +487,9 @@ void s_tty_move_cursor_x(struct s_tty *tty, enum s_tty_position_base base, int p
} }
} }
void s_tty_move_cursor_y(struct s_tty *tty, enum s_tty_position_base base, int pos) void b_tty_move_cursor_y(struct b_tty *tty, enum b_tty_position_base base, int pos)
{ {
if (base == TTY_POS_START) { if (base == B_TTY_POS_START) {
/* we don't need this functionality right now */ /* we don't need this functionality right now */
abort(); abort();
} }
@@ -438,24 +505,48 @@ void s_tty_move_cursor_y(struct s_tty *tty, enum s_tty_position_base base, int p
} }
} }
void s_tty_clear(struct s_tty *tty, enum s_tty_clear_mode mode) void b_tty_clear(struct b_tty *tty, enum b_tty_clear_mode mode)
{ {
const char *arg; const char *arg;
if (mode & TTY_CLEAR_ALL) { if (mode & B_TTY_CLEAR_ALL) {
arg = "2"; arg = "2";
} else if (mode & TTY_CLEAR_TO_CURSOR) { } else if (mode & B_TTY_CLEAR_TO_CURSOR) {
arg = "1"; arg = "1";
} else if (mode & TTY_CLEAR_FROM_CURSOR) { } else if (mode & B_TTY_CLEAR_FROM_CURSOR) {
arg = ""; arg = "";
} else { } else {
abort(); abort();
} }
if (mode & TTY_CLEAR_SCREEN) { if (mode & B_TTY_CLEAR_SCREEN) {
fprintf(tty->t_out, "\033[%sJ", arg); fprintf(tty->t_out, "\033[%sJ", arg);
} else if (mode & TTY_CLEAR_LINE) { } else if (mode & B_TTY_CLEAR_LINE) {
fprintf(tty->t_out, "\033[%sK", arg); fprintf(tty->t_out, "\033[%sK", arg);
} else { } else {
abort(); abort();
} }
} }
enum b_status b_tty_get_dimensions(
struct b_tty *tty, unsigned int *w, unsigned int *h)
{
if (!(tty->t_flags & B_TTY_INTERACTIVE)) {
return -1;
}
int fd = fileno(tty->t_out);
struct winsize ws;
if (ioctl(fd, TIOCGWINSZ, &ws) == -1) {
return -1;
}
if (w) {
*w = ws.ws_col;
}
if (h) {
*h = ws.ws_row;
}
return 0;
}

View File

@@ -1,5 +1,6 @@
#include "../../../line-ed/tty.h" #include "../../tty.h"
#include <blue/term/tty.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -24,67 +25,78 @@
#define ANSI_TRUECOLOUR_BG "48;2" #define ANSI_TRUECOLOUR_BG "48;2"
enum tty_flags { enum tty_flags {
TTY_INIT = 0x01u, B_TTY_INIT = 0x01u,
TTY_INTERACTIVE = 0x02u, B_TTY_INTERACTIVE = 0x02u,
}; };
struct s_tty { struct b_tty {
FILE *t_in, *t_out; FILE *t_in, *t_out;
enum tty_flags t_flags; enum tty_flags t_flags;
struct termios t_ios_raw, t_ios_default; struct termios t_ios_raw, t_ios_default;
struct s_tty_vmode t_vmode; struct b_tty_vmode t_vmode;
unsigned char t_mcount; unsigned char t_mcount;
struct tty_format_buf t_format_buf;
}; };
static struct s_tty tty = {}; static struct b_tty std = {0};
static struct b_tty err = {0};
static const char *ansi_colour16_fg[] = { static const char *ansi_colour16_fg[] = {
[TTY_COLOUR16_BLACK] = "30", [B_TTY_COLOUR16_BLACK] = "30",
[TTY_COLOUR16_RED] = "31", [B_TTY_COLOUR16_RED] = "31",
[TTY_COLOUR16_GREEN] = "32", [B_TTY_COLOUR16_GREEN] = "32",
[TTY_COLOUR16_YELLOW] = "33", [B_TTY_COLOUR16_YELLOW] = "33",
[TTY_COLOUR16_BLUE] = "34", [B_TTY_COLOUR16_BLUE] = "34",
[TTY_COLOUR16_MAGENTA] = "35", [B_TTY_COLOUR16_MAGENTA] = "35",
[TTY_COLOUR16_CYAN] = "36", [B_TTY_COLOUR16_CYAN] = "36",
[TTY_COLOUR16_WHITE] = "37", [B_TTY_COLOUR16_WHITE] = "37",
[TTY_COLOUR16_GREY] = "90", [B_TTY_COLOUR16_BRIGHT_BLACK] = "90",
[TTY_COLOUR16_BRIGHT_RED] = "91", [B_TTY_COLOUR16_BRIGHT_RED] = "91",
[TTY_COLOUR16_BRIGHT_GREEN] = "92", [B_TTY_COLOUR16_BRIGHT_GREEN] = "92",
[TTY_COLOUR16_BRIGHT_YELLOW] = "93", [B_TTY_COLOUR16_BRIGHT_YELLOW] = "93",
[TTY_COLOUR16_BRIGHT_BLUE] = "94", [B_TTY_COLOUR16_BRIGHT_BLUE] = "94",
[TTY_COLOUR16_BRIGHT_MAGENTA] = "95", [B_TTY_COLOUR16_BRIGHT_MAGENTA] = "95",
[TTY_COLOUR16_BRIGHT_CYAN] = "96", [B_TTY_COLOUR16_BRIGHT_CYAN] = "96",
[TTY_COLOUR16_BRIGHT_WHITE] = "97", [B_TTY_COLOUR16_BRIGHT_WHITE] = "97",
}; };
static const char *ansi_colour16_bg[] = { static const char *ansi_colour16_bg[] = {
[TTY_COLOUR16_BLACK] = "40", [B_TTY_COLOUR16_BLACK] = "40",
[TTY_COLOUR16_RED] = "41", [B_TTY_COLOUR16_RED] = "41",
[TTY_COLOUR16_GREEN] = "42", [B_TTY_COLOUR16_GREEN] = "42",
[TTY_COLOUR16_YELLOW] = "43", [B_TTY_COLOUR16_YELLOW] = "43",
[TTY_COLOUR16_BLUE] = "44", [B_TTY_COLOUR16_BLUE] = "44",
[TTY_COLOUR16_MAGENTA] = "45", [B_TTY_COLOUR16_MAGENTA] = "45",
[TTY_COLOUR16_CYAN] = "46", [B_TTY_COLOUR16_CYAN] = "46",
[TTY_COLOUR16_WHITE] = "47", [B_TTY_COLOUR16_WHITE] = "47",
[TTY_COLOUR16_GREY] = "100", [B_TTY_COLOUR16_BRIGHT_BLACK] = "100",
[TTY_COLOUR16_BRIGHT_RED] = "101", [B_TTY_COLOUR16_BRIGHT_RED] = "101",
[TTY_COLOUR16_BRIGHT_GREEN] = "102", [B_TTY_COLOUR16_BRIGHT_GREEN] = "102",
[TTY_COLOUR16_BRIGHT_YELLOW] = "103", [B_TTY_COLOUR16_BRIGHT_YELLOW] = "103",
[TTY_COLOUR16_BRIGHT_BLUE] = "104", [B_TTY_COLOUR16_BRIGHT_BLUE] = "104",
[TTY_COLOUR16_BRIGHT_MAGENTA] = "105", [B_TTY_COLOUR16_BRIGHT_MAGENTA] = "105",
[TTY_COLOUR16_BRIGHT_CYAN] = "106", [B_TTY_COLOUR16_BRIGHT_CYAN] = "106",
[TTY_COLOUR16_BRIGHT_WHITE] = "107", [B_TTY_COLOUR16_BRIGHT_WHITE] = "107",
}; };
static void init_tty(struct s_tty *tty, FILE *in, FILE *out) static void init_tty(struct b_tty *tty, FILE *in, FILE *out)
{ {
tty->t_in = in; tty->t_in = in;
tty->t_out = out; tty->t_out = out;
int fd = fileno(in); int fd = -1;
if (in) {
fd = fileno(in);
} else if (out) {
fd = fileno(out);
}
if (fd == -1) {
return;
}
if (isatty(fd)) { if (isatty(fd)) {
tty->t_flags |= TTY_INTERACTIVE; tty->t_flags |= B_TTY_INTERACTIVE;
} }
tcgetattr(fd, &tty->t_ios_default); tcgetattr(fd, &tty->t_ios_default);
@@ -94,69 +106,124 @@ static void init_tty(struct s_tty *tty, FILE *in, FILE *out)
tty->t_ios_raw.c_oflag &= ~(OPOST); tty->t_ios_raw.c_oflag &= ~(OPOST);
tty->t_ios_raw.c_lflag &= ~(ECHO | ICANON | IEXTEN); tty->t_ios_raw.c_lflag &= ~(ECHO | ICANON | IEXTEN);
tty->t_flags |= TTY_INIT; tty->t_flags |= B_TTY_INIT;
} }
struct s_tty *s_get_tty(void) struct b_tty *z__b_tty_get_std(void)
{ {
if (!(tty.t_flags & TTY_INIT)) { if (!(std.t_flags & B_TTY_INIT)) {
init_tty(&tty, stdin, stdout); init_tty(&std, stdin, stdout);
} }
return &tty; return &std;
} }
bool s_tty_is_interactive(const struct s_tty *tty) struct b_tty *z__b_tty_get_err(void)
{ {
return (tty->t_flags & TTY_INTERACTIVE) == TTY_INTERACTIVE; if (!(err.t_flags & B_TTY_INIT)) {
init_tty(&err, NULL, stderr);
}
return &err;
} }
void s_tty_set_raw(struct s_tty *tty) struct tty_format_buf *z__b_tty_get_format_buf(struct b_tty *tty)
{ {
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tty->t_ios_raw); return &tty->t_format_buf;
} }
void s_tty_set_canon(struct s_tty *tty) void z__b_tty_putc(struct b_tty *tty, char c)
{ {
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tty->t_ios_default); fputc(c, tty->t_out);
} }
void s_tty_reset_vmode(struct s_tty *tty) bool b_tty_is_interactive(const struct b_tty *tty)
{ {
if (tty->t_vmode.v_fg.c_mode == TTY_COLOUR_NONE return (tty->t_flags & B_TTY_INTERACTIVE) == B_TTY_INTERACTIVE;
&& tty->t_vmode.v_bg.c_mode == TTY_COLOUR_NONE }
&& tty->t_vmode.v_attrib == TTY_ATTRIB_NORMAL) {
static void set_raw(struct b_tty *tty)
{
int fd = -1;
if (tty->t_in) {
fd = fileno(tty->t_in);
} else if (tty->t_out) {
fd = fileno(tty->t_out);
}
if (fd == -1) {
return; return;
} }
fprintf(tty->t_out, "\033[0;39;49m"); tcsetattr(fd, TCSAFLUSH, &tty->t_ios_raw);
}
static void set_canon(struct b_tty *tty)
{
int fd = -1;
if (tty->t_in) {
fd = fileno(tty->t_in);
} else if (tty->t_out) {
fd = fileno(tty->t_out);
}
if (fd == -1) {
return;
}
tcsetattr(fd, TCSAFLUSH, &tty->t_ios_default);
}
void b_tty_set_mode(struct b_tty *tty, enum b_tty_mode mode)
{
switch (mode) {
case B_TTY_CANONICAL:
set_canon(tty);
break;
case B_TTY_RAW:
set_raw(tty);
break;
default:
break;
}
}
void b_tty_reset_vmode(struct b_tty *tty)
{
if (tty->t_vmode.v_fg.c_mode == B_TTY_COLOUR_NONE
&& tty->t_vmode.v_bg.c_mode == B_TTY_COLOUR_NONE
&& tty->t_vmode.v_attrib == B_TTY_ATTRIB_NORMAL) {
return;
}
fprintf(tty->t_out, "\033[0m");
memset(&tty->t_vmode, 0x0, sizeof tty->t_vmode); memset(&tty->t_vmode, 0x0, sizeof tty->t_vmode);
tty->t_vmode.v_fg.c_mode = TTY_COLOUR_NONE; tty->t_vmode.v_fg.c_mode = B_TTY_COLOUR_NONE;
tty->t_vmode.v_bg.c_mode = TTY_COLOUR_NONE; tty->t_vmode.v_bg.c_mode = B_TTY_COLOUR_NONE;
tty->t_vmode.v_attrib = TTY_ATTRIB_NORMAL; tty->t_vmode.v_attrib = B_TTY_ATTRIB_NORMAL;
} }
static int compare_colour( static int compare_colour(
const struct s_tty_colour *a, const struct s_tty_colour *b) const struct b_tty_colour *a, const struct b_tty_colour *b)
{ {
if (a->c_mode != b->c_mode) { if (a->c_mode != b->c_mode) {
return -1; return -1;
} }
switch (a->c_mode) { switch (a->c_mode) {
case TTY_COLOUR_16: case B_TTY_COLOUR_16:
if (a->c_16.value != b->c_16.value) { if (a->c_16.value != b->c_16.value) {
return -1; return -1;
} }
break; break;
case TTY_COLOUR_256: case B_TTY_COLOUR_256:
if (a->c_256.value != b->c_256.value) { if (a->c_256.value != b->c_256.value) {
return -1; return -1;
} }
break; break;
case TTY_COLOUR_TRUE: case B_TTY_COLOUR_TRUE:
if (a->c_true.r != b->c_true.r) { if (a->c_true.r != b->c_true.r) {
return -1; return -1;
} }
@@ -176,7 +243,7 @@ static int compare_colour(
return 0; return 0;
} }
static int compare_vmode(const struct s_tty_vmode *a, const struct s_tty_vmode *b) static int compare_vmode(const struct b_tty_vmode *a, const struct b_tty_vmode *b)
{ {
if (a->v_attrib != b->v_attrib) { if (a->v_attrib != b->v_attrib) {
return -1; return -1;
@@ -193,7 +260,7 @@ static int compare_vmode(const struct s_tty_vmode *a, const struct s_tty_vmode *
return 0; return 0;
} }
static void put_ansi_attrib(struct s_tty *tty, const char *s) static void put_ansi_attrib(struct b_tty *tty, const char *s)
{ {
if (tty->t_mcount > 0) { if (tty->t_mcount > 0) {
fputs(";", tty->t_out); fputs(";", tty->t_out);
@@ -204,46 +271,46 @@ static void put_ansi_attrib(struct s_tty *tty, const char *s)
} }
static void set_attrib( static void set_attrib(
struct s_tty *tty, enum s_tty_attrib old, enum s_tty_attrib new) struct b_tty *tty, enum b_tty_attrib old, enum b_tty_attrib new)
{ {
if (old == new) { if (old == new) {
return; return;
} }
/* Bold ON */ /* Bold ON */
if (!(old & TTY_ATTRIB_BOLD) && new &TTY_ATTRIB_BOLD) { if (!(old & B_TTY_ATTRIB_BOLD) && new &B_TTY_ATTRIB_BOLD) {
put_ansi_attrib(tty, ANSI_BOLD_ON); put_ansi_attrib(tty, ANSI_BOLD_ON);
} }
/* Bold OFF */ /* Bold OFF */
if (old & TTY_ATTRIB_BOLD && !(new &TTY_ATTRIB_BOLD)) { if (old & B_TTY_ATTRIB_BOLD && !(new &B_TTY_ATTRIB_BOLD)) {
put_ansi_attrib(tty, ANSI_BOLD_OFF); put_ansi_attrib(tty, ANSI_BOLD_OFF);
} }
/* Underline ON */ /* Underline ON */
if (!(old & TTY_ATTRIB_UNDERLINE) && new &TTY_ATTRIB_UNDERLINE) { if (!(old & B_TTY_ATTRIB_UNDERLINE) && new &B_TTY_ATTRIB_UNDERLINE) {
put_ansi_attrib(tty, ANSI_UNDERLINE_ON); put_ansi_attrib(tty, ANSI_UNDERLINE_ON);
} }
/* Underline OFF */ /* Underline OFF */
if (old & TTY_ATTRIB_UNDERLINE && !(new &TTY_ATTRIB_UNDERLINE)) { if (old & B_TTY_ATTRIB_UNDERLINE && !(new &B_TTY_ATTRIB_UNDERLINE)) {
put_ansi_attrib(tty, ANSI_UNDERLINE_OFF); put_ansi_attrib(tty, ANSI_UNDERLINE_OFF);
} }
/* Italic ON */ /* Italic ON */
if (!(old & TTY_ATTRIB_ITALIC) && new &TTY_ATTRIB_ITALIC) { if (!(old & B_TTY_ATTRIB_ITALIC) && new &B_TTY_ATTRIB_ITALIC) {
put_ansi_attrib(tty, ANSI_ITALIC_ON); put_ansi_attrib(tty, ANSI_ITALIC_ON);
} }
/* Italic OFF */ /* Italic OFF */
if (old & TTY_ATTRIB_ITALIC && !(new &TTY_ATTRIB_ITALIC)) { if (old & B_TTY_ATTRIB_ITALIC && !(new &B_TTY_ATTRIB_ITALIC)) {
put_ansi_attrib(tty, ANSI_ITALIC_OFF); put_ansi_attrib(tty, ANSI_ITALIC_OFF);
} }
} }
static void set_fg( static void set_fg(
struct s_tty *tty, const struct s_tty_colour *old, struct b_tty *tty, const struct b_tty_colour *old,
const struct s_tty_colour *new) const struct b_tty_colour *new)
{ {
if (compare_colour(old, new) == 0) { if (compare_colour(old, new) == 0) {
return; return;
@@ -252,18 +319,18 @@ static void set_fg(
char buf[8]; char buf[8];
switch (new->c_mode) { switch (new->c_mode) {
case TTY_COLOUR_NONE: case B_TTY_COLOUR_NONE:
put_ansi_attrib(tty, ANSI_DEFAULTCOLOUR_FG); put_ansi_attrib(tty, ANSI_DEFAULTCOLOUR_FG);
break; break;
case TTY_COLOUR_16: case B_TTY_COLOUR_16:
put_ansi_attrib(tty, ansi_colour16_fg[new->c_16.value]); put_ansi_attrib(tty, ansi_colour16_fg[new->c_16.value]);
break; break;
case TTY_COLOUR_256: case B_TTY_COLOUR_256:
put_ansi_attrib(tty, ANSI_256COLOUR_FG); put_ansi_attrib(tty, ANSI_256COLOUR_FG);
snprintf(buf, sizeof buf, "%u", new->c_256.value); snprintf(buf, sizeof buf, "%u", new->c_256.value);
put_ansi_attrib(tty, buf); put_ansi_attrib(tty, buf);
break; break;
case TTY_COLOUR_TRUE: case B_TTY_COLOUR_TRUE:
put_ansi_attrib(tty, ANSI_TRUECOLOUR_FG); put_ansi_attrib(tty, ANSI_TRUECOLOUR_FG);
snprintf(buf, sizeof buf, "%u", new->c_true.r); snprintf(buf, sizeof buf, "%u", new->c_true.r);
put_ansi_attrib(tty, buf); put_ansi_attrib(tty, buf);
@@ -278,8 +345,8 @@ static void set_fg(
} }
static void set_bg( static void set_bg(
struct s_tty *tty, const struct s_tty_colour *old, struct b_tty *tty, const struct b_tty_colour *old,
const struct s_tty_colour *new) const struct b_tty_colour *new)
{ {
if (compare_colour(old, new) == 0) { if (compare_colour(old, new) == 0) {
return; return;
@@ -288,18 +355,18 @@ static void set_bg(
char buf[8]; char buf[8];
switch (new->c_mode) { switch (new->c_mode) {
case TTY_COLOUR_NONE: case B_TTY_COLOUR_NONE:
put_ansi_attrib(tty, ANSI_DEFAULTCOLOUR_BG); put_ansi_attrib(tty, ANSI_DEFAULTCOLOUR_BG);
break; break;
case TTY_COLOUR_16: case B_TTY_COLOUR_16:
put_ansi_attrib(tty, ansi_colour16_bg[new->c_16.value]); put_ansi_attrib(tty, ansi_colour16_bg[new->c_16.value]);
break; break;
case TTY_COLOUR_256: case B_TTY_COLOUR_256:
put_ansi_attrib(tty, ANSI_256COLOUR_BG); put_ansi_attrib(tty, ANSI_256COLOUR_BG);
snprintf(buf, sizeof buf, "%u", new->c_256.value); snprintf(buf, sizeof buf, "%u", new->c_256.value);
put_ansi_attrib(tty, buf); put_ansi_attrib(tty, buf);
break; break;
case TTY_COLOUR_TRUE: case B_TTY_COLOUR_TRUE:
put_ansi_attrib(tty, ANSI_TRUECOLOUR_BG); put_ansi_attrib(tty, ANSI_TRUECOLOUR_BG);
snprintf(buf, sizeof buf, "%u", new->c_true.r); snprintf(buf, sizeof buf, "%u", new->c_true.r);
put_ansi_attrib(tty, buf); put_ansi_attrib(tty, buf);
@@ -313,7 +380,7 @@ static void set_bg(
} }
} }
void s_tty_set_vmode(struct s_tty *tty, const struct s_tty_vmode *vmode) void b_tty_set_vmode(struct b_tty *tty, const struct b_tty_vmode *vmode)
{ {
if (compare_vmode(&tty->t_vmode, vmode) == 0) { if (compare_vmode(&tty->t_vmode, vmode) == 0) {
return; return;
@@ -332,7 +399,7 @@ void s_tty_set_vmode(struct s_tty *tty, const struct s_tty_vmode *vmode)
memcpy(&tty->t_vmode, vmode, sizeof *vmode); memcpy(&tty->t_vmode, vmode, sizeof *vmode);
} }
s_keycode s_tty_read_key(struct s_tty *tty) b_keycode b_tty_read_key(struct b_tty *tty)
{ {
char c; char c;
int v; int v;
@@ -341,19 +408,19 @@ s_keycode s_tty_read_key(struct s_tty *tty)
while (1) { while (1) {
v = read(fd, &c, 1); v = read(fd, &c, 1);
if (v < 1) { if (v < 1) {
return S_KEY_EOF; return B_KEY_EOF;
} }
if (c == '\r' || c == '\n') { if (c == '\r' || c == '\n') {
return S_KEY_RETURN; return B_KEY_RETURN;
} }
if (c == '\b' || c == 0x7F) { if (c == '\b' || c == 0x7F) {
return S_KEY_BACKSPACE; return B_KEY_BACKSPACE;
} }
if (c >= 1 && c <= 26) { if (c >= 1 && c <= 26) {
return S_TTY_CTRL_KEY(c + 'a' - 1); return B_TTY_CTRL_KEY(c + 'a' - 1);
} }
if (c != 0x1b) { if (c != 0x1b) {
@@ -362,7 +429,7 @@ s_keycode s_tty_read_key(struct s_tty *tty)
v = read(fd, &c, 1); v = read(fd, &c, 1);
if (v < 1) { if (v < 1) {
return S_KEY_EOF; return B_KEY_EOF;
} }
if (c != '[') { if (c != '[') {
@@ -371,18 +438,18 @@ s_keycode s_tty_read_key(struct s_tty *tty)
v = read(fd, &c, 1); v = read(fd, &c, 1);
if (v < 1) { if (v < 1) {
return S_KEY_EOF; return B_KEY_EOF;
} }
switch (c) { switch (c) {
case 'A': case 'A':
return S_KEY_ARROW_UP; return B_KEY_ARROW_UP;
case 'B': case 'B':
return S_KEY_ARROW_DOWN; return B_KEY_ARROW_DOWN;
case 'C': case 'C':
return S_KEY_ARROW_RIGHT; return B_KEY_ARROW_RIGHT;
case 'D': case 'D':
return S_KEY_ARROW_LEFT; return B_KEY_ARROW_LEFT;
default: default:
continue; continue;
} }
@@ -391,9 +458,9 @@ s_keycode s_tty_read_key(struct s_tty *tty)
return c; return c;
} }
void s_tty_move_cursor_x(struct s_tty *tty, enum s_tty_position_base base, int pos) void b_tty_move_cursor_x(struct b_tty *tty, enum b_tty_position_base base, int pos)
{ {
if (base == TTY_POS_CURSOR && pos < 0 && pos >= -4) { if (base == B_TTY_POS_CURSOR && pos < 0 && pos >= -4) {
for (int i = 0; i > pos; i--) { for (int i = 0; i > pos; i--) {
fputc('\b', tty->t_out); fputc('\b', tty->t_out);
} }
@@ -401,7 +468,7 @@ void s_tty_move_cursor_x(struct s_tty *tty, enum s_tty_position_base base, int p
return; return;
} }
if (base == TTY_POS_START) { if (base == B_TTY_POS_START) {
if (pos == 0) { if (pos == 0) {
fputs("\033[G", tty->t_out); fputs("\033[G", tty->t_out);
} else { } else {
@@ -420,9 +487,9 @@ void s_tty_move_cursor_x(struct s_tty *tty, enum s_tty_position_base base, int p
} }
} }
void s_tty_move_cursor_y(struct s_tty *tty, enum s_tty_position_base base, int pos) void b_tty_move_cursor_y(struct b_tty *tty, enum b_tty_position_base base, int pos)
{ {
if (base == TTY_POS_START) { if (base == B_TTY_POS_START) {
/* we don't need this functionality right now */ /* we don't need this functionality right now */
abort(); abort();
} }
@@ -438,24 +505,48 @@ void s_tty_move_cursor_y(struct s_tty *tty, enum s_tty_position_base base, int p
} }
} }
void s_tty_clear(struct s_tty *tty, enum s_tty_clear_mode mode) void b_tty_clear(struct b_tty *tty, enum b_tty_clear_mode mode)
{ {
const char *arg; const char *arg;
if (mode & TTY_CLEAR_ALL) { if (mode & B_TTY_CLEAR_ALL) {
arg = "2"; arg = "2";
} else if (mode & TTY_CLEAR_TO_CURSOR) { } else if (mode & B_TTY_CLEAR_TO_CURSOR) {
arg = "1"; arg = "1";
} else if (mode & TTY_CLEAR_FROM_CURSOR) { } else if (mode & B_TTY_CLEAR_FROM_CURSOR) {
arg = ""; arg = "";
} else { } else {
abort(); abort();
} }
if (mode & TTY_CLEAR_SCREEN) { if (mode & B_TTY_CLEAR_SCREEN) {
fprintf(tty->t_out, "\033[%sJ", arg); fprintf(tty->t_out, "\033[%sJ", arg);
} else if (mode & TTY_CLEAR_LINE) { } else if (mode & B_TTY_CLEAR_LINE) {
fprintf(tty->t_out, "\033[%sK", arg); fprintf(tty->t_out, "\033[%sK", arg);
} else { } else {
abort(); abort();
} }
} }
enum b_status b_tty_get_dimensions(
struct b_tty *tty, unsigned int *w, unsigned int *h)
{
if (!(tty->t_flags & B_TTY_INTERACTIVE)) {
return -1;
}
int fd = fileno(tty->t_out);
struct winsize ws;
if (ioctl(fd, TIOCGWINSZ, &ws) == -1) {
return -1;
}
if (w) {
*w = ws.ws_col;
}
if (h) {
*h = ws.ws_row;
}
return 0;
}

View File

@@ -1,49 +1,50 @@
#include <blue/term/tty.h>
#include <blue/core/hash.h>
#include "tty.h" #include "tty.h"
#include "printf.h"
#define MOD_HASH_BLACK 0x4b5dd0abbc6fc1e4 #include <blue/core/hash.h>
#define MOD_HASH_RED 0x89e9be1960f4c21c #include <blue/term/tty.h>
#define MOD_HASH_GREEN 0x0f40f029637fecbc #include <string.h>
#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_BLACK 0x4b5dd0abbc6fc1e4
#define MOD_HASH_BRIGHT_RED 0xbad8e3fe841b9385 #define MOD_HASH_RED 0x89e9be1960f4c21c
#define MOD_HASH_BRIGHT_GREEN 0x11cc5e579bdd2fb9 #define MOD_HASH_GREEN 0x0f40f029637fecbc
#define MOD_HASH_BRIGHT_YELLOW 0xfd579007fe8579f6 #define MOD_HASH_YELLOW 0x8346a574925e75a9
#define MOD_HASH_BRIGHT_BLUE 0x57c76bf18badb6d6 #define MOD_HASH_BLUE 0xc5ccd29bc2dda64d
#define MOD_HASH_BRIGHT_MAGENTA 0xf6ecc6d3fdfec129 #define MOD_HASH_MAGENTA 0x6c90e772edbc8708
#define MOD_HASH_BRIGHT_CYAN 0x03df73fd4e12ec6d #define MOD_HASH_CYAN 0x70ae2e90c1bce27a
#define MOD_HASH_BRIGHT_WHITE 0xb5ebc3323f57d7fb #define MOD_HASH_WHITE 0xced973885856e206
#define MOD_HASH_BG_BLACK 0xd87a8f2d9d394432 #define MOD_HASH_DARK_GREY 0x55a19de854654d99
#define MOD_HASH_BG_RED 0x145b1e4366c7d7aa #define MOD_HASH_BRIGHT_RED 0xbad8e3fe841b9385
#define MOD_HASH_BG_GREEN 0xa00b8541d3b1e55a #define MOD_HASH_BRIGHT_GREEN 0x11cc5e579bdd2fb9
#define MOD_HASH_BG_YELLOW 0x98b030fd86e3b3cf #define MOD_HASH_BRIGHT_YELLOW 0xfd579007fe8579f6
#define MOD_HASH_BG_BLUE 0xa15529109506b5df #define MOD_HASH_BRIGHT_BLUE 0x57c76bf18badb6d6
#define MOD_HASH_BG_MAGENTA 0x86dbda99bcc86222 #define MOD_HASH_BRIGHT_MAGENTA 0xf6ecc6d3fdfec129
#define MOD_HASH_BG_CYAN 0xf16a3104cf61a098 #define MOD_HASH_BRIGHT_CYAN 0x03df73fd4e12ec6d
#define MOD_HASH_BG_WHITE 0x3408c46ab5836674 #define MOD_HASH_BRIGHT_WHITE 0xb5ebc3323f57d7fb
#define MOD_HASH_BG_DARK_GREY 0x820d2e77568eec47 #define MOD_HASH_BG_BLACK 0xd87a8f2d9d394432
#define MOD_HASH_BRIGHT_BG_RED 0x144f5dc138087701 #define MOD_HASH_BG_RED 0x145b1e4366c7d7aa
#define MOD_HASH_BRIGHT_BG_GREEN 0xc4d88c6426ffe355 #define MOD_HASH_BG_GREEN 0xa00b8541d3b1e55a
#define MOD_HASH_BRIGHT_BG_YELLOW 0xf7bb000a4a792602 #define MOD_HASH_BG_YELLOW 0x98b030fd86e3b3cf
#define MOD_HASH_BRIGHT_BG_BLUE 0x9b5c16d6807a1002 #define MOD_HASH_BG_BLUE 0xa15529109506b5df
#define MOD_HASH_BRIGHT_BG_MAGENTA 0xc59fb2196cdba3fd #define MOD_HASH_BG_MAGENTA 0x86dbda99bcc86222
#define MOD_HASH_BRIGHT_BG_CYAN 0x46feb6dc999a6f09 #define MOD_HASH_BG_CYAN 0xf16a3104cf61a098
#define MOD_HASH_BRIGHT_BG_WHITE 0xa3e7d1da08826f5f #define MOD_HASH_BG_WHITE 0x3408c46ab5836674
#define MOD_HASH_BOLD 0xcd32ea9bc6b26ff6 #define MOD_HASH_BG_DARK_GREY 0x820d2e77568eec47
#define MOD_HASH_ULINE 0x141fe741e9f8c22a #define MOD_HASH_BRIGHT_BG_RED 0x144f5dc138087701
#define MOD_HASH_ITALIC 0x69d5e5f057d8992d #define MOD_HASH_BRIGHT_BG_GREEN 0xc4d88c6426ffe355
#define MOD_HASH_INVERT 0xab4ab85ddd6232e1 #define MOD_HASH_BRIGHT_BG_YELLOW 0xf7bb000a4a792602
#define MOD_HASH_RESET 0x0f136ff2c086b760 #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)) #define COMPARE_MOD_NAME(ss, sd, hs, hd) ((hs) == (hd) && !strcmp(ss, sd))
@@ -102,32 +103,38 @@ static void apply_code_to_vmode(struct tty_format_buf *fmt)
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_RED; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_GREEN; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_YELLOW; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLUE; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_MAGENTA; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_CYAN; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_WHITE; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_WHITE;
} }
@@ -172,42 +179,54 @@ static void apply_code_to_vmode(struct tty_format_buf *fmt)
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_WHITE; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLACK; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_RED; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_GREEN; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_YELLOW; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLUE; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_MAGENTA; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_CYAN; 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)) { 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_mode = B_TTY_COLOUR_16;
fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_WHITE; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_WHITE;
} }
@@ -229,16 +248,14 @@ static void apply_code_to_vmode(struct tty_format_buf *fmt)
} }
if (COMPARE_MOD_NAME(modifier, "reset", mod_hash, MOD_HASH_RESET)) { if (COMPARE_MOD_NAME(modifier, "reset", mod_hash, MOD_HASH_RESET)) {
fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->reset_vmode = true;
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_NONE;
fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_NONE;
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; fmt->vmode.v_attrib = 0;
} }
} }
static void format_buffer_putc(struct tty_format_buf* fmt, int c) static void format_buffer_putc(struct tty_format_buf *fmt, int c)
{ {
if (fmt->ptr < TTY_TMPBUF_SIZE - 1) { if (fmt->ptr < TTY_TMPBUF_SIZE - 1) {
fmt->buf[fmt->ptr++] = c; fmt->buf[fmt->ptr++] = c;
@@ -246,15 +263,20 @@ static void format_buffer_putc(struct tty_format_buf* fmt, int c)
} }
} }
static void format_buffer_clear(struct tty_format_buf* fmt) static void format_buffer_clear(struct tty_format_buf *fmt)
{ {
fmt->ptr = 0; fmt->ptr = 0;
fmt->buf[fmt->ptr] = '\0'; fmt->buf[fmt->ptr] = '\0';
fmt->reset_vmode = false;
} }
static void flush_vmode(struct b_tty* tty, struct tty_format_buf* fmt) static void flush_vmode(struct b_tty *tty, struct tty_format_buf *fmt)
{ {
b_tty_set_vmode(tty, &fmt->vmode); if (fmt->reset_vmode) {
b_tty_reset_vmode(tty);
} else {
b_tty_set_vmode(tty, &fmt->vmode);
}
} }
int b_tty_putc(struct b_tty *tty, enum b_tty_print_flags flags, char c) int b_tty_putc(struct b_tty *tty, enum b_tty_print_flags flags, char c)
@@ -265,7 +287,7 @@ int b_tty_putc(struct b_tty *tty, enum b_tty_print_flags flags, char c)
} }
struct tty_format_buf *fmt = z__b_tty_get_format_buf(tty); struct tty_format_buf *fmt = z__b_tty_get_format_buf(tty);
if (c == '[') { if (c == '[') {
if (!fmt->in_format) { if (!fmt->in_format) {
fmt->in_format = true; fmt->in_format = true;
@@ -306,8 +328,7 @@ int b_tty_putc(struct b_tty *tty, enum b_tty_print_flags flags, char c)
return c; return c;
} }
int b_tty_puts( int b_tty_puts(struct b_tty *tty, enum b_tty_print_flags flags, const char *s)
struct b_tty* tty, enum b_tty_print_flags flags, const char* s)
{ {
int r = 0; int r = 0;
@@ -319,8 +340,7 @@ int b_tty_puts(
return r; return r;
} }
int b_tty_printf( int b_tty_printf(struct b_tty *tty, enum b_tty_print_flags flags, const char *s, ...)
struct b_tty* tty, enum b_tty_print_flags flags, const char* s, ...)
{ {
va_list arg; va_list arg;
va_start(arg, s); va_start(arg, s);

View File

@@ -1,12 +1,16 @@
#ifndef _TTY_H_ #ifndef _TTY_H_
#define _TTY_H_ #define _TTY_H_
#include <blue/term/tty.h>
#include <stdbool.h>
#define TTY_TMPBUF_SIZE 128 #define TTY_TMPBUF_SIZE 128
struct b_tty; struct b_tty;
struct tty_format_buf { struct tty_format_buf {
bool in_format; bool in_format;
bool reset_vmode;
char buf[TTY_TMPBUF_SIZE]; char buf[TTY_TMPBUF_SIZE];
unsigned int ptr; unsigned int ptr;
@@ -16,4 +20,4 @@ struct tty_format_buf {
extern struct tty_format_buf *z__b_tty_get_format_buf(struct b_tty *tty); extern struct tty_format_buf *z__b_tty_get_format_buf(struct b_tty *tty);
extern void z__b_tty_putc(struct b_tty *tty, char c); extern void z__b_tty_putc(struct b_tty *tty, char c);
#endif #endif