From eda7a1f9512e34ae99d08b3162930bb211c0c4ba Mon Sep 17 00:00:00 2001 From: Max Wash Date: Tue, 19 Nov 2024 13:00:11 +0000 Subject: [PATCH] frontend: line-ed: add missing tty function implementations for linux & darwin --- frontend/sys/darwin/line-ed/tty.c | 189 +++++++++++++++++++++--------- frontend/sys/linux/line-ed/tty.c | 189 +++++++++++++++++++++--------- 2 files changed, 266 insertions(+), 112 deletions(-) diff --git a/frontend/sys/darwin/line-ed/tty.c b/frontend/sys/darwin/line-ed/tty.c index 0368583..e2ca52f 100644 --- a/frontend/sys/darwin/line-ed/tty.c +++ b/frontend/sys/darwin/line-ed/tty.c @@ -1,25 +1,27 @@ +#include "../../../line-ed/tty.h" + +#include +#include +#include #include #include #include -#include -#include -#include "tty.h" -#define ANSI_BOLD_ON "1" -#define ANSI_BOLD_OFF "22" -#define ANSI_ITALIC_ON "3" -#define ANSI_ITALIC_OFF "23" -#define ANSI_UNDERLINE_ON "4" -#define ANSI_UNDERLINE_OFF "24" +#define ANSI_BOLD_ON "1" +#define ANSI_BOLD_OFF "22" +#define ANSI_ITALIC_ON "3" +#define ANSI_ITALIC_OFF "23" +#define ANSI_UNDERLINE_ON "4" +#define ANSI_UNDERLINE_OFF "24" #define ANSI_DEFAULTCOLOUR_FG "39" #define ANSI_DEFAULTCOLOUR_BG "49" -#define ANSI_256COLOUR_FG "38;5" -#define ANSI_256COLOUR_BG "48;5" +#define ANSI_256COLOUR_FG "38;5" +#define ANSI_256COLOUR_BG "48;5" -#define ANSI_TRUECOLOUR_FG "38;2" -#define ANSI_TRUECOLOUR_BG "48;2" +#define ANSI_TRUECOLOUR_FG "38;2" +#define ANSI_TRUECOLOUR_BG "48;2" enum tty_flags { TTY_INIT = 0x01u, @@ -37,41 +39,41 @@ struct s_tty { static struct s_tty tty = {}; static const char *ansi_colour16_fg[] = { - [TTY_COLOUR16_BLACK] = "30", - [TTY_COLOUR16_RED] = "31", - [TTY_COLOUR16_GREEN] = "32", - [TTY_COLOUR16_YELLOW] = "33", - [TTY_COLOUR16_BLUE] = "34", - [TTY_COLOUR16_MAGENTA] = "35", - [TTY_COLOUR16_CYAN] = "36", - [TTY_COLOUR16_WHITE] = "37", - [TTY_COLOUR16_GREY] = "90", - [TTY_COLOUR16_BRIGHT_RED] = "91", - [TTY_COLOUR16_BRIGHT_GREEN] = "92", - [TTY_COLOUR16_BRIGHT_YELLOW] = "93", - [TTY_COLOUR16_BRIGHT_BLUE] = "94", + [TTY_COLOUR16_BLACK] = "30", + [TTY_COLOUR16_RED] = "31", + [TTY_COLOUR16_GREEN] = "32", + [TTY_COLOUR16_YELLOW] = "33", + [TTY_COLOUR16_BLUE] = "34", + [TTY_COLOUR16_MAGENTA] = "35", + [TTY_COLOUR16_CYAN] = "36", + [TTY_COLOUR16_WHITE] = "37", + [TTY_COLOUR16_GREY] = "90", + [TTY_COLOUR16_BRIGHT_RED] = "91", + [TTY_COLOUR16_BRIGHT_GREEN] = "92", + [TTY_COLOUR16_BRIGHT_YELLOW] = "93", + [TTY_COLOUR16_BRIGHT_BLUE] = "94", [TTY_COLOUR16_BRIGHT_MAGENTA] = "95", - [TTY_COLOUR16_BRIGHT_CYAN] = "96", - [TTY_COLOUR16_BRIGHT_WHITE] = "97", + [TTY_COLOUR16_BRIGHT_CYAN] = "96", + [TTY_COLOUR16_BRIGHT_WHITE] = "97", }; static const char *ansi_colour16_bg[] = { - [TTY_COLOUR16_BLACK] = "40", - [TTY_COLOUR16_RED] = "41", - [TTY_COLOUR16_GREEN] = "42", - [TTY_COLOUR16_YELLOW] = "43", - [TTY_COLOUR16_BLUE] = "44", - [TTY_COLOUR16_MAGENTA] = "45", - [TTY_COLOUR16_CYAN] = "46", - [TTY_COLOUR16_WHITE] = "47", - [TTY_COLOUR16_GREY] = "100", - [TTY_COLOUR16_BRIGHT_RED] = "101", - [TTY_COLOUR16_BRIGHT_GREEN] = "102", - [TTY_COLOUR16_BRIGHT_YELLOW] = "103", - [TTY_COLOUR16_BRIGHT_BLUE] = "104", + [TTY_COLOUR16_BLACK] = "40", + [TTY_COLOUR16_RED] = "41", + [TTY_COLOUR16_GREEN] = "42", + [TTY_COLOUR16_YELLOW] = "43", + [TTY_COLOUR16_BLUE] = "44", + [TTY_COLOUR16_MAGENTA] = "45", + [TTY_COLOUR16_CYAN] = "46", + [TTY_COLOUR16_WHITE] = "47", + [TTY_COLOUR16_GREY] = "100", + [TTY_COLOUR16_BRIGHT_RED] = "101", + [TTY_COLOUR16_BRIGHT_GREEN] = "102", + [TTY_COLOUR16_BRIGHT_YELLOW] = "103", + [TTY_COLOUR16_BRIGHT_BLUE] = "104", [TTY_COLOUR16_BRIGHT_MAGENTA] = "105", - [TTY_COLOUR16_BRIGHT_CYAN] = "106", - [TTY_COLOUR16_BRIGHT_WHITE] = "107", + [TTY_COLOUR16_BRIGHT_CYAN] = "106", + [TTY_COLOUR16_BRIGHT_WHITE] = "107", }; static void init_tty(struct s_tty *tty, FILE *in, FILE *out) @@ -122,8 +124,8 @@ void s_tty_set_canon(struct s_tty *tty) void s_tty_reset_vmode(struct s_tty *tty) { if (tty->t_vmode.v_fg.c_mode == TTY_COLOUR_NONE - && tty->t_vmode.v_bg.c_mode == TTY_COLOUR_NONE - && tty->t_vmode.v_attrib == TTY_ATTRIB_NORMAL) { + && tty->t_vmode.v_bg.c_mode == TTY_COLOUR_NONE + && tty->t_vmode.v_attrib == TTY_ATTRIB_NORMAL) { return; } @@ -136,7 +138,8 @@ void s_tty_reset_vmode(struct s_tty *tty) tty->t_vmode.v_attrib = TTY_ATTRIB_NORMAL; } -static int compare_colour(const struct s_tty_colour *a, const struct s_tty_colour *b) +static int compare_colour( + const struct s_tty_colour *a, const struct s_tty_colour *b) { if (a->c_mode != b->c_mode) { return -1; @@ -200,44 +203,47 @@ static void put_ansi_attrib(struct s_tty *tty, const char *s) tty->t_mcount++; } -static void set_attrib(struct s_tty *tty, enum s_tty_attrib old, enum s_tty_attrib new) +static void set_attrib( + struct s_tty *tty, enum s_tty_attrib old, enum s_tty_attrib new) { if (old == new) { return; } /* Bold ON */ - if (!(old & TTY_ATTRIB_BOLD) && new & TTY_ATTRIB_BOLD) { + if (!(old & TTY_ATTRIB_BOLD) && new &TTY_ATTRIB_BOLD) { put_ansi_attrib(tty, ANSI_BOLD_ON); } /* Bold OFF */ - if (old & TTY_ATTRIB_BOLD && !(new & TTY_ATTRIB_BOLD)) { + if (old & TTY_ATTRIB_BOLD && !(new &TTY_ATTRIB_BOLD)) { put_ansi_attrib(tty, ANSI_BOLD_OFF); } /* Underline ON */ - if (!(old & TTY_ATTRIB_UNDERLINE) && new & TTY_ATTRIB_UNDERLINE) { + if (!(old & TTY_ATTRIB_UNDERLINE) && new &TTY_ATTRIB_UNDERLINE) { put_ansi_attrib(tty, ANSI_UNDERLINE_ON); } /* Underline OFF */ - if (old & TTY_ATTRIB_UNDERLINE && !(new & TTY_ATTRIB_UNDERLINE)) { + if (old & TTY_ATTRIB_UNDERLINE && !(new &TTY_ATTRIB_UNDERLINE)) { put_ansi_attrib(tty, ANSI_UNDERLINE_OFF); } /* Italic ON */ - if (!(old & TTY_ATTRIB_ITALIC) && new & TTY_ATTRIB_ITALIC) { + if (!(old & TTY_ATTRIB_ITALIC) && new &TTY_ATTRIB_ITALIC) { put_ansi_attrib(tty, ANSI_ITALIC_ON); } /* Italic OFF */ - if (old & TTY_ATTRIB_ITALIC && !(new & TTY_ATTRIB_ITALIC)) { + if (old & TTY_ATTRIB_ITALIC && !(new &TTY_ATTRIB_ITALIC)) { put_ansi_attrib(tty, ANSI_ITALIC_OFF); } } -static void set_fg(struct s_tty *tty, const struct s_tty_colour *old, const struct s_tty_colour *new) +static void set_fg( + struct s_tty *tty, const struct s_tty_colour *old, + const struct s_tty_colour *new) { if (compare_colour(old, new) == 0) { return; @@ -271,7 +277,9 @@ static void set_fg(struct s_tty *tty, const struct s_tty_colour *old, const stru } } -static void set_bg(struct s_tty *tty, const struct s_tty_colour *old, const struct s_tty_colour *new) +static void set_bg( + struct s_tty *tty, const struct s_tty_colour *old, + const struct s_tty_colour *new) { if (compare_colour(old, new) == 0) { return; @@ -337,7 +345,7 @@ s_keycode s_tty_read_key(struct s_tty *tty) } if (c == '\r' || c == '\n') { - return S_KEY_RETURN; + return S_KEY_RETURN; } if (c == '\b' || c == 0x7F) { @@ -382,3 +390,72 @@ s_keycode s_tty_read_key(struct s_tty *tty) return c; } + +void s_tty_move_cursor_x(struct s_tty *tty, enum s_tty_position_base base, int pos) +{ + if (base == TTY_POS_CURSOR && pos < 0 && pos >= -4) { + for (int i = 0; i > pos; i--) { + fputc('\b', tty->t_out); + } + + return; + } + + if (base == TTY_POS_START) { + if (pos == 0) { + fputs("\033[G", tty->t_out); + } else { + fprintf(tty->t_out, "\033[%dG", pos + 1); + } + } else { + if (pos > 1) { + fprintf(tty->t_out, "\033[%dC", pos); + } else if (pos == 1) { + fputs("\033[C", tty->t_out); + } else if (pos == -1) { + fputs("\033[D", tty->t_out); + } else if (pos < -1) { + fprintf(tty->t_out, "\033[%dD", -pos); + } + } +} + +void s_tty_move_cursor_y(struct s_tty *tty, enum s_tty_position_base base, int pos) +{ + if (base == TTY_POS_START) { + /* we don't need this functionality right now */ + abort(); + } + + if (pos > 1) { + fprintf(tty->t_out, "\033[%dB", pos); + } else if (pos == 1) { + fputs("\033[B", tty->t_out); + } else if (pos == -1) { + fputs("\033[A", tty->t_out); + } else if (pos < -1) { + fprintf(tty->t_out, "\033[%dA", -pos); + } +} + +void s_tty_clear(struct s_tty *tty, enum s_tty_clear_mode mode) +{ + const char *arg; + if (mode & TTY_CLEAR_ALL) { + arg = "2"; + } else if (mode & TTY_CLEAR_TO_CURSOR) { + arg = "1"; + } else if (mode & TTY_CLEAR_FROM_CURSOR) { + arg = ""; + } else { + abort(); + } + + if (mode & TTY_CLEAR_SCREEN) { + fprintf(tty->t_out, "\033[%sJ", arg); + } else if (mode & TTY_CLEAR_LINE) { + fprintf(tty->t_out, "\033[%sK", arg); + } else { + abort(); + } +} diff --git a/frontend/sys/linux/line-ed/tty.c b/frontend/sys/linux/line-ed/tty.c index 0368583..e2ca52f 100644 --- a/frontend/sys/linux/line-ed/tty.c +++ b/frontend/sys/linux/line-ed/tty.c @@ -1,25 +1,27 @@ +#include "../../../line-ed/tty.h" + +#include +#include +#include #include #include #include -#include -#include -#include "tty.h" -#define ANSI_BOLD_ON "1" -#define ANSI_BOLD_OFF "22" -#define ANSI_ITALIC_ON "3" -#define ANSI_ITALIC_OFF "23" -#define ANSI_UNDERLINE_ON "4" -#define ANSI_UNDERLINE_OFF "24" +#define ANSI_BOLD_ON "1" +#define ANSI_BOLD_OFF "22" +#define ANSI_ITALIC_ON "3" +#define ANSI_ITALIC_OFF "23" +#define ANSI_UNDERLINE_ON "4" +#define ANSI_UNDERLINE_OFF "24" #define ANSI_DEFAULTCOLOUR_FG "39" #define ANSI_DEFAULTCOLOUR_BG "49" -#define ANSI_256COLOUR_FG "38;5" -#define ANSI_256COLOUR_BG "48;5" +#define ANSI_256COLOUR_FG "38;5" +#define ANSI_256COLOUR_BG "48;5" -#define ANSI_TRUECOLOUR_FG "38;2" -#define ANSI_TRUECOLOUR_BG "48;2" +#define ANSI_TRUECOLOUR_FG "38;2" +#define ANSI_TRUECOLOUR_BG "48;2" enum tty_flags { TTY_INIT = 0x01u, @@ -37,41 +39,41 @@ struct s_tty { static struct s_tty tty = {}; static const char *ansi_colour16_fg[] = { - [TTY_COLOUR16_BLACK] = "30", - [TTY_COLOUR16_RED] = "31", - [TTY_COLOUR16_GREEN] = "32", - [TTY_COLOUR16_YELLOW] = "33", - [TTY_COLOUR16_BLUE] = "34", - [TTY_COLOUR16_MAGENTA] = "35", - [TTY_COLOUR16_CYAN] = "36", - [TTY_COLOUR16_WHITE] = "37", - [TTY_COLOUR16_GREY] = "90", - [TTY_COLOUR16_BRIGHT_RED] = "91", - [TTY_COLOUR16_BRIGHT_GREEN] = "92", - [TTY_COLOUR16_BRIGHT_YELLOW] = "93", - [TTY_COLOUR16_BRIGHT_BLUE] = "94", + [TTY_COLOUR16_BLACK] = "30", + [TTY_COLOUR16_RED] = "31", + [TTY_COLOUR16_GREEN] = "32", + [TTY_COLOUR16_YELLOW] = "33", + [TTY_COLOUR16_BLUE] = "34", + [TTY_COLOUR16_MAGENTA] = "35", + [TTY_COLOUR16_CYAN] = "36", + [TTY_COLOUR16_WHITE] = "37", + [TTY_COLOUR16_GREY] = "90", + [TTY_COLOUR16_BRIGHT_RED] = "91", + [TTY_COLOUR16_BRIGHT_GREEN] = "92", + [TTY_COLOUR16_BRIGHT_YELLOW] = "93", + [TTY_COLOUR16_BRIGHT_BLUE] = "94", [TTY_COLOUR16_BRIGHT_MAGENTA] = "95", - [TTY_COLOUR16_BRIGHT_CYAN] = "96", - [TTY_COLOUR16_BRIGHT_WHITE] = "97", + [TTY_COLOUR16_BRIGHT_CYAN] = "96", + [TTY_COLOUR16_BRIGHT_WHITE] = "97", }; static const char *ansi_colour16_bg[] = { - [TTY_COLOUR16_BLACK] = "40", - [TTY_COLOUR16_RED] = "41", - [TTY_COLOUR16_GREEN] = "42", - [TTY_COLOUR16_YELLOW] = "43", - [TTY_COLOUR16_BLUE] = "44", - [TTY_COLOUR16_MAGENTA] = "45", - [TTY_COLOUR16_CYAN] = "46", - [TTY_COLOUR16_WHITE] = "47", - [TTY_COLOUR16_GREY] = "100", - [TTY_COLOUR16_BRIGHT_RED] = "101", - [TTY_COLOUR16_BRIGHT_GREEN] = "102", - [TTY_COLOUR16_BRIGHT_YELLOW] = "103", - [TTY_COLOUR16_BRIGHT_BLUE] = "104", + [TTY_COLOUR16_BLACK] = "40", + [TTY_COLOUR16_RED] = "41", + [TTY_COLOUR16_GREEN] = "42", + [TTY_COLOUR16_YELLOW] = "43", + [TTY_COLOUR16_BLUE] = "44", + [TTY_COLOUR16_MAGENTA] = "45", + [TTY_COLOUR16_CYAN] = "46", + [TTY_COLOUR16_WHITE] = "47", + [TTY_COLOUR16_GREY] = "100", + [TTY_COLOUR16_BRIGHT_RED] = "101", + [TTY_COLOUR16_BRIGHT_GREEN] = "102", + [TTY_COLOUR16_BRIGHT_YELLOW] = "103", + [TTY_COLOUR16_BRIGHT_BLUE] = "104", [TTY_COLOUR16_BRIGHT_MAGENTA] = "105", - [TTY_COLOUR16_BRIGHT_CYAN] = "106", - [TTY_COLOUR16_BRIGHT_WHITE] = "107", + [TTY_COLOUR16_BRIGHT_CYAN] = "106", + [TTY_COLOUR16_BRIGHT_WHITE] = "107", }; static void init_tty(struct s_tty *tty, FILE *in, FILE *out) @@ -122,8 +124,8 @@ void s_tty_set_canon(struct s_tty *tty) void s_tty_reset_vmode(struct s_tty *tty) { if (tty->t_vmode.v_fg.c_mode == TTY_COLOUR_NONE - && tty->t_vmode.v_bg.c_mode == TTY_COLOUR_NONE - && tty->t_vmode.v_attrib == TTY_ATTRIB_NORMAL) { + && tty->t_vmode.v_bg.c_mode == TTY_COLOUR_NONE + && tty->t_vmode.v_attrib == TTY_ATTRIB_NORMAL) { return; } @@ -136,7 +138,8 @@ void s_tty_reset_vmode(struct s_tty *tty) tty->t_vmode.v_attrib = TTY_ATTRIB_NORMAL; } -static int compare_colour(const struct s_tty_colour *a, const struct s_tty_colour *b) +static int compare_colour( + const struct s_tty_colour *a, const struct s_tty_colour *b) { if (a->c_mode != b->c_mode) { return -1; @@ -200,44 +203,47 @@ static void put_ansi_attrib(struct s_tty *tty, const char *s) tty->t_mcount++; } -static void set_attrib(struct s_tty *tty, enum s_tty_attrib old, enum s_tty_attrib new) +static void set_attrib( + struct s_tty *tty, enum s_tty_attrib old, enum s_tty_attrib new) { if (old == new) { return; } /* Bold ON */ - if (!(old & TTY_ATTRIB_BOLD) && new & TTY_ATTRIB_BOLD) { + if (!(old & TTY_ATTRIB_BOLD) && new &TTY_ATTRIB_BOLD) { put_ansi_attrib(tty, ANSI_BOLD_ON); } /* Bold OFF */ - if (old & TTY_ATTRIB_BOLD && !(new & TTY_ATTRIB_BOLD)) { + if (old & TTY_ATTRIB_BOLD && !(new &TTY_ATTRIB_BOLD)) { put_ansi_attrib(tty, ANSI_BOLD_OFF); } /* Underline ON */ - if (!(old & TTY_ATTRIB_UNDERLINE) && new & TTY_ATTRIB_UNDERLINE) { + if (!(old & TTY_ATTRIB_UNDERLINE) && new &TTY_ATTRIB_UNDERLINE) { put_ansi_attrib(tty, ANSI_UNDERLINE_ON); } /* Underline OFF */ - if (old & TTY_ATTRIB_UNDERLINE && !(new & TTY_ATTRIB_UNDERLINE)) { + if (old & TTY_ATTRIB_UNDERLINE && !(new &TTY_ATTRIB_UNDERLINE)) { put_ansi_attrib(tty, ANSI_UNDERLINE_OFF); } /* Italic ON */ - if (!(old & TTY_ATTRIB_ITALIC) && new & TTY_ATTRIB_ITALIC) { + if (!(old & TTY_ATTRIB_ITALIC) && new &TTY_ATTRIB_ITALIC) { put_ansi_attrib(tty, ANSI_ITALIC_ON); } /* Italic OFF */ - if (old & TTY_ATTRIB_ITALIC && !(new & TTY_ATTRIB_ITALIC)) { + if (old & TTY_ATTRIB_ITALIC && !(new &TTY_ATTRIB_ITALIC)) { put_ansi_attrib(tty, ANSI_ITALIC_OFF); } } -static void set_fg(struct s_tty *tty, const struct s_tty_colour *old, const struct s_tty_colour *new) +static void set_fg( + struct s_tty *tty, const struct s_tty_colour *old, + const struct s_tty_colour *new) { if (compare_colour(old, new) == 0) { return; @@ -271,7 +277,9 @@ static void set_fg(struct s_tty *tty, const struct s_tty_colour *old, const stru } } -static void set_bg(struct s_tty *tty, const struct s_tty_colour *old, const struct s_tty_colour *new) +static void set_bg( + struct s_tty *tty, const struct s_tty_colour *old, + const struct s_tty_colour *new) { if (compare_colour(old, new) == 0) { return; @@ -337,7 +345,7 @@ s_keycode s_tty_read_key(struct s_tty *tty) } if (c == '\r' || c == '\n') { - return S_KEY_RETURN; + return S_KEY_RETURN; } if (c == '\b' || c == 0x7F) { @@ -382,3 +390,72 @@ s_keycode s_tty_read_key(struct s_tty *tty) return c; } + +void s_tty_move_cursor_x(struct s_tty *tty, enum s_tty_position_base base, int pos) +{ + if (base == TTY_POS_CURSOR && pos < 0 && pos >= -4) { + for (int i = 0; i > pos; i--) { + fputc('\b', tty->t_out); + } + + return; + } + + if (base == TTY_POS_START) { + if (pos == 0) { + fputs("\033[G", tty->t_out); + } else { + fprintf(tty->t_out, "\033[%dG", pos + 1); + } + } else { + if (pos > 1) { + fprintf(tty->t_out, "\033[%dC", pos); + } else if (pos == 1) { + fputs("\033[C", tty->t_out); + } else if (pos == -1) { + fputs("\033[D", tty->t_out); + } else if (pos < -1) { + fprintf(tty->t_out, "\033[%dD", -pos); + } + } +} + +void s_tty_move_cursor_y(struct s_tty *tty, enum s_tty_position_base base, int pos) +{ + if (base == TTY_POS_START) { + /* we don't need this functionality right now */ + abort(); + } + + if (pos > 1) { + fprintf(tty->t_out, "\033[%dB", pos); + } else if (pos == 1) { + fputs("\033[B", tty->t_out); + } else if (pos == -1) { + fputs("\033[A", tty->t_out); + } else if (pos < -1) { + fprintf(tty->t_out, "\033[%dA", -pos); + } +} + +void s_tty_clear(struct s_tty *tty, enum s_tty_clear_mode mode) +{ + const char *arg; + if (mode & TTY_CLEAR_ALL) { + arg = "2"; + } else if (mode & TTY_CLEAR_TO_CURSOR) { + arg = "1"; + } else if (mode & TTY_CLEAR_FROM_CURSOR) { + arg = ""; + } else { + abort(); + } + + if (mode & TTY_CLEAR_SCREEN) { + fprintf(tty->t_out, "\033[%sJ", arg); + } else if (mode & TTY_CLEAR_LINE) { + fprintf(tty->t_out, "\033[%sK", arg); + } else { + abort(); + } +}