summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorWormHeamer2025-11-05 04:35:47 -0500
committerWormHeamer2025-11-05 04:35:47 -0500
commit4fe994585ac5afbcc42a28326dcd660617b56fc3 (patch)
tree5eafed93eb2c86cfcd63eff0ef8176e3dfadbbde /main.c
parent4bc52d28a2b6602109885b59fe6d31dd75f4956f (diff)
more keyboarding stuff
Diffstat (limited to 'main.c')
-rw-r--r--main.c218
1 files changed, 174 insertions, 44 deletions
diff --git a/main.c b/main.c
index f14684e..f380d97 100644
--- a/main.c
+++ b/main.c
@@ -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: