From 9c3d454c196c0353a6ec42d3e1dafc6ec5cad65f Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 18 Apr 2020 22:47:24 -0700 Subject: [PATCH] Added timeout argument for getkey. --- C/test.c | 2 +- Lua/lbtui.c | 5 ++- Makefile | 2 +- btui.h | 97 ++++++++++++++++++++++++++++------------------------- 4 files changed, 58 insertions(+), 48 deletions(-) diff --git a/C/test.c b/C/test.c index 5f23363..ff9f87a 100644 --- a/C/test.c +++ b/C/test.c @@ -21,7 +21,7 @@ int main(void) btui_flush(bt); int mouse_x = -1, mouse_y = -1; - int key = btui_getkey(bt, &mouse_x, &mouse_y); + int key = btui_getkey(bt, 0, &mouse_x, &mouse_y); btui_clear_screen(bt); switch (key) { case 'q': case KEY_CTRL_C: done = 1; break; diff --git a/Lua/lbtui.c b/Lua/lbtui.c index f8939df..eaa8dae 100644 --- a/Lua/lbtui.c +++ b/Lua/lbtui.c @@ -66,7 +66,10 @@ static int Lbtui_getkey(lua_State *L) if (bt == NULL) luaL_error(L, "Not a BTUI object"); if (*bt == NULL) luaL_error(L, "BTUI object not initialized"); int mouse_x = -1, mouse_y = -1; - int key = btui_getkey(*bt, &mouse_x, &mouse_y); + int isnum = 1; + int timeout = lua_gettop(L) > 1 ? lua_tointegerx(L, 2, &isnum) : -1; + if (!isnum) luaL_argerror(L, 2, "timeout should be an integer"); + int key = btui_getkey(*bt, timeout, &mouse_x, &mouse_y); if (key == -1) return 0; char buf[256] = {0}; btui_keyname(key, buf); diff --git a/Makefile b/Makefile index 02dae73..8e19b7f 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ checksyntax: btui.h clean: @cd Lua; make clean @cd C; make clean - @cd python; make clean + @cd Python; make clean %: %.c btui.h $(CC) $(CFLAGS) $(CWARN) $(G) $(O) $< -o $@ diff --git a/btui.h b/btui.h index f1ac6a8..436da7f 100644 --- a/btui.h +++ b/btui.h @@ -26,7 +26,7 @@ typedef struct { btui_t* btui_enable(void); void btui_disable(btui_t *bt); -int btui_getkey(btui_t *bt, int *mouse_x, int *mouse_y); +int btui_getkey(btui_t *bt, int timeout, int *mouse_x, int *mouse_y); int btui_move_cursor(btui_t *bt, int x, int y); char *btui_keyname(int key, char *buf); int btui_keynamed(const char *name); @@ -158,6 +158,48 @@ static keyname_t key_names[] = { {':', "Colon"}, }; +static const struct termios normal_termios = { + .c_iflag = ICRNL, + .c_oflag = OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0, + .c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE, + .c_cflag = CS8 | CREAD, + .c_cc[VINTR] = '', + .c_cc[VQUIT] = '', + .c_cc[VERASE] = 127, + .c_cc[VKILL] = '', + .c_cc[VEOF] = '', + .c_cc[VSTART] = '', + .c_cc[VSTOP] = '', + .c_cc[VSUSP] = '', + .c_cc[VREPRINT] = '', + .c_cc[VWERASE] = '', + .c_cc[VLNEXT] = '', + .c_cc[VDISCARD] = '', + .c_cc[VMIN] = 1, + .c_cc[VTIME] = 0, +}; + +static struct termios tui_termios = { + .c_iflag = 0, + .c_oflag = ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0, + .c_lflag = ECHOE | ECHOK | ECHOCTL | ECHOKE, + .c_cflag = CS8 | CREAD, + .c_cc[VINTR] = '', + .c_cc[VQUIT] = '', + .c_cc[VERASE] = 127, + .c_cc[VKILL] = '', + .c_cc[VEOF] = '', + .c_cc[VSTART] = '', + .c_cc[VSTOP] = '', + .c_cc[VSUSP] = '', + .c_cc[VREPRINT] = '', + .c_cc[VWERASE] = '', + .c_cc[VLNEXT] = '', + .c_cc[VDISCARD] = '', + .c_cc[VMIN] = 1, + .c_cc[VTIME] = 0, +}; + static inline int nextchar(int fd) { char c; @@ -176,8 +218,16 @@ static inline int nextnum(int fd, int c, int *n) * If mouse_x or mouse_y are non-null and a mouse event occurs, they will be * set to the position of the mouse (0-indexed). */ -int btui_getkey(btui_t *bt, int *mouse_x, int *mouse_y) +int btui_getkey(btui_t *bt, int timeout, int *mouse_x, int *mouse_y) { + int new_vmin = timeout < 0 ? 1 : 0, new_vtime = timeout < 0 ? 0 : timeout; + if (new_vmin != tui_termios.c_cc[VMIN] || new_vtime != tui_termios.c_cc[VTIME]) { + tui_termios.c_cc[VMIN] = new_vmin; + tui_termios.c_cc[VTIME] = new_vtime; + if (tcsetattr(fileno(bt->out), TCSANOW, &tui_termios) == -1) + return -1; + } + if (mouse_x) *mouse_x = -1; if (mouse_y) *mouse_y = -1; int fd = fileno(bt->in); @@ -366,49 +416,6 @@ int btui_keynamed(const char *name) return strlen(name) == 1 ? name[0] : -1; } - -static const struct termios normal_termios = { - .c_iflag = ICRNL, - .c_oflag = OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0, - .c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE, - .c_cflag = CS8 | CREAD, - .c_cc[VINTR] = '', - .c_cc[VQUIT] = '', - .c_cc[VERASE] = 127, - .c_cc[VKILL] = '', - .c_cc[VEOF] = '', - .c_cc[VSTART] = '', - .c_cc[VSTOP] = '', - .c_cc[VSUSP] = '', - .c_cc[VREPRINT] = '', - .c_cc[VWERASE] = '', - .c_cc[VLNEXT] = '', - .c_cc[VDISCARD] = '', - .c_cc[VMIN] = 1, - .c_cc[VTIME] = 0, -}; - -static const struct termios tui_termios = { - .c_iflag = 0, - .c_oflag = ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0, - .c_lflag = ECHOE | ECHOK | ECHOCTL | ECHOKE, - .c_cflag = CS8 | CREAD, - .c_cc[VINTR] = '', - .c_cc[VQUIT] = '', - .c_cc[VERASE] = 127, - .c_cc[VKILL] = '', - .c_cc[VEOF] = '', - .c_cc[VSTART] = '', - .c_cc[VSTOP] = '', - .c_cc[VSUSP] = '', - .c_cc[VREPRINT] = '', - .c_cc[VWERASE] = '', - .c_cc[VLNEXT] = '', - .c_cc[VDISCARD] = '', - .c_cc[VMIN] = 1, - .c_cc[VTIME] = 0, -}; - static void cleanup(void) { if (!current_bt.out) return;