memzap

replay memory writes
git clone git://git.2f30.org/memzap
Log | Files | Refs | README | LICENSE

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 }