summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-08-12 12:37:54 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-08-12 12:37:54 -0400
commita9860417f53216a2f3b0b490afec46ab5db70181 (patch)
tree6dd9d598a78ff644a9b645ded415ec3f84bba53f /io.c
parentd49e39c672e78d536d658785adffb9149715832b (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.c328
1 files changed, 186 insertions, 142 deletions
diff --git a/io.c b/io.c
index ef491f5..37116df 100644
--- a/io.c
+++ b/io.c
@@ -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;
}