diff options
| author | WormHeamer | 2025-11-05 04:35:47 -0500 |
|---|---|---|
| committer | WormHeamer | 2025-11-05 04:35:47 -0500 |
| commit | 4fe994585ac5afbcc42a28326dcd660617b56fc3 (patch) | |
| tree | 5eafed93eb2c86cfcd63eff0ef8176e3dfadbbde /main.c | |
| parent | 4bc52d28a2b6602109885b59fe6d31dd75f4956f (diff) | |
more keyboarding stuff
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 218 |
1 files changed, 174 insertions, 44 deletions
@@ -34,15 +34,22 @@ typedef enum { KEY_ESC = 0x1b, KEY_DEL = 0x7f, KEY_UTF8_MAX = 0x10ffff, - KEY_LEFT, - KEY_RIGHT, - KEY_UP, - KEY_DOWN, - KEY_HOME, - KEY_END, - KEY_PGUP, - KEY_PGDN, - KEY_INVALID = 0x7fffffff + + KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, + KEY_HOME, KEY_END, KEY_PGUP, KEY_PGDN, + + KEY_F1, KEY_F2, KEY_F3, KEY_F4, + KEY_F5, KEY_F6, KEY_F7, KEY_F8, + KEY_F9, KEY_F10, KEY_F11, KEY_F12, + + KEY_SHIFT_BIT = 0x200000, + KEY_CTRL_BIT = 0x400000, + KEY_ALT_BIT = 0x800000, + KEY_META_BIT = 0x1000000, + KEY_INVALID = 0x7fffffff, + + KEY_CTRL_MASK = 0xe000000, + KEY_BASE_MASK = ~KEY_CTRL_MASK, } VuiKey; typedef enum { @@ -223,7 +230,15 @@ void vui_on_sigwinch(int _) { void vui_init(void) { tcgetattr(STDIN_FILENO, &vui_init_stdin_tos); vui_raw_stdin_tos = vui_init_stdin_tos; - vui_raw_stdin_tos.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN); + //vui_raw_stdin_tos.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); + //vui_raw_stdin_tos.c_lflag |= IGNBRK; + + vui_raw_stdin_tos.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + vui_raw_stdin_tos.c_oflag &= ~OPOST; + vui_raw_stdin_tos.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + vui_raw_stdin_tos.c_cflag &= ~(CSIZE | PARENB); + vui_raw_stdin_tos.c_cflag |= CS8; + tcsetattr(STDIN_FILENO, TCSANOW, &vui_raw_stdin_tos); tcgetattr(STDOUT_FILENO, &vui_init_stdout_tos); @@ -301,6 +316,10 @@ void vui_outf(const char *fmt, ...) { * { 6,6,6,6,6,6,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,1,1,1,1,1,1,1,1, } * len(cp) = tbl[32 - clz(cp)]. * + * how could we possibly reduce this? + * 6 sixes, 5 fives, 5 fours, 5 threes, four twos, and eight ones. + * no obvious pattern. + * * to avoid the subtraction we reverse: * { 1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6, } * @@ -313,9 +332,8 @@ void vui_outf(const char *fmt, ...) { * concatenate bits: * 0b0000000000000001010101101010101011111111111111111111111111111111 * - * convert to hex: - * lut = 0x156AAFFFFFFFF - * len(cp) = 1 + (lut >> (2 * clz(cp))) & 3 + * convert to hex, and now: + * len(cp) = 1 + (0x156AAFFFFFFFF >> (2 * clz(cp))) & 3 */ #define UTF8_CP_LEN_BITS ((uint64_t)0x156AAFFFFFFFF) @@ -330,8 +348,8 @@ static inline void vui_outc(char c) { /* don't pass a NUL to this */ /* it doesn't make sense to do so, and assuming non-zero lets us dodge a branch * in stdc_leading_zeros() */ -void vui_outvc(VuiChar c) { - ASSUME(c > 0 && c <= 0x10ffff); +static inline void vui_outvc(VuiChar c) { + ASSUME(c > 0 && c <= 0x110000); uint8_t len = UTF8_CP_LEN(c); vui_out_fit(vui_outn + len); ASSUME(len > 0 && len < 5); @@ -367,7 +385,7 @@ static inline void vui_outs(const char *s) { static inline void vui_out_flush(void) { fwrite(vui_out, 1, vui_outn, stdout); fflush(stdout); -#if 1 +#if 0 static unsigned out_frame = 0; FILE *f = fopen("out_log.txt", "a"); assert(f); @@ -640,6 +658,23 @@ void vui_chr(int x, int y, VuiChar c) { vui_chra(x, y, c, ATTR_DEFAULT); } +static inline u32 utf8_next(u32 *p, const char *s, u32 n) { + u32 i = *p; + u8 c = s[i++]; + usize bits = stdc_leading_ones(c); + if (!bits) { + *p = i; + return c; + } + u32 cp = c & ((1 << (7-bits)) - 1); + while (--bits) { + c = s[i++]; + cp = (cp << 6) | (c & 0x3F); + } + *p = i; + return cp; +} + int vui_avprintf(int x, int y, VuiAttr a, const char *fmt, va_list ap) { va_list ap2; va_copy(ap2, ap); @@ -650,9 +685,11 @@ int vui_avprintf(int x, int y, VuiAttr a, const char *fmt, va_list ap) { if (n > 0) { char buf[n + 1]; vsnprintf(buf, n + 1, fmt, ap2); - memcpy(&CHR(x,y), buf, n < COLS - x ? n : COLS - x); - for (unsigned x1 = x; x1 < COLS && x1 < x + n; x1++) { - ATTR(x1, y) = a; + for (unsigned i = 0; i < n && x < COLS;) { + u32 c = utf8_next(&i, buf, n); + CHR(x, y) = c; + ATTR(x, y) = a; + x++; } } return n; @@ -748,15 +785,52 @@ static unsigned getk_utf8(uint8_t start) { return ch; } -VuiKey vui_key(void) { - int c = getk(); - if (c & 0x80) return getk_utf8(c); - if (c == '\n') return KEY_RET; - if (c != KEY_ESC) return c; - if (!has_input()) return KEY_ESC; - c = getk(); - if (c != '[') goto bad_esc_seq; - switch (getk()) { +VuiKey vui_bad_key(void) { + /* yell */ + putchar('\a'); + fflush(stdout); + return KEY_INVALID; +} + +VuiKey vui_esc_key(u32 c); + +VuiKey vui_meta_key(u32 c) { + switch (c) { + case '2': return vui_esc_key(getk()) | KEY_SHIFT_BIT; break; + case '3': return vui_esc_key(getk()) | KEY_ALT_BIT; break; + case '4': return vui_esc_key(getk()) | KEY_ALT_BIT | KEY_SHIFT_BIT; break; + case '5': return vui_esc_key(getk()) | KEY_CTRL_BIT; break; + case '6': return vui_esc_key(getk()) | KEY_CTRL_BIT | KEY_SHIFT_BIT; break; + case '7': return vui_esc_key(getk()) | KEY_CTRL_BIT | KEY_ALT_BIT; break; + case '8': return vui_esc_key(getk()) | KEY_CTRL_BIT | KEY_SHIFT_BIT | KEY_ALT_BIT; break; + case '9': return vui_esc_key(getk()) | KEY_META_BIT; break; + case '1': + switch (getk()) { + case '0': return vui_esc_key(getk()) | KEY_META_BIT | KEY_SHIFT_BIT; break; + case '1': return vui_esc_key(getk()) | KEY_META_BIT | KEY_ALT_BIT; break; + case '3': return vui_esc_key(getk()) | KEY_META_BIT | KEY_CTRL_BIT; break; + case '4': return vui_esc_key(getk()) | KEY_META_BIT | KEY_SHIFT_BIT | KEY_CTRL_BIT; break; + case '5': return vui_esc_key(getk()) | KEY_META_BIT | KEY_ALT_BIT | KEY_CTRL_BIT; break; + case '6': return vui_esc_key(getk()) | KEY_META_BIT | KEY_SHIFT_BIT | KEY_ALT_BIT | KEY_CTRL_BIT; break; + default: return vui_bad_key(); + } + default: return vui_bad_key(); + } +} + +VuiKey vui_esc_key(u32 c) { + switch (c) { + case 'P': return KEY_F1; break; + case 'Q': return KEY_F2; break; + case 'R': return KEY_F3; break; + case 'S': return KEY_F4; break; + case '1': + switch (getk()) { + case ';': return vui_meta_key(getk()); + case '5': + default: return vui_bad_key(); + } + break; case 'A': return KEY_UP; case 'B': return KEY_DOWN; case 'C': return KEY_RIGHT; @@ -764,16 +838,34 @@ VuiKey vui_key(void) { case 'H': return KEY_HOME; case 'F': return KEY_END; case '5': - if (getk() != '~') goto bad_esc_seq; + if (getk() != '~') return vui_bad_key(); return KEY_PGUP; case '6': - if (getk() != '~') goto bad_esc_seq; + if (getk() != '~') return vui_bad_key(); return KEY_PGDN; - default: goto bad_esc_seq; + default: return vui_bad_key(); + } +} + +VuiKey vui_key(void) { + int c = getk(); + if (c & 0x80) return getk_utf8(c); + if (c == '\n') return KEY_RET; + if (c != KEY_ESC) return c; + if (!has_input()) return KEY_ESC; + c = getk(); + switch (c) { + case 'O': + switch (getk()) { + case 'P': return KEY_F1; break; + case 'Q': return KEY_F2; break; + case 'R': return KEY_F3; break; + case 'S': return KEY_F4; break; + default: return vui_bad_key(); break; + } + case '[': return vui_esc_key(getk()); + default: return vui_bad_key(); } -bad_esc_seq: - putchar('\a'); - return KEY_INVALID; } int x = 0, y = 0; @@ -786,9 +878,11 @@ int half_y = 0; void draw(void *ctx) { (void)ctx; + /* FILE *f = fopen("tmp.txt", "a"); fprintf(f, "%u\n", vui_out_chars); fclose(f); + */ vui_blit(); } @@ -822,16 +916,47 @@ int main(int argc, const char **argv) { vui_curs_vis(1); vui_win.redraw_fn = draw; - int x = 0, y = 0; + int x = 10, y = 0; + int scroll_x = 0, scroll_y = 0; for (;;) { - if (x < 10) { vui_scroll(10 - x, 0); x = 10; } - if (y < 5) { vui_scroll(0, 5 - y); y = 5; } - if (x > COLS-10) { vui_scroll((COLS-10) - x, 0); x = COLS-10; } - if (y > LINES-5) { vui_scroll(0, (LINES-5) - y); y = LINES-5; } + static int last_left = 0; + int left = (COLS - (72 < COLS ? 72 : COLS - 2)) >> 1; + int right = COLS - left; + int top = 5; + int bottom = LINES - 5; + + if (y < top) { scroll_y = top - y; } + if (y > bottom) { scroll_y = bottom - y; } + + scroll_x += left - last_left; + last_left = left; + + int sdx = scroll_x > 0 ? 1 : (scroll_x < 0 ? -1 : 0); + int sdy = scroll_y > 0 ? 1 : (scroll_y < 0 ? -1 : 0); + vui_scroll(sdx, sdy); + x += sdx; + y += sdy; + scroll_x -= sdx; + scroll_y -= sdy; vui_curs_pos(x, y); draw(NULL); + + int animating = !!scroll_x || !!scroll_y; + if (animating && !wait_for_input(STDIN_FILENO, 33)) continue; VuiKey c = vui_key(); + if (c == KEY_INVALID || c == KEY_ESC) goto done; + static unsigned i = 0; + int x1 = x; + i++; + if (c > 0x1f && c < KEY_UTF8_MAX && x < right) { + vui_chra(x++, y, c, FG_BLACK | BG_WHITE); + } else if (c == KEY_RET) { + x = left; + y++; + } + + /* switch (c) { case KEY_ESC: goto done; case KEY_LEFT: x--; break; @@ -839,10 +964,14 @@ int main(int argc, const char **argv) { case KEY_UP: y--; break; case KEY_DOWN: y++; break; case KEY_HOME: x = 10; break; - case KEY_RET: - x = 10; - y++; - break; + case KEY_END: + x = COLS - 1; + while (x > 9 && CHR(x, y) == ' ') x--; + x++; + break; + case KEY_PGDN: y += 8; break; + case KEY_PGUP: y -= 8; break; + case KEY_RET: x = 10; y++; break; case KEY_DEL: case KEY_BACKSPACE: if (x > 0) x--; @@ -852,7 +981,7 @@ int main(int argc, const char **argv) { puts("invalid key!"); return 1; default: - if (c < 0x20) continue; + if (c < 0x20 || c > KEY_UTF8_MAX) continue; { static unsigned a_ = 0; VuiAttr a = (a_++ >> 3) & ((1<<13)-1); @@ -862,6 +991,7 @@ int main(int argc, const char **argv) { vui_chr(x++, y, c); } } + */ } done: |
