input.c (2531B)
1 #include <assert.h> 2 #include <stdio.h> 3 #include <string.h> 4 5 #include "term.h" 6 7 #define BUFFER_SIZE_MAX 16 8 9 /* if s1 starts with s2 returns 1, else 0 */ 10 static int starts_with(const char *s1, const char *s2) 11 { 12 /* nice huh? */ 13 while (*s2) if (*s1++ != *s2++) return 0; return 1; 14 } 15 16 /* convert escape sequence to event, and return consumed bytes on success (failure == 0) */ 17 static int parse_escape_seq(struct tb_event *event, const char *buf) 18 { 19 /* it's pretty simple here, find 'starts_with' match and return success, else return failure */ 20 int i; 21 for (i = 0; keys[i]; i++) { 22 if (starts_with(buf, keys[i])) { 23 event->ch = 0; 24 event->key = 0xFFFF-i; 25 return strlen(keys[i]); 26 } 27 } 28 return 0; 29 } 30 31 bool extract_event(struct tb_event *event, struct ringbuffer *inbuf, int inputmode) 32 { 33 char buf[BUFFER_SIZE_MAX+1]; 34 int nbytes = ringbuffer_data_size(inbuf); 35 36 if (nbytes > BUFFER_SIZE_MAX) 37 nbytes = BUFFER_SIZE_MAX; 38 39 if (nbytes == 0) 40 return false; 41 42 ringbuffer_read(inbuf, buf, nbytes); 43 buf[nbytes] = '\0'; 44 45 if (buf[0] == '\033') { 46 int n = parse_escape_seq(event, buf); 47 if (n) { 48 ringbuffer_pop(inbuf, 0, n); 49 return true; 50 } else { 51 /* it's not escape sequence, then it's ALT or ESC, check inputmode */ 52 switch (inputmode) { 53 case TB_INPUT_ESC: 54 /* if we're in escape mode, fill ESC event, pop buffer, return success */ 55 event->ch = 0; 56 event->key = TB_KEY_ESC; 57 event->mod = 0; 58 ringbuffer_pop(inbuf, 0, 1); 59 return true; 60 case TB_INPUT_ALT: 61 /* if we're in alt mode, set ALT modifier to event and redo parsing */ 62 event->mod = TB_MOD_ALT; 63 ringbuffer_pop(inbuf, 0, 1); 64 return extract_event(event, inbuf, inputmode); 65 default: 66 assert(!"never got here"); 67 break; 68 } 69 } 70 } 71 72 /* if we're here, this is not an escape sequence and not an alt sequence 73 * so, it's a FUNCTIONAL KEY or a UNICODE character 74 */ 75 76 /* first of all check if it's a functional key */ 77 if ((unsigned char)buf[0] <= TB_KEY_SPACE || 78 (unsigned char)buf[0] == TB_KEY_BACKSPACE2) 79 { 80 /* fill event, pop buffer, return success */ 81 event->ch = 0; 82 event->key = (uint16_t)buf[0]; 83 ringbuffer_pop(inbuf, 0, 1); 84 return true; 85 } 86 87 /* feh... we got utf8 here */ 88 89 /* check if there is all bytes */ 90 if (nbytes >= utf8_char_length(buf[0])) { 91 /* everything ok, fill event, pop buffer, return success */ 92 utf8_char_to_unicode(&event->ch, buf); 93 event->key = 0; 94 ringbuffer_pop(inbuf, 0, utf8_char_length(buf[0])); 95 return true; 96 } 97 98 /* fuck!!!!1111odin1odinodin */ 99 return false; 100 }