diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2020-08-12 12:37:54 -0400 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2020-08-12 12:37:54 -0400 |
commit | a9860417f53216a2f3b0b490afec46ab5db70181 (patch) | |
tree | 6dd9d598a78ff644a9b645ded415ec3f84bba53f /io.c | |
parent | d49e39c672e78d536d658785adffb9149715832b (diff) |
- Refactored the escape sequence parsing, and handling.
It now uses a struct to store the escape sequence.
Before it handles the escape sequence, it parses it,
which includes things like getting any arguments
that are supplied, and getting the mode type.
- Moved the code that handles control codes to a
separate function.
The reason for doing this was because I wanted to make
the escape sequence handling faster, but also make the
code more readable at the same time.
I got the idea to do this from st, a terminal emulator
created by the suckless.org project.
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 328 |
1 files changed, 186 insertions, 142 deletions
@@ -1,11 +1,25 @@ #include "sux.h" +#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) +#define DEFAULT(a, b) (a) = (a) ? (a) : (b) + char *key = NULL; uint8_t key_idx = 0; -uint8_t iscol; -uint8_t idx = 3; -uint8_t bcd[4]; +uint8_t esc = 0; +uint8_t iscsi = 0; + +typedef struct escape escape; + +struct escape { + char buf[128]; /* Buffer. */ + size_t len; /* Buffer length. */ + int arg[16]; /* Arguments. */ + int narg; /* Number of arguments. */ + char mode[2]; /* Mode type. */ +}; + +escape escseq; static inline char *get_keyseq(int keycode) { switch (keycode) { @@ -115,9 +129,165 @@ int get_key(WINDOW *scr) { return c; } +void parse_esc() { + char *str = escseq.buf, *nstr; + long int value; + escseq.narg = 0; -void io(uint64_t address, uint8_t rw) { + escseq.buf[escseq.len] = '\0'; + for (;str < escseq.buf + escseq.len; str++) { + nstr = NULL; + value = strtol(str, &nstr, 10); + if (nstr == str) { + value = 0; + } + if (value == LONG_MAX || value == LONG_MIN) { + value = -1; + } + escseq.arg[escseq.narg++] = value; + str = nstr; + if (*str != ';' || escseq.narg == 16) { + break; + } + } + escseq.mode[0] = *str++; + escseq.mode[1] = (str < (escseq.buf + escseq.len)) ? *str : '\0'; +} + +void handle_esc() { int x, y; + getyx(scr, y, x); + switch (escseq.mode[0]) { + case 'A': + DEFAULT(escseq.arg[0], 1); + if (y-escseq.arg[0] >= 0) { + y -= escseq.arg[0]; + #if !debug + wmove(scr, y, x); + #endif + } + break; + case 'B': + case 'e': + DEFAULT(escseq.arg[0], 1); + if (y+escseq.arg[0] <= getmaxy(scr)) { + y += escseq.arg[0]; + #if !debug + wmove(scr, y, x); + #endif + } + break; + case 'C': + case 'a': + DEFAULT(escseq.arg[0], 1); + if (x+escseq.arg[0] <= getmaxx(scr)) { + x += escseq.arg[0]; + #if !debug + wmove(scr, y, x); + #endif + } + break; + case 'D': + DEFAULT(escseq.arg[0], 1); + if (x-escseq.arg[0] >= 0) { + x -= escseq.arg[0]; + #if !debug + wmove(scr, y, x); + #endif + } + break; + case 'H': + case 'f': + DEFAULT(escseq.arg[0], 1); + DEFAULT(escseq.arg[1], 1); + #if !debug + wmove(scr, escseq.arg[0]-1, escseq.arg[1]-1); + #else + wmove(scr, 31, 0); + wclrtoeol(scr); + wprintw(scr, "escseq.arg[0]: %i, escseq.arg[1]: %i", escseq.arg[0], escseq.arg[1]); + #endif + break; + case 'S': + DEFAULT(escseq.arg[0], 1); + #if !debug + wscrl(scr, -escseq.arg[0]); + #else + #endif + break; + case 'T': + DEFAULT(escseq.arg[0], 1); + #if !debug + wscrl(scr, escseq.arg[0]); + #else + #endif + break; + } +} + +void reset_esc() { + memset(&escseq, 0, sizeof(escseq)); +} + +void handle_ctrlcode(int c) { + int x, y; + getyx(scr, y, x); + switch (c) { + case 0xC: + x=0,y=0; + #if !debug + wclear(scr); + wmove(scr, y, x); + #endif + break; + case CURSES_BACKSPACE: + case '\b': + if (x > 0) { + x--; + #if !debug + wmove(scr, y, x); + #endif + } + #if !debug + wdelch(scr); + #else + if (!subdbg) { + scr_col++; + wmove(scr, 28, scr_col--); + wdelch(scr); + wmove(scr, 28, scr_col); + wdelch(scr); + } + #endif + break; + case '\033': reset_esc(); esc = 1; break; + case '\n': + x = 0; + y+=1; + #if !debug + wmove(scr, y, x); + #endif + break; + default: + #if !debug + /*wmove(scr, y, x);*/ + waddch(scr, c); + #else + if (!subdbg && scr_col < 160) { + if (c != ' ') { + wprintw(scr, "%02X", c); + } else { + wprintw(scr, " "); + } + } + #endif + x+=1; + break; + } +} + + +void io(uint64_t address, uint8_t rw) { uint16_t scr_col = 0; /*step |= (!rw) ? (cpu->pc[thread] == CTRL_ADDR) : step;*/ switch (address) { @@ -135,7 +305,6 @@ void io(uint64_t address, uint8_t rw) { if (rw) { break; } - getyx(scr, y, x); #if debug if (!subdbg) { scr_col = (addr[TX_ADDR] != 0x0C && addr[TX_ADDR] != '\n' && scr_col < 160) ? (addr[1] << 1)-2 : 0; @@ -148,146 +317,21 @@ void io(uint64_t address, uint8_t rw) { wclrtoeol(scr); } #endif - switch (addr[TX_ADDR]) { - case 'A': - if (y > 0) - y--; - #if !debug - wmove(scr, y, x); - #endif - esc = 0; - break; - case 'B': - if (y < getmaxy(scr)) - y++; - #if !debug - wmove(scr, y, x); - #endif + int c = addr[TX_ADDR]; + if (iscsi) { + escseq.buf[escseq.len++] = c; + if (BETWEEN(c, 0x40, 0x7E) || escseq.len >= sizeof(escseq.buf)-1) { esc = 0; - break; - case 'C': - if (x < getmaxx(scr)) - x++; - #if !debug - wmove(scr, y, x); - #endif - esc = 0; - break; - case 'D': - if (x > 0) - x--; - #if !debug - wmove(scr, y, x); - #endif - esc = 0; - break; - case 'H': - if (!bcd[2] && !bcd[3]) { - y = 0; - } else { - y = ((bcd[3]*10) + bcd[2]); - } - if (!bcd[0] && !bcd[1]) { - x = 0; - } else { - x = ((bcd[1]*10) + bcd[0]); - } - #if !debug - wmove(scr, y, x); - #else - /*mvwprintw(scr, 31, 0, "x: %i, y: %i ", x, y);*/ - mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]); - #endif - idx = 3; - bcd[0] = 0; - bcd[1] = 0; - bcd[2] = 0; - bcd[3] = 0; - esc = 0; - break; - case 'S': - #if !debug - wscrl(scr, -1); - #else - #endif - esc = 0; - break; - case 'T': - #if !debug - wscrl(scr, 1); - #else - #endif - esc = 0; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - bcd[idx--] = (addr[address] - '0'); - break; - default: - iscol = (addr[address] == ';'); - break; + iscsi = 0; + parse_esc(); + handle_esc(); + } } - } else { - switch (addr[TX_ADDR]) { - case 0xC: - x=0,y=0; - #if !debug - wclear(scr); - wmove(scr, y, x); - #endif - break; - case CURSES_BACKSPACE: - case '\b': - if (x > 0) { - x--; - #if !debug - wmove(scr, y, x); - #endif - } - #if !debug - wdelch(scr); - #else - if (!subdbg) { - scr_col++; - wmove(scr, 28, scr_col--); - wdelch(scr); - wmove(scr, 28, scr_col); - wdelch(scr); - } - #endif - break; - case '\033': esc = 1; break; - case '\n': - x = 0; - y+=1; - #if !debug - wmove(scr, y, x); - #endif - break; - default: - #if !debug - /*wmove(scr, y, x);*/ - waddch(scr, addr[address]); - #else - if (!subdbg && scr_col < 160) { - if (addr[address] != ' ') { - wprintw(scr, "%02X", addr[address]); - } else { - wprintw(scr, " "); - } - } - #endif - x+=1; - break; + if (c == '[') { + iscsi = 1; } + } else { + handle_ctrlcode(addr[TX_ADDR]); } break; } |