diff options
| author | Albert Cervin <albert@acervin.com> | 2022-12-18 21:20:19 +0100 |
|---|---|---|
| committer | Albert Cervin <albert@acervin.com> | 2022-12-18 21:20:19 +0100 |
| commit | a817e01bfe2356fdd860010d46db4e4361f343a6 (patch) | |
| tree | f6e34056d236b1df6e6a62573d4f9adf602b0dc7 /src/keyboard.c | |
| parent | 3deb7c91056779d1f1b2be112e727bc9999ac21d (diff) | |
| download | dged-a817e01bfe2356fdd860010d46db4e4361f343a6.tar.gz dged-a817e01bfe2356fdd860010d46db4e4361f343a6.tar.xz dged-a817e01bfe2356fdd860010d46db4e4361f343a6.zip | |
Fixup utf-8 and meta handling in input
Diffstat (limited to 'src/keyboard.c')
| -rw-r--r-- | src/keyboard.c | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index aaeccd2..b4c0c6d 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,6 +1,7 @@ #include "keyboard.h" #include "reactor.h" #include "stdio.h" +#include "utf8.h" #include <ctype.h> #include <errno.h> @@ -13,31 +14,48 @@ 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) { + uint32_t *out_nkeys, struct key *previous_key) { 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->nbytes = 1; if (b == 0x1b) { // meta kp->mod |= Meta; } else if (b >= 0x00 && b <= 0x1f) { // ctrl char kp->mod |= Ctrl; - kp->c = b | 0x40; - + kp->bytes[0] = b | 0x40; + ++nkps; + prevkp = kp; } else if (b == 0x7f) { // ^? kp->mod |= Ctrl; - kp->c = '?'; - } else { // normal char (or part of char) - kp->c = b; + kp->bytes[0] = '?'; + ++nkps; + prevkp = kp; + } else if (utf8_byte_is_unicode_start((uint8_t)b)) { + kp->bytes[0] = b; + ++nkps; + prevkp = kp; + } else if (utf8_byte_is_unicode_continuation((uint8_t)b)) { + prevkp->bytes[prevkp->nbytes] = b; + ++prevkp->nbytes; + } else { /* ascii char */ + if (prevkp->mod & Meta) { + prevkp->bytes[0] = b; + } else { + kp->bytes[0] = b; + } + ++nkps; + prevkp = kp; } - - ++nkps; } *out_nkeys = nkps; @@ -61,7 +79,7 @@ struct keyboard_update keyboard_update(struct keyboard *kbd, int nbytes = read(STDIN_FILENO, bytes, 32); if (nbytes > 0) { - parse_keys(bytes, nbytes, upd.keys, &upd.nkeys); + parse_keys(bytes, nbytes, upd.keys, &upd.nkeys, &kbd->last_key); } else if (nbytes == EAGAIN) { kbd->has_data = false; } @@ -69,8 +87,13 @@ struct keyboard_update keyboard_update(struct keyboard *kbd, return upd; } -bool key_equal(struct key *key, uint8_t mod, uint8_t c) { - return key->c == c && key->mod == mod; +bool key_equal_char(struct key *key, uint8_t mod, uint8_t c) { + return key->bytes[0] == c && key->mod == mod; +} + +bool key_equal(struct key *key1, struct key *key2) { + return memcmp(key1->bytes, key2->bytes, key1->nbytes) == 0 && + key1->mod == key2->mod && key1->nbytes == key2->nbytes; } void key_name(struct key *key, char *buf, size_t capacity) { @@ -84,5 +107,10 @@ void key_name(struct key *key, char *buf, size_t capacity) { break; } - snprintf(buf, capacity, "%s%c", mod, tolower((char)key->c)); + uint8_t lower[6]; + for (uint32_t bytei = 0; bytei < key->nbytes; ++bytei) { + lower[bytei] = tolower(key->bytes[bytei]); + } + + snprintf(buf, capacity, "%s%.*s", mod, key->nbytes, lower); } |
