protect initdata, notcurses_getvec()

pull/2166/head
nick black 3 years ago
parent 1630a1629f
commit 5f00466b38
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -321,70 +321,72 @@ static int
stash_string(inputctx* ictx){ stash_string(inputctx* ictx){
struct initial_responses* inits = ictx->initdata; struct initial_responses* inits = ictx->initdata;
//fprintf(stderr, "string terminator after %d [%s]\n", inits->stringstate, inits->runstring); //fprintf(stderr, "string terminator after %d [%s]\n", inits->stringstate, inits->runstring);
switch(ictx->stringstate){ if(inits){
case STATE_XTVERSION1:{ switch(ictx->stringstate){
static const struct { case STATE_XTVERSION1:{
const char* prefix; static const struct {
char suffix; const char* prefix;
queried_terminals_e term; char suffix;
} xtvers[] = { queried_terminals_e term;
{ .prefix = "XTerm(", .suffix = ')', .term = TERMINAL_XTERM, }, } xtvers[] = {
{ .prefix = "WezTerm ", .suffix = 0, .term = TERMINAL_WEZTERM, }, { .prefix = "XTerm(", .suffix = ')', .term = TERMINAL_XTERM, },
{ .prefix = "contour ", .suffix = 0, .term = TERMINAL_CONTOUR, }, { .prefix = "WezTerm ", .suffix = 0, .term = TERMINAL_WEZTERM, },
{ .prefix = "kitty(", .suffix = ')', .term = TERMINAL_KITTY, }, { .prefix = "contour ", .suffix = 0, .term = TERMINAL_CONTOUR, },
{ .prefix = "foot(", .suffix = ')', .term = TERMINAL_FOOT, }, { .prefix = "kitty(", .suffix = ')', .term = TERMINAL_KITTY, },
{ .prefix = "mlterm(", .suffix = ')', .term = TERMINAL_MLTERM, }, { .prefix = "foot(", .suffix = ')', .term = TERMINAL_FOOT, },
{ .prefix = "tmux ", .suffix = 0, .term = TERMINAL_TMUX, }, { .prefix = "mlterm(", .suffix = ')', .term = TERMINAL_MLTERM, },
{ .prefix = "iTerm2 ", .suffix = 0, .term = TERMINAL_ITERM, }, { .prefix = "tmux ", .suffix = 0, .term = TERMINAL_TMUX, },
{ .prefix = "mintty ", .suffix = 0, .term = TERMINAL_MINTTY, }, { .prefix = "iTerm2 ", .suffix = 0, .term = TERMINAL_ITERM, },
{ .prefix = NULL, .suffix = 0, .term = TERMINAL_UNKNOWN, }, { .prefix = "mintty ", .suffix = 0, .term = TERMINAL_MINTTY, },
}, *xtv; { .prefix = NULL, .suffix = 0, .term = TERMINAL_UNKNOWN, },
for(xtv = xtvers ; xtv->prefix ; ++xtv){ }, *xtv;
if(strncmp(ictx->runstring, xtv->prefix, strlen(xtv->prefix)) == 0){ for(xtv = xtvers ; xtv->prefix ; ++xtv){
if(extract_xtversion(ictx, strlen(xtv->prefix), xtv->suffix) == 0){ if(strncmp(ictx->runstring, xtv->prefix, strlen(xtv->prefix)) == 0){
inits->qterm = xtv->term; if(extract_xtversion(ictx, strlen(xtv->prefix), xtv->suffix) == 0){
inits->qterm = xtv->term;
}
break;
} }
}
if(xtv->prefix == NULL){
logwarn("Unrecognizable XTVERSION [%s]\n", ictx->runstring);
}
break;
}case STATE_XTGETTCAP_TERMNAME1:
if(strcmp(ictx->runstring, "xterm-kitty") == 0){
inits->qterm = TERMINAL_KITTY;
}else if(strcmp(ictx->runstring, "mlterm") == 0){
// MLterm prior to late 3.9.1 only reports via XTGETTCAP
inits->qterm = TERMINAL_MLTERM;
}
break;
case STATE_TDA1:
if(strcmp(ictx->runstring, "~VTE") == 0){
inits->qterm = TERMINAL_VTE;
}else if(strcmp(ictx->runstring, "~~TY") == 0){
inits->qterm = TERMINAL_TERMINOLOGY;
}else if(strcmp(ictx->runstring, "FOOT") == 0){
inits->qterm = TERMINAL_FOOT;
}
break;
case STATE_BG1:{
int r, g, b;
if(sscanf(ictx->runstring, "rgb:%02x/%02x/%02x", &r, &g, &b) == 3){
// great! =]
}else if(sscanf(ictx->runstring, "rgb:%04x/%04x/%04x", &r, &g, &b) == 3){
r /= 256;
g /= 256;
b /= 256;
}else{
break; break;
} }
} inits->bg = (r << 16u) | (g << 8u) | b;
if(xtv->prefix == NULL){
logwarn("Unrecognizable XTVERSION [%s]\n", ictx->runstring);
}
break;
}case STATE_XTGETTCAP_TERMNAME1:
if(strcmp(ictx->runstring, "xterm-kitty") == 0){
inits->qterm = TERMINAL_KITTY;
}else if(strcmp(ictx->runstring, "mlterm") == 0){
// MLterm prior to late 3.9.1 only reports via XTGETTCAP
inits->qterm = TERMINAL_MLTERM;
}
break;
case STATE_TDA1:
if(strcmp(ictx->runstring, "~VTE") == 0){
inits->qterm = TERMINAL_VTE;
}else if(strcmp(ictx->runstring, "~~TY") == 0){
inits->qterm = TERMINAL_TERMINOLOGY;
}else if(strcmp(ictx->runstring, "FOOT") == 0){
inits->qterm = TERMINAL_FOOT;
}
break;
case STATE_BG1:{
int r, g, b;
if(sscanf(ictx->runstring, "rgb:%02x/%02x/%02x", &r, &g, &b) == 3){
// great! =]
}else if(sscanf(ictx->runstring, "rgb:%04x/%04x/%04x", &r, &g, &b) == 3){
r /= 256;
g /= 256;
b /= 256;
}else{
break; break;
} }default:
inits->bg = (r << 16u) | (g << 8u) | b; // don't generally enable this -- XTerm terminates TDA with ST
break; //fprintf(stderr, "invalid string [%s] stashed %d\n", inits->runstring, inits->stringstate);
}default: break;
// don't generally enable this -- XTerm terminates TDA with ST }
//fprintf(stderr, "invalid string [%s] stashed %d\n", inits->runstring, inits->stringstate);
break;
} }
ictx->runstring[0] = '\0'; ictx->runstring[0] = '\0';
ictx->stridx = 0; ictx->stridx = 0;
@ -451,7 +453,9 @@ pump_control_read(inputctx* ictx, unsigned char c){
break; break;
case STATE_APC: case STATE_APC:
if(c == 'G'){ if(c == 'G'){
ictx->initdata->kitty_graphics = true; if(ictx->initdata){
ictx->initdata->kitty_graphics = true;
}
} }
ictx->state = STATE_APC_DRAIN; ictx->state = STATE_APC_DRAIN;
break; break;
@ -503,11 +507,13 @@ pump_control_read(inputctx* ictx, unsigned char c){
// SDA yields up Alacritty's crate version, but it doesn't unambiguously // SDA yields up Alacritty's crate version, but it doesn't unambiguously
// identify Alacritty. If we've got any other version information, skip // identify Alacritty. If we've got any other version information, skip
// directly to STATE_SDA_DRAIN, rather than doing STATE_SDA_VER. // directly to STATE_SDA_DRAIN, rather than doing STATE_SDA_VER.
if(ictx->initdata->qterm || ictx->initdata->version){ if(ictx->initdata){
loginfo("Identified terminal already; ignoring DA2\n"); if(ictx->initdata->qterm || ictx->initdata->version){
ictx->state = STATE_SDA_DRAIN; loginfo("Identified terminal already; ignoring DA2\n");
}else{ ictx->state = STATE_SDA_DRAIN;
ictx->state = STATE_SDA; }else{
ictx->state = STATE_SDA;
}
} }
}else if(isdigit(c)){ }else if(isdigit(c)){
ictx->numeric = 0; ictx->numeric = 0;
@ -562,16 +568,22 @@ pump_control_read(inputctx* ictx, unsigned char c){
ictx->state = STATE_NULL; ictx->state = STATE_NULL;
}else if(c == 't'){ }else if(c == 't'){
//fprintf(stderr, "CELLS X: %d\n", ictx->numeric); //fprintf(stderr, "CELLS X: %d\n", ictx->numeric);
ictx->initdata->dimx = ictx->numeric; if(ictx->initdata){
ictx->initdata->dimy = ictx->p2; ictx->initdata->dimx = ictx->numeric;
ictx->initdata->dimy = ictx->p2;
}
ictx->state = STATE_NULL; ictx->state = STATE_NULL;
}else if(c == ';'){ }else if(c == ';'){
if(ictx->p2 == 4){ if(ictx->p2 == 4){
ictx->initdata->pixy = ictx->numeric; if(ictx->initdata){
ictx->state = STATE_PIXELS_WIDTH; ictx->initdata->pixy = ictx->numeric;
ictx->state = STATE_PIXELS_WIDTH;
}
ictx->numeric = 0; ictx->numeric = 0;
}else if(ictx->p2 == 8){ }else if(ictx->p2 == 8){
ictx->initdata->dimy = ictx->numeric; if(ictx->initdata){
ictx->initdata->dimy = ictx->numeric;
}
ictx->state = STATE_CELLS_WIDTH; ictx->state = STATE_CELLS_WIDTH;
ictx->numeric = 0; ictx->numeric = 0;
}else{ }else{
@ -588,8 +600,10 @@ pump_control_read(inputctx* ictx, unsigned char c){
return -1; return -1;
} }
}else if(c == 't'){ }else if(c == 't'){
ictx->initdata->pixx = ictx->numeric; if(ictx->initdata){
loginfo("got pixel geometry: %d/%d\n", ictx->initdata->pixy, ictx->initdata->pixx); ictx->initdata->pixx = ictx->numeric;
loginfo("got pixel geometry: %d/%d\n", ictx->initdata->pixy, ictx->initdata->pixx);
}
ictx->state = STATE_NULL; ictx->state = STATE_NULL;
}else{ }else{
ictx->state = STATE_NULL; ictx->state = STATE_NULL;
@ -601,8 +615,10 @@ pump_control_read(inputctx* ictx, unsigned char c){
return -1; return -1;
} }
}else if(c == 't'){ }else if(c == 't'){
ictx->initdata->dimx = ictx->numeric; if(ictx->initdata){
loginfo("got cell geometry: %d/%d\n", ictx->initdata->dimy, ictx->initdata->dimx); ictx->initdata->dimx = ictx->numeric;
loginfo("got cell geometry: %d/%d\n", ictx->initdata->dimy, ictx->initdata->dimx);
}
ictx->state = STATE_NULL; ictx->state = STATE_NULL;
}else{ }else{
ictx->state = STATE_NULL; ictx->state = STATE_NULL;
@ -722,12 +738,14 @@ pump_control_read(inputctx* ictx, unsigned char c){
case STATE_SDA_VER: case STATE_SDA_VER:
if(c == ';'){ if(c == ';'){
ictx->state = STATE_SDA_DRAIN; ictx->state = STATE_SDA_DRAIN;
loginfo("Got DA2 Pv: %u\n", ictx->numeric); if(ictx->initdata){
// if a version was set, we couldn't have arrived here. alacritty loginfo("Got DA2 Pv: %u\n", ictx->numeric);
// writes its crate version here, in an encoded form. nothing else // if a version was set, we couldn't have arrived here. alacritty
// necessarily does, though, so allow failure. this value will be // writes its crate version here, in an encoded form. nothing else
// interpreted as the version only if TERM indicates alacritty. // necessarily does, though, so allow failure. this value will be
ictx->initdata->version = set_sda_version(ictx); // interpreted as the version only if TERM indicates alacritty.
ictx->initdata->version = set_sda_version(ictx);
}
}else if(ruts_numeric(&ictx->numeric, c)){ }else if(ruts_numeric(&ictx->numeric, c)){
return -1; return -1;
} }
@ -807,8 +825,10 @@ pump_control_read(inputctx* ictx, unsigned char c){
} }
}else if(c == 'S'){ }else if(c == 'S'){
if(ictx->p2 == 1){ if(ictx->p2 == 1){
ictx->initdata->color_registers = ictx->numeric; if(ictx->initdata){
loginfo("sixel color registers: %d\n", ictx->initdata->color_registers); ictx->initdata->color_registers = ictx->numeric;
loginfo("sixel color registers: %d\n", ictx->initdata->color_registers);
}
ictx->numeric = 0; ictx->numeric = 0;
} }
ictx->state = STATE_NULL; ictx->state = STATE_NULL;
@ -836,9 +856,11 @@ pump_control_read(inputctx* ictx, unsigned char c){
return -1; return -1;
} }
}else if(c == 'S'){ }else if(c == 'S'){
ictx->initdata->sixelx = ictx->p4; if(ictx->initdata){
ictx->initdata->sixely = ictx->numeric; ictx->initdata->sixelx = ictx->p4;
loginfo("max sixel geometry: %dx%d\n", ictx->initdata->sixely, ictx->initdata->sixelx); ictx->initdata->sixely = ictx->numeric;
loginfo("max sixel geometry: %dx%d\n", ictx->initdata->sixely, ictx->initdata->sixelx);
}
}else if(c >= 0x40 && c <= 0x7E){ }else if(c >= 0x40 && c <= 0x7E){
ictx->state = STATE_NULL; ictx->state = STATE_NULL;
if(c == 'c'){ if(c == 'c'){
@ -848,7 +870,9 @@ pump_control_read(inputctx* ictx, unsigned char c){
break; break;
case STATE_APPSYNC_REPORT: case STATE_APPSYNC_REPORT:
if(ictx->numeric == '2'){ if(ictx->numeric == '2'){
ictx->initdata->appsync_supported = 1; if(ictx->initdata){
ictx->initdata->appsync_supported = 1;
}
ictx->state = STATE_APPSYNC_REPORT_DRAIN; ictx->state = STATE_APPSYNC_REPORT_DRAIN;
} }
break; break;
@ -1174,6 +1198,23 @@ uint32_t notcurses_get(notcurses* nc, const struct timespec* ts, ncinput* ni){
return r; return r;
} }
int notcurses_getvec(notcurses* n, const struct timespec* ts,
ncinput* ni, int vcount){
for(int v = 0 ; v < vcount ; ++v){
// FIXME need to manage ts; right now, we could delay up to ts * vcount!
uint32_t u = notcurses_get(n, ts, &ni[v]);
if(u == (uint32_t)-1){
if(v == 0){
return -1;
}
return v;
}else if(u == 0){
return v;
}
}
return vcount;
}
uint32_t ncdirect_get(ncdirect* n, const struct timespec* ts, ncinput* ni){ uint32_t ncdirect_get(ncdirect* n, const struct timespec* ts, ncinput* ni){
return internal_get(n->tcache.ictx, ts, ni, 0, 0); return internal_get(n->tcache.ictx, ts, ni, 0, 0);
} }

Loading…
Cancel
Save