diff options
| author | Albert Cervin <albert@acervin.com> | 2022-11-02 22:20:04 +0100 |
|---|---|---|
| committer | Albert Cervin <albert@acervin.com> | 2022-11-16 23:33:49 +0100 |
| commit | 2f4cb88d5c60f725323739300bb49dfa8923e7d5 (patch) | |
| tree | 6ec22c2be92eff05f18e5919e747faab56e555ad /src/display.c | |
| download | dged-2f4cb88d5c60f725323739300bb49dfa8923e7d5.tar.gz dged-2f4cb88d5c60f725323739300bb49dfa8923e7d5.tar.xz dged-2f4cb88d5c60f725323739300bb49dfa8923e7d5.zip | |
🎉 And so it begins
Diffstat (limited to 'src/display.c')
| -rw-r--r-- | src/display.c | 100 |
1 files changed, 100 insertions, 0 deletions
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 <stdio.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#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); +} |
