Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1136 - switch from ncurses to https://github.com/nsf/termbox
- Loading branch information
Showing
12 changed files
with
1,651 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Copyright (C) 2010-2013 nsf <no.smile.face@gmail.com> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Fork of https://github.com/nsf/termbox as of 2015-04-22 | ||
git hash 7c154d98a7d9207d768ee0a8e519ede74c0105cf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
struct bytebuffer { | ||
char *buf; | ||
int len; | ||
int cap; | ||
}; | ||
|
||
static void bytebuffer_reserve(struct bytebuffer *b, int cap) { | ||
if (b->cap >= cap) { | ||
return; | ||
} | ||
|
||
// prefer doubling capacity | ||
if (b->cap * 2 >= cap) { | ||
cap = b->cap * 2; | ||
} | ||
|
||
char *newbuf = malloc(cap); | ||
if (b->len > 0) { | ||
// copy what was there, b->len > 0 assumes b->buf != null | ||
memcpy(newbuf, b->buf, b->len); | ||
} | ||
if (b->buf) { | ||
// in case there was an allocated buffer, free it | ||
free(b->buf); | ||
} | ||
b->buf = newbuf; | ||
b->cap = cap; | ||
} | ||
|
||
static void bytebuffer_init(struct bytebuffer *b, int cap) { | ||
b->cap = 0; | ||
b->len = 0; | ||
b->buf = 0; | ||
|
||
if (cap > 0) { | ||
b->cap = cap; | ||
b->buf = malloc(cap); // just assume malloc works always | ||
} | ||
} | ||
|
||
static void bytebuffer_free(struct bytebuffer *b) { | ||
if (b->buf) | ||
free(b->buf); | ||
} | ||
|
||
static void bytebuffer_clear(struct bytebuffer *b) { | ||
b->len = 0; | ||
} | ||
|
||
static void bytebuffer_append(struct bytebuffer *b, const char *data, int len) { | ||
bytebuffer_reserve(b, b->len + len); | ||
memcpy(b->buf + b->len, data, len); | ||
b->len += len; | ||
} | ||
|
||
static void bytebuffer_puts(struct bytebuffer *b, const char *str) { | ||
bytebuffer_append(b, str, strlen(str)); | ||
} | ||
|
||
static void bytebuffer_resize(struct bytebuffer *b, int len) { | ||
bytebuffer_reserve(b, len); | ||
b->len = len; | ||
} | ||
|
||
static void bytebuffer_flush(struct bytebuffer *b, int fd) { | ||
write(fd, b->buf, b->len); | ||
bytebuffer_clear(b); | ||
} | ||
|
||
static void bytebuffer_truncate(struct bytebuffer *b, int n) { | ||
if (n <= 0) | ||
return; | ||
if (n > b->len) | ||
n = b->len; | ||
const int nmove = b->len - n; | ||
memmove(b->buf, b->buf+n, nmove); | ||
b->len -= n; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
// 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) | ||
{ | ||
int n = 0; | ||
while (*s2 && n < len) { | ||
if (*s1++ != *s2++) | ||
return false; | ||
n++; | ||
} | ||
return *s2 == 0; | ||
} | ||
|
||
// 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) | ||
{ | ||
if (len >= 6 && starts_with(buf, len, "\033[M")) { | ||
|
||
switch (buf[3] & 3) { | ||
case 0: | ||
if (buf[3] == 0x60) | ||
event->key = TB_KEY_MOUSE_WHEEL_UP; | ||
else | ||
event->key = TB_KEY_MOUSE_LEFT; | ||
break; | ||
case 1: | ||
if (buf[3] == 0x61) | ||
event->key = TB_KEY_MOUSE_WHEEL_DOWN; | ||
else | ||
event->key = TB_KEY_MOUSE_MIDDLE; | ||
break; | ||
case 2: | ||
event->key = TB_KEY_MOUSE_RIGHT; | ||
break; | ||
case 3: | ||
event->key = TB_KEY_MOUSE_RELEASE; | ||
break; | ||
default: | ||
return -6; | ||
} | ||
event->type = TB_EVENT_MOUSE; // TB_EVENT_KEY by default | ||
|
||
// the coord is 1,1 for upper left | ||
event->x = buf[4] - 1 - 32; | ||
event->y = buf[5] - 1 - 32; | ||
|
||
return 6; | ||
} | ||
|
||
// it's pretty simple here, find 'starts_with' match and return | ||
// success, else return failure | ||
int i; | ||
for (i = 0; keys[i]; i++) { | ||
if (starts_with(buf, len, keys[i])) { | ||
event->ch = 0; | ||
event->key = 0xFFFF-i; | ||
return strlen(keys[i]); | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf, int inputmode) | ||
{ | ||
const char *buf = inbuf->buf; | ||
const int len = inbuf->len; | ||
if (len == 0) | ||
return false; | ||
|
||
if (buf[0] == '\033') { | ||
int n = parse_escape_seq(event, buf, len); | ||
if (n != 0) { | ||
bool success = true; | ||
if (n < 0) { | ||
success = false; | ||
n = -n; | ||
} | ||
bytebuffer_truncate(inbuf, n); | ||
return success; | ||
} else { | ||
// it's not escape sequence, then it's ALT or ESC, | ||
// check inputmode | ||
if (inputmode&TB_INPUT_ESC) { | ||
// if we're in escape mode, fill ESC event, pop | ||
// buffer, return success | ||
event->ch = 0; | ||
event->key = TB_KEY_ESC; | ||
event->mod = 0; | ||
bytebuffer_truncate(inbuf, 1); | ||
return true; | ||
} | ||
if (inputmode&TB_INPUT_ALT) { | ||
// if we're in alt mode, set ALT modifier to | ||
// event and redo parsing | ||
event->mod = TB_MOD_ALT; | ||
bytebuffer_truncate(inbuf, 1); | ||
return extract_event(event, inbuf, inputmode); | ||
} | ||
assert(!"never got here"); | ||
} | ||
} | ||
|
||
// 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 | ||
|
||
// 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) | ||
{ | ||
// fill event, pop buffer, return success */ | ||
event->ch = 0; | ||
event->key = (uint16_t)buf[0]; | ||
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])) { | ||
/* 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])); | ||
return true; | ||
} | ||
|
||
// event isn't recognized, perhaps there is not enough bytes in utf8 | ||
// sequence | ||
return false; | ||
} |
Oops, something went wrong.