summaryrefslogtreecommitdiff
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2023-01-15 23:07:37 +0100
committerAlbert Cervin <albert@acervin.com>2023-01-15 23:07:37 +0100
commit385c9d62a5507d901ff7e54d7a4c0342cf3aff43 (patch)
tree53e53ee0075e34ef59aeeeb554a69580af1e2d1c /src/keyboard.c
parentd806403fe93daa2fb84e2c72aa7660575c33000e (diff)
downloaddged-385c9d62a5507d901ff7e54d7a4c0342cf3aff43.tar.gz
dged-385c9d62a5507d901ff7e54d7a4c0342cf3aff43.tar.xz
dged-385c9d62a5507d901ff7e54d7a4c0342cf3aff43.zip
Lots of fixes for rendering, utf-8 and kbd.
Diffstat (limited to 'src/keyboard.c')
-rw-r--r--src/keyboard.c61
1 files changed, 39 insertions, 22 deletions
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));