From 2f4cb88d5c60f725323739300bb49dfa8923e7d5 Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Wed, 2 Nov 2022 22:20:04 +0100 Subject: =?UTF-8?q?=F0=9F=8E=89=20And=20so=20it=20begins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/display.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/display.c (limited to 'src/display.c') diff --git a/src/display.c b/src/display.c new file mode 100644 index 0000000..b34cbf1 --- /dev/null +++ b/src/display.c @@ -0,0 +1,100 @@ +#define _DEFAULT_SOURCE +#include "display.h" + +#include "buffer.h" + +#include +#include +#include + +#define ESC 0x1b + +struct display display_create() { + + struct winsize ws; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) { + // TODO: if it fails to fetch, do something? + return (struct display){ + .height = 0, + .width = 0, + }; + } + + // save old settings + struct termios orig_term; + tcgetattr(0, &orig_term); + + // set terminal to raw mode + struct termios term; + cfmakeraw(&term); + // non-blocking input + // TODO: move to kbd? + term.c_cc[VMIN] = 0; + term.c_cc[VTIME] = 0; + + tcsetattr(0, TCSADRAIN, &term); + + return (struct display){ + .orig_term = orig_term, + .term = term, + .height = ws.ws_row, + .width = ws.ws_col, + }; +} + +void display_destroy(struct display *display) { + // reset old terminal mode + tcsetattr(0, TCSADRAIN, &display->orig_term); +} + +void putbytes(uint8_t *line_bytes, uint32_t line_length) { + fwrite(line_bytes, 1, line_length, stdout); +} + +void putbyte(uint8_t c) { putc(c, stdout); } + +void put_ansiparm(int n) { + int q = n / 10; + if (q != 0) { + int r = q / 10; + if (r != 0) { + putbyte((r % 10) + '0'); + } + putbyte((q % 10) + '0'); + } + putbyte((n % 10) + '0'); +} + +void display_move_cursor(struct display *display, uint32_t row, uint32_t col) { + putbyte(ESC); + putbyte('['); + put_ansiparm(row + 1); + putbyte(';'); + put_ansiparm(col + 1); + putbyte('H'); +} + +void display_clear(struct display *display) { + display_move_cursor(display, 0, 0); + uint8_t bytes[] = {ESC, '[', 'J'}; + putbytes(bytes, 3); +} + +void delete_to_eol() { + uint8_t bytes[] = {ESC, '[', 'K'}; + putbytes(bytes, 3); +} + +void display_update(struct display *display, struct render_cmd *cmds, + uint32_t ncmds, uint32_t currow, uint32_t curcol) { + for (uint64_t cmdi = 0; cmdi < ncmds; ++cmdi) { + struct render_cmd *cmd = &cmds[cmdi]; + display_move_cursor(display, cmd->row, cmd->col); + putbytes(cmd->data, cmd->len); + delete_to_eol(); + } + + display_move_cursor(display, currow, curcol); + + fflush(stdout); +} -- cgit v1.2.3