input: decode special keys, call notcurses_resize() #79

This commit is contained in:
nick black 2019-11-29 03:56:53 -05:00
parent e391bfbb81
commit 8c6d0495ee
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
4 changed files with 52 additions and 18 deletions

View File

@ -140,6 +140,7 @@ API int notcurses_render(struct notcurses* nc);
// 0 is returned only by notcurses_getc(), to indicate that no input was
// available. Otherwise (including on EOF) -1 is returned.
typedef enum {
NCKEY_INVALID,
NCKEY_RESIZE,
NCKEY_UP,
NCKEY_RIGHT,
@ -158,7 +159,7 @@ API int notcurses_getc_blocking(const struct notcurses* n, cell* c,
// (as signaled via SIGWINCH), notcurses_render() might not function properly.
// References to ncplanes remain valid following a resize operation, but the
// cursor might have changed position.
API int notcurses_resize(struct notcurses* n);
API int notcurses_resize(struct notcurses* n, int* y, int* x);
// Get a reference to the standard plane (one matching our current idea of the
// terminal size) for this terminal.

View File

@ -6,18 +6,34 @@
#include <iostream>
#include <notcurses.h>
static int dimy, dimx;
static struct notcurses* nc;
const char* nckeystr(ncspecial_key key){
switch(key){
case NCKEY_RESIZE:
notcurses_resize(nc, &dimy, &dimx);
return "resize event";
case NCKEY_INVALID: return "invalid";
case NCKEY_LEFT: return "left";
case NCKEY_UP: return "up";
case NCKEY_RIGHT: return "right";
case NCKEY_DOWN: return "down";
default: return "unknown";
}
}
int main(void){
if(setlocale(LC_ALL, "") == nullptr){
return EXIT_FAILURE;
}
notcurses_options opts{};
opts.outfp = stdout;
struct notcurses* nc = notcurses_init(&opts);
if(nc == nullptr){
if((nc = notcurses_init(&opts)) == nullptr){
return EXIT_FAILURE;;
}
struct ncplane* n = notcurses_stdplane(nc);
int r, dimy, dimx;
int r;
notcurses_term_dim_yx(nc, &dimy, &dimx);
cell c = CELL_TRIVIAL_INITIALIZER;
if(ncplane_fg_rgb8(n, 255, 255, 255)){
@ -36,7 +52,12 @@ int main(void){
}
if(cell_simple_p(&c)){
char kp = c.gcluster;
if(ncplane_printf(n, "Got keypress: [0x%04x (%04d)] '%c'\n", kp, kp, kp) < 0){
if(kp == 0){
if(ncplane_printf(n, "Got special key: [0x%04x (%04d)] '%s'\n",
special, special, nckeystr(special)) < 0){
break;
}
}else if(ncplane_printf(n, "Got UTF-8: [0x%04x (%04d)] '%c'\n", kp, kp, kp) < 0){
break;
}
}else{

View File

@ -89,12 +89,13 @@ typedef struct notcurses {
// only one notcurses object can be the target of signal handlers, due to their
// process-wide nature.
static sig_atomic_t resize_seen;
static notcurses* _Atomic signal_nc = ATOMIC_VAR_INIT(NULL); // ugh
static void (*signal_sa_handler)(int); // stashed signal handler we replaced
static void
sigwinch_handler(int signo __attribute__ ((unused))){
// FIXME
sigwinch_handler(int signo){
resize_seen = signo;
}
// this wildly unsafe handler will attempt to restore the screen upon
@ -316,21 +317,19 @@ create_initial_ncplane(notcurses* nc){
return nc->stdscr;
}
// Call this when the screen size changes. Takes a flat
// array of *rows * *cols cells (may be NULL if *rows == *cols == 0). Gets the
// new size, and copies what can be copied from the old stdscr. Assumes that
// the screen is always anchored in the same place.
// FIXME rewrite this in terms of ncpanel_resize(n->stdscr)
int notcurses_resize(notcurses* n){
// Call this when the screen size changes. Acquires the new size, and copies
// what can be copied from the old stdscr. Assumes that the screen is always
// anchored in the same place.
// // FIXME rewrite this in terms of ncpanel_resize(n->stdscr)
int notcurses_resize(notcurses* n, int* rows, int* cols){
int oldrows = n->stdscr->leny;
int oldcols = n->stdscr->lenx;
int rows, cols;
if(update_term_dimensions(n, &rows, &cols)){
if(update_term_dimensions(n, rows, cols)){
return -1;
}
ncplane* p = n->stdscr;
cell* preserved = p->fb;
size_t fbsize = sizeof(*preserved) * (rows * cols);
size_t fbsize = sizeof(*preserved) * (*rows * *cols);
if((p->fb = malloc(fbsize)) == NULL){
p->fb = preserved;
return -1;
@ -1315,6 +1314,12 @@ handle_getc(const notcurses* nc __attribute__ ((unused)), cell* c, int kpress,
}
int notcurses_getc(const notcurses* nc, cell* c, ncspecial_key* special){
if(resize_seen){
resize_seen = 0;
c->gcluster = 0;
*special = NCKEY_RESIZE;
return 1;
}
int r = getc(nc->ttyinfp);
if(r < 0){
return r;
@ -1325,6 +1330,14 @@ int notcurses_getc(const notcurses* nc, cell* c, ncspecial_key* special){
int notcurses_getc_blocking(const notcurses* nc, cell* c, ncspecial_key* special){
int r = getc(nc->ttyinfp);
if(r < 0){
if(errno == EINTR){
if(resize_seen){
resize_seen = 0;
c->gcluster = 0;
*special = NCKEY_RESIZE;
return 1;
}
}
return r;
}
return handle_getc(nc, c, r, special);

View File

@ -56,9 +56,8 @@ TEST_F(NotcursesTest, TermDimensions) {
TEST_F(NotcursesTest, ResizeSameSize) {
int x, y;
notcurses_term_dim_yx(nc_, &y, &x);
EXPECT_EQ(0, notcurses_resize(nc_));
int newx, newy;
notcurses_term_dim_yx(nc_, &newy, &newx);
EXPECT_EQ(0, notcurses_resize(nc_, &newy, &newx));
EXPECT_EQ(newx, x);
EXPECT_EQ(newy, y);
}