commit ca75f09d87624b5a01a667491ad81e386df7b189
parent 588bbeba8516f84e1b04c0eb04b5a319e0ea6871
Author: Brian Swetland <swetland@frotz.net>
Date: Wed, 1 Mar 2023 04:21:13 -0800
termbox: make bytebuffers unsigned, add TB_INPUT_SPACE flag
Traditionally, termbox treats the space key as a special/function key
like ESC, F4, or BACKSPACE. The new TB_INPUT_SPACE flag for
tb_select_input_mode() changes that so it becomes a regular character,
which makes more sense to me.
At the same time, bytebuffer, utf8, and input processing were adjusted to
treat all characters as uint8_t instead of using char and often casting
to unsigned char.
Diffstat:
4 files changed, 41 insertions(+), 29 deletions(-)
diff --git a/termbox/bytebuffer.inl.c b/termbox/bytebuffer.inl.c
@@ -1,5 +1,5 @@
struct bytebuffer {
- char *buf;
+ uint8_t *buf;
int len;
int cap;
};
@@ -14,7 +14,7 @@ static void bytebuffer_reserve(struct bytebuffer *b, int cap) {
cap = b->cap * 2;
}
- char *newbuf = realloc(b->buf, cap);
+ uint8_t *newbuf = realloc(b->buf, cap);
b->buf = newbuf;
b->cap = cap;
}
diff --git a/termbox/input.inl.c b/termbox/input.inl.c
@@ -1,9 +1,12 @@
// if s1 starts with s2 returns true, else false
// len is the length of s1
// s2 should be null-terminated
-static bool starts_with(const char *s1, int len, const char *s2)
+static bool starts_with(const void *_s1, int len, const void *_s2)
{
+ const uint8_t *s1 = _s1;
+ const uint8_t *s2 = _s2;
int n = 0;
+
while (*s2 && n < len) {
if (*s1++ != *s2++)
return false;
@@ -12,7 +15,7 @@ static bool starts_with(const char *s1, int len, const char *s2)
return *s2 == 0;
}
-static int parse_mouse_event(struct tb_event *event, const char *buf, int len) {
+static int parse_mouse_event(struct tb_event *event, uint8_t *buf, int len) {
if (len >= 6 && starts_with(buf, len, "\033[M")) {
// X10 mouse encoding, the simplest one
// \033 [ M Cb Cx Cy
@@ -87,9 +90,9 @@ static int parse_mouse_event(struct tb_event *event, const char *buf, int len) {
if (s1 == -1 || s2 == -1 || s1 == s2)
return 0;
- n1 = strtoul(&buf[starti], NULL, 10);
- n2 = strtoul(&buf[s1 + 1], NULL, 10);
- n3 = strtoul(&buf[s2 + 1], NULL, 10);
+ n1 = strtoul((void*) &buf[starti], NULL, 10);
+ n2 = strtoul((void*) &buf[s1 + 1], NULL, 10);
+ n3 = strtoul((void*) &buf[s2 + 1], NULL, 10);
if (isU)
n1 -= 32;
@@ -138,7 +141,7 @@ static int parse_mouse_event(struct tb_event *event, const char *buf, int len) {
}
// convert escape sequence to event, and return consumed bytes on success (failure == 0)
-static int parse_escape_seq(struct tb_event *event, const char *buf, int len)
+static int parse_escape_seq(struct tb_event *event, uint8_t *buf, int len)
{
int mouse_parsed = parse_mouse_event(event, buf, len);
@@ -160,7 +163,7 @@ static int parse_escape_seq(struct tb_event *event, const char *buf, int len)
static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf, int inputmode)
{
- const char *buf = inbuf->buf;
+ uint8_t *buf = inbuf->buf;
const int len = inbuf->len;
if (len == 0)
return false;
@@ -200,25 +203,30 @@ static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf, int
// if we're here, this is not an escape sequence and not an alt sequence
// so, it's a FUNCTIONAL KEY or a UNICODE character
+ uint8_t buf0 = buf[0];
+
// first of all check if it's a functional key
- if ((unsigned char)buf[0] <= TB_KEY_SPACE ||
- (unsigned char)buf[0] == TB_KEY_BACKSPACE2)
+ if (buf0 <= TB_KEY_SPACE ||
+ buf0 == TB_KEY_BACKSPACE2)
{
- // fill event, pop buffer, return success */
- event->ch = 0;
- event->key = (uint16_t)buf[0];
- bytebuffer_truncate(inbuf, 1);
- return true;
+ if (buf0 != TB_KEY_SPACE ||
+ !(inputmode&TB_INPUT_SPACE)) {
+ // fill event, pop buffer, return success */
+ event->ch = 0;
+ event->key = buf0;
+ bytebuffer_truncate(inbuf, 1);
+ return true;
+ }
}
// feh... we got utf8 here
// check if there is all bytes
- if (len >= tb_utf8_char_length(buf[0])) {
+ if (len >= tb_utf8_char_length(buf0)) {
/* everything ok, fill event, pop buffer, return success */
tb_utf8_char_to_unicode(&event->ch, buf);
event->key = 0;
- bytebuffer_truncate(inbuf, tb_utf8_char_length(buf[0]));
+ bytebuffer_truncate(inbuf, tb_utf8_char_length(buf0));
return true;
}
diff --git a/termbox/termbox.h b/termbox/termbox.h
@@ -228,10 +228,11 @@ SO_IMPORT void tb_blit(int x, int y, int w, int h, const struct tb_cell *cells);
*/
SO_IMPORT struct tb_cell *tb_cell_buffer(void);
-#define TB_INPUT_CURRENT 0 /* 000 */
-#define TB_INPUT_ESC 1 /* 001 */
-#define TB_INPUT_ALT 2 /* 010 */
-#define TB_INPUT_MOUSE 4 /* 100 */
+#define TB_INPUT_CURRENT 0 /* 0000 */
+#define TB_INPUT_ESC 1 /* 0001 */
+#define TB_INPUT_ALT 2 /* 0010 */
+#define TB_INPUT_MOUSE 4 /* 0100 */
+#define TB_INPUT_SPACE 8 /* 1000 */
/* Sets the termbox input mode. Termbox has two input modes:
* 1. Esc input mode.
@@ -247,6 +248,9 @@ SO_IMPORT struct tb_cell *tb_cell_buffer(void);
* reason you've decided to use (TB_INPUT_ESC | TB_INPUT_ALT) combination, it
* will behave as if only TB_INPUT_ESC was selected.
*
+ * TB_INPUT_SPACE may be bitwise OR'd as well to treat space as a regular
+ * character rather than a special/function key.
+ *
* If 'mode' is TB_INPUT_CURRENT, it returns the current input mode.
*
* Default termbox input mode is TB_INPUT_ESC.
@@ -311,8 +315,8 @@ SO_IMPORT int tb_poll_event(struct tb_event *event);
/* Utility utf8 functions. */
#define TB_EOF -1
-SO_IMPORT int tb_utf8_char_length(char c);
-SO_IMPORT int tb_utf8_char_to_unicode(uint32_t *out, const char *c);
+SO_IMPORT int tb_utf8_char_length(uint8_t c);
+SO_IMPORT int tb_utf8_char_to_unicode(uint32_t *out, uint8_t *c);
SO_IMPORT int tb_utf8_unicode_to_char(char *out, uint32_t c);
#ifdef __cplusplus
diff --git a/termbox/utf8.c b/termbox/utf8.c
@@ -1,6 +1,6 @@
#include "termbox.h"
-static const unsigned char utf8_length[256] = {
+static const uint8_t utf8_length[256] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
@@ -11,7 +11,7 @@ static const unsigned char utf8_length[256] = {
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
};
-static const unsigned char utf8_mask[6] = {
+static const uint8_t utf8_mask[6] = {
0x7F,
0x1F,
0x0F,
@@ -20,12 +20,12 @@ static const unsigned char utf8_mask[6] = {
0x01
};
-int tb_utf8_char_length(char c)
+int tb_utf8_char_length(uint8_t c)
{
- return utf8_length[(unsigned char)c];
+ return utf8_length[c];
}
-int tb_utf8_char_to_unicode(uint32_t *out, const char *c)
+int tb_utf8_char_to_unicode(uint32_t *out, uint8_t *c)
{
if (*c == 0)
return TB_EOF;