[input] provide utf8 form in ncinput

pull/2411/head
nick black 3 years ago
parent 62f694dfa3
commit 538dff91ba
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -35,6 +35,9 @@ rearrangements of Notcurses.
* `CELL_TRIVIAL_INITIALIZER`, `CELL_CHAR_INITIALIZER`, and
`CELL_INITIALIZER` are all now prefixed with `NC`.
* A new resize callback, `ncplane_resize_placewithin()`, has been added.
* The `ncinput` struct has a new field, `utf8`. `notcurses_get()` will fill
in this array of `char` with the NUL-terminated UTF-8 representation of
the input whenever one exists.
* 2.4.9 (2021-11-11)
* Added `ncnmetric()`, which uses `snprintf()` internally. `ncmetric()`

@ -18,6 +18,7 @@ typedef struct ncinput {
uint32_t id; // Unicode codepoint
int y; // Y cell coordinate of event, -1 for undefined
int x; // X cell coordinate of event, -1 for undefined
char utf8[5]; // utf8 representation, when one exists
bool alt; // Was Alt held during the event?
bool shift; // Was Shift held during the event?
bool ctrl; // Was Ctrl held during the event?
@ -69,6 +70,8 @@ must be explicitly enabled via **notcurses_mice_enable**. The full 32-bit
range of Unicode is supported (see **unicode(7)**), with synthesized events
mapped above the 1,114,112 codepoints of Unicode 14.0's seventeen Planes.
Unicode characters are returned directly as UCS-32, one codepoint at a time.
When the input has a UTF8 representation, it is written to **utf8**; this
field is always NUL-terminated.
notcurses takes its keyboard input from **stdin**, which will be placed into
non-blocking mode for the duration of operation. The terminal is put into

@ -1065,6 +1065,7 @@ nckey_mouse_p(uint32_t r){
typedef struct ncinput {
uint32_t id; // Unicode codepoint or synthesized NCKEY event
int y, x; // y/x cell coordinate of event, -1 for undefined
char utf8[5]; // utf8 representation, if one exists
bool alt; // was alt held?
bool shift; // was shift held?
bool ctrl; // was ctrl held?

@ -346,7 +346,7 @@ int input_demo(ncpp::NotCurses* nc) {
}
}else{
n->set_fg_rgb8(64, 128, 250);
n->printf("Unicode: [0x%08x] '%lc'", r, (wchar_t)r);
n->printf("Unicode: [0x%08x] '%s'", r, ni.utf8);
}
}
unsigned x;

@ -2220,6 +2220,10 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){
uint32_t id;
if(ictx->drain){
logerror("input is being drained\n");
if(ni){
memset(ni, 0, sizeof(*ni));
ni->id = (uint32_t)-1;
}
return (uint32_t)-1;
}
pthread_mutex_lock(&ictx->ilock);
@ -2239,9 +2243,16 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){
int r = pthread_cond_timedwait(&ictx->icond, &ictx->ilock, ts);
if(r == ETIMEDOUT){
pthread_mutex_unlock(&ictx->ilock);
if(ni){
memset(ni, 0, sizeof(*ni));
}
return 0;
}else if(r < 0){
inc_input_errors(ictx);
if(ni){
memset(ni, 0, sizeof(*ni));
ni->id = (uint32_t)-1;
}
return (uint32_t)-1;
}
}
@ -2249,6 +2260,9 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){
id = ictx->inputs[ictx->iread].id;
if(ni){
memcpy(ni, &ictx->inputs[ictx->iread], sizeof(*ni));
if(notcurses_ucs32_to_utf8(&ni->id, 1, (unsigned char*)ni->utf8, sizeof(ni->utf8)) < 0){
ni->utf8[0] = 0;
}
}
if(++ictx->iread == ictx->isize){
ictx->iread = 0;
@ -2278,14 +2292,8 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){
// infp has already been set non-blocking
uint32_t notcurses_get(notcurses* nc, const struct timespec* absdl, ncinput* ni){
uint32_t id = internal_get(nc->tcache.ictx, absdl, ni);
if(ni){
if(id == (uint32_t)-1){
ni->id = id;
}
}
logdebug("returning 0x%08x\n", id);
return id;
uint32_t ret = internal_get(nc->tcache.ictx, absdl, ni);
return ret;
}
// FIXME better performance if we move this within the locked area

Loading…
Cancel
Save