diff options
Diffstat (limited to 'src/roms/ipxe/src/hci/mucurses/ansi_screen.c')
-rw-r--r-- | src/roms/ipxe/src/hci/mucurses/ansi_screen.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/roms/ipxe/src/hci/mucurses/ansi_screen.c b/src/roms/ipxe/src/hci/mucurses/ansi_screen.c new file mode 100644 index 0000000..1cf3309 --- /dev/null +++ b/src/roms/ipxe/src/hci/mucurses/ansi_screen.c @@ -0,0 +1,102 @@ +#include <stdio.h> +#include <curses.h> +#include <ipxe/ansicol.h> +#include <ipxe/console.h> + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +static void ansiscr_reset(struct _curses_screen *scr) __nonnull; +static void ansiscr_movetoyx(struct _curses_screen *scr, + unsigned int y, unsigned int x) __nonnull; +static void ansiscr_putc(struct _curses_screen *scr, chtype c) __nonnull; + +static unsigned int saved_usage; + +static void ansiscr_attrs ( struct _curses_screen *scr, attr_t attrs ) { + int bold = ( attrs & A_BOLD ); + attr_t cpair = PAIR_NUMBER ( attrs ); + + if ( scr->attrs != attrs ) { + scr->attrs = attrs; + /* Reset attributes and set/clear bold as appropriate */ + printf ( "\033[0;%dm", ( bold ? 1 : 22 ) ); + /* Set foreground and background colours */ + ansicol_set_pair ( cpair ); + } +} + +static void ansiscr_reset ( struct _curses_screen *scr ) { + /* Reset terminal attributes and clear screen */ + scr->attrs = 0; + scr->curs_x = 0; + scr->curs_y = 0; + printf ( "\0330m" ); + ansicol_set_pair ( CPAIR_DEFAULT ); + printf ( "\033[2J" ); +} + +static void ansiscr_init ( struct _curses_screen *scr ) { + saved_usage = console_set_usage ( CONSOLE_USAGE_TUI ); + ansiscr_reset ( scr ); +} + +static void ansiscr_exit ( struct _curses_screen *scr ) { + ansiscr_reset ( scr ); + console_set_usage ( saved_usage ); +} + +static void ansiscr_erase ( struct _curses_screen *scr, attr_t attrs ) { + ansiscr_attrs ( scr, attrs ); + printf ( "\033[2J" ); +} + +static void ansiscr_movetoyx ( struct _curses_screen *scr, + unsigned int y, unsigned int x ) { + if ( ( x != scr->curs_x ) || ( y != scr->curs_y ) ) { + /* ANSI escape sequence to update cursor position */ + printf ( "\033[%d;%dH", ( y + 1 ), ( x + 1 ) ); + scr->curs_x = x; + scr->curs_y = y; + } +} + +static void ansiscr_putc ( struct _curses_screen *scr, chtype c ) { + unsigned int character = ( c & A_CHARTEXT ); + attr_t attrs = ( c & ( A_ATTRIBUTES | A_COLOR ) ); + + /* Update attributes if changed */ + ansiscr_attrs ( scr, attrs ); + + /* Print the actual character */ + putchar ( character ); + + /* Update expected cursor position */ + if ( ++(scr->curs_x) == COLS ) { + scr->curs_x = 0; + ++scr->curs_y; + } +} + +static int ansiscr_getc ( struct _curses_screen *scr __unused ) { + return getchar(); +} + +static bool ansiscr_peek ( struct _curses_screen *scr __unused ) { + return iskey(); +} + +static void ansiscr_cursor ( struct _curses_screen *scr __unused, + int visibility ) { + printf ( "\033[?25%c", ( visibility ? 'h' : 'l' ) ); +} + +SCREEN _ansi_screen = { + .init = ansiscr_init, + .exit = ansiscr_exit, + .erase = ansiscr_erase, + .movetoyx = ansiscr_movetoyx, + .putc = ansiscr_putc, + .getc = ansiscr_getc, + .peek = ansiscr_peek, + .cursor = ansiscr_cursor, +}; |