From 385c9d62a5507d901ff7e54d7a4c0342cf3aff43 Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Sun, 15 Jan 2023 23:07:37 +0100 Subject: Lots of fixes for rendering, utf-8 and kbd. --- src/keyboard.c | 61 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 22 deletions(-) (limited to 'src/keyboard.c') diff --git a/src/keyboard.c b/src/keyboard.c index e2cdc34..03d0bd4 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -23,42 +23,56 @@ struct keyboard keyboard_create(struct reactor *reactor) { .reactor_event_id = reactor_register_interest(reactor, STDIN_FILENO, ReadInterest), .has_data = false, - .last_key = {0}, }; } void parse_keys(uint8_t *bytes, uint32_t nbytes, struct key *out_keys, - uint32_t *out_nkeys, struct key *previous_key) { + uint32_t *out_nkeys) { uint32_t nkps = 0; - struct key *prevkp = previous_key; for (uint32_t bytei = 0; bytei < nbytes; ++bytei) { uint8_t b = bytes[bytei]; - struct key *kp = &out_keys[nkps]; - kp->start = bytei; - - bool inserted = true; if (b == 0x1b) { // meta - kp->mod |= Meta; + struct key *kp = &out_keys[nkps]; + kp->start = bytei; + kp->mod = Meta; + } else if (b == '[' || + b == '0') { // special char (function keys, pgdn, etc) + struct key *kp = &out_keys[nkps]; + if (kp->mod & Meta) { + kp->mod = Spec; + } } else if (b >= 0x00 && b <= 0x1f) { // ctrl char + struct key *kp = &out_keys[nkps]; kp->mod |= Ctrl; kp->key = b | 0x40; - } else if (b == 0x7f) { // ^? + kp->start = bytei; + kp->end = bytei + 1; + ++nkps; + } else if (b == 0x7f) { // ? + struct key *kp = &out_keys[nkps]; kp->mod |= Ctrl; kp->key = '?'; - } else if (prevkp->mod & Meta) { - prevkp->key = b; - prevkp->end = bytei + 1; - inserted = false; - } else { - inserted = false; - } - - kp->end = bytei + 1; - - if (inserted) { + kp->start = bytei; + kp->end = bytei + 1; ++nkps; - prevkp = kp; + } else { + struct key *kp = &out_keys[nkps]; + if (kp->mod & Spec && b == '~') { + // skip tilde in special chars + kp->end = bytei + 1; + ++nkps; + } else if (kp->mod & Meta || kp->mod & Spec) { + kp->key = b; + kp->end = bytei + 1; + + bool has_more = bytei + 1 < nbytes; + + if (kp->mod & Meta || + (kp->mod & Spec && !(has_more && bytes[bytei + 1] == '~'))) { + ++nkps; + } + } } } @@ -87,7 +101,7 @@ struct keyboard_update keyboard_update(struct keyboard *kbd, if (nbytes > 0) { upd.nbytes = nbytes; - parse_keys(upd.raw, upd.nbytes, upd.keys, &upd.nkeys, &kbd->last_key); + parse_keys(upd.raw, upd.nbytes, upd.keys, &upd.nkeys); if (nbytes < 32) { kbd->has_data = false; @@ -116,6 +130,9 @@ void key_name(struct key *key, char *buf, size_t capacity) { case Meta: mod = "m-"; break; + case Spec: + mod = "special-"; + break; } snprintf(buf, capacity, "%s%c", mod, tolower(key->key)); -- cgit v1.2.3