Unify interrogate_terminfo() #614

pull/632/head
nick black 4 years ago
parent 30412d54ce
commit 381263e9fe
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -225,8 +225,8 @@ int main(void){
if(!plot){
return EXIT_FAILURE;
}
n->set_fg(0);
n->set_bg(0xbb64bb);
n->set_fg_rgb(0x00, 0x00, 0x00);
n->set_bg_rgb(0xbb, 0x64, 0xbb);
n->styles_on(CellStyle::Underline);
if(n->putstr(0, NCAlign::Center, "mash keys, yo. give that mouse some waggle! ctrl+d exits.") <= 0){
return EXIT_FAILURE;
@ -234,7 +234,7 @@ int main(void){
n->styles_set(CellStyle::None);
n->set_bg_default();
if(!nc.render()){
throw std::runtime_error("error rendering");
return EXIT_FAILURE;
}
int y = 2;
std::deque<wchar_t> cells;
@ -247,7 +247,6 @@ int main(void){
if(r == 0){ // interrupted by signal
continue;
}
if((r == 'D' || r == 'd') && ni.ctrl){
done = true;
tid.join();
@ -276,13 +275,11 @@ int main(void){
}else{
if(nckey_supppuab_p(r)){
n->set_fg_rgb(250, 64, 128);
if(n->printf("Special: [0x%02x (%02d)] '%s'",
r, r, nckeystr(r)) < 0){
if(n->printf("Special: [0x%02x (%02d)] '%s'", r, r, nckeystr(r)) < 0){
break;
}
if(NCKey::IsMouse(r)){
if(n->printf(-1, NCAlign::Right, " x: %d y: %d",
ni.x, ni.y) < 0){
if(n->printf(-1, NCAlign::Right, " x: %d y: %d", ni.x, ni.y) < 0){
break;
}
}

@ -320,6 +320,9 @@ typedef struct notcurses {
void sigwinch_handler(int signo);
int term_verify_seq(char** gseq, const char* name);
int interrogate_terminfo(tinfo* ti);
// Search the provided multibyte (UTF8) string 's' for the provided unicode
// codepoint 'cp'. If found, return the column offset of the EGC in which the
// codepoint appears in 'col', and the byte offset as the return value. If not

@ -238,19 +238,6 @@ int update_term_dimensions(int fd, int* rows, int* cols){
return 0;
}
static int
term_verify_seq(char** gseq, const char* name){
char* seq;
if(gseq == NULL){
gseq = &seq;
}
*gseq = tigetstr(name);
if(*gseq == NULL || *gseq == (char*)-1){
return -1;
}
return 0;
}
static void
free_plane(ncplane* p){
if(p){
@ -525,141 +512,6 @@ int ncplane_destroy(ncplane* ncp){
return 0;
}
static bool
query_rgb(void){
bool rgb = tigetflag("RGB") == 1;
if(!rgb){
// RGB terminfo capability being a new thing (as of ncurses 6.1), it's not commonly found in
// terminal entries today. COLORTERM, however, is a de-facto (if imperfect/kludgy) standard way
// of indicating TrueColor support for a terminal. The variable takes one of two case-sensitive
// values:
//
// truecolor
// 24bit
//
// https://gist.github.com/XVilka/8346728#true-color-detection gives some more information about
// the topic
//
const char* cterm = getenv("COLORTERM");
rgb = cterm && (strcmp(cterm, "truecolor") == 0 || strcmp(cterm, "24bit") == 0);
}
return rgb;
}
static int
interrogate_terminfo(notcurses* nc, const notcurses_options* opts, int* dimy, int* dimx){
*dimy = *dimx = 0;
update_term_dimensions(nc->ttyfd, dimy, dimx);
nc->truecols = *dimx;
char* shortname_term = termname();
char* longname_term = longname();
if(!opts->suppress_banner){
fprintf(stderr, "Term: %dx%d %s (%s)\n", *dimx, *dimy,
shortname_term ? shortname_term : "?",
longname_term ? longname_term : "?");
}
nc->tcache.RGBflag = query_rgb();
if((nc->tcache.colors = tigetnum("colors")) <= 0){
if(!opts->suppress_banner){
fprintf(stderr, "This terminal doesn't appear to support colors\n");
}
nc->tcache.colors = 1;
nc->tcache.CCCflag = false;
nc->tcache.RGBflag = false;
nc->tcache.initc = NULL;
}else{
term_verify_seq(&nc->tcache.initc, "initc");
if(nc->tcache.initc){
nc->tcache.CCCflag = tigetflag("ccc") == 1;
}else{
nc->tcache.CCCflag = false;
}
}
term_verify_seq(&nc->tcache.cup, "cup");
if(nc->tcache.cup == NULL){
fprintf(stderr, "Required terminfo capability 'cup' not defined\n");
return -1;
}
nc->tcache.AMflag = tigetflag("am") == 1;
if(!nc->tcache.AMflag){
fprintf(stderr, "Required terminfo capability 'am' not defined\n");
return -1;
}
term_verify_seq(&nc->tcache.civis, "civis");
term_verify_seq(&nc->tcache.cnorm, "cnorm");
term_verify_seq(&nc->tcache.standout, "smso"); // smso / rmso
term_verify_seq(&nc->tcache.uline, "smul");
term_verify_seq(&nc->tcache.reverse, "reverse");
term_verify_seq(&nc->tcache.blink, "blink");
term_verify_seq(&nc->tcache.dim, "dim");
term_verify_seq(&nc->tcache.bold, "bold");
term_verify_seq(&nc->tcache.italics, "sitm");
term_verify_seq(&nc->tcache.italoff, "ritm");
term_verify_seq(&nc->tcache.sgr, "sgr");
term_verify_seq(&nc->tcache.sgr0, "sgr0");
term_verify_seq(&nc->tcache.op, "op");
term_verify_seq(&nc->tcache.oc, "oc");
term_verify_seq(&nc->tcache.home, "home");
term_verify_seq(&nc->tcache.clearscr, "clear");
term_verify_seq(&nc->tcache.cleareol, "el");
term_verify_seq(&nc->tcache.clearbol, "el1");
term_verify_seq(&nc->tcache.cuf, "cuf"); // n non-destructive spaces
term_verify_seq(&nc->tcache.cub, "cub"); // n non-destructive backspaces
term_verify_seq(&nc->tcache.cuf1, "cuf1"); // non-destructive space
term_verify_seq(&nc->tcache.cub1, "cub1"); // non-destructive backspace
term_verify_seq(&nc->tcache.smkx, "smkx"); // set application mode
if(nc->tcache.smkx){
if(putp(tiparm(nc->tcache.smkx)) != OK){
fprintf(stderr, "Error entering application mode\n");
return -1;
}
}
if(prep_special_keys(nc)){
return -1;
}
// Some terminals cannot combine certain styles with colors. Don't advertise
// support for the style in that case.
int nocolor_stylemask = tigetnum("ncv");
if(nocolor_stylemask > 0){
if(nocolor_stylemask & WA_STANDOUT){ // ncv is composed of terminfo bits, not ours
nc->tcache.standout = NULL;
}
if(nocolor_stylemask & WA_UNDERLINE){
nc->tcache.uline = NULL;
}
if(nocolor_stylemask & WA_REVERSE){
nc->tcache.reverse = NULL;
}
if(nocolor_stylemask & WA_BLINK){
nc->tcache.blink = NULL;
}
if(nocolor_stylemask & WA_DIM){
nc->tcache.dim = NULL;
}
if(nocolor_stylemask & WA_BOLD){
nc->tcache.bold = NULL;
}
if(nocolor_stylemask & WA_ITALIC){
nc->tcache.italics = NULL;
}
}
term_verify_seq(&nc->tcache.getm, "getm"); // get mouse events
// Not all terminals support setting the fore/background independently
term_verify_seq(&nc->tcache.setaf, "setaf");
term_verify_seq(&nc->tcache.setab, "setab");
term_verify_seq(&nc->tcache.smkx, "smkx");
term_verify_seq(&nc->tcache.rmkx, "rmkx");
// Neither of these is supported on e.g. the "linux" virtual console.
if(!opts->inhibit_alternate_screen){
term_verify_seq(&nc->tcache.smcup, "smcup");
term_verify_seq(&nc->tcache.rmcup, "rmcup");
}else{
nc->tcache.smcup = nc->tcache.rmcup = NULL;
}
nc->top = nc->stdscr = NULL;
return 0;
}
static int
make_nonblocking(FILE* fp){
int fd = fileno(fp);
@ -769,43 +621,9 @@ ncdirect* ncdirect_init(const char* termtype, FILE* outfp){
free(ret);
return NULL;
}
term_verify_seq(&ret->tcache.standout, "smso"); // smso / rmso
term_verify_seq(&ret->tcache.uline, "smul");
term_verify_seq(&ret->tcache.reverse, "reverse");
term_verify_seq(&ret->tcache.blink, "blink");
term_verify_seq(&ret->tcache.dim, "dim");
term_verify_seq(&ret->tcache.bold, "bold");
term_verify_seq(&ret->tcache.italics, "sitm");
term_verify_seq(&ret->tcache.italoff, "ritm");
term_verify_seq(&ret->tcache.sgr, "sgr");
term_verify_seq(&ret->tcache.sgr0, "sgr0");
term_verify_seq(&ret->tcache.op, "op");
term_verify_seq(&ret->tcache.oc, "oc");
term_verify_seq(&ret->tcache.setaf, "setaf");
term_verify_seq(&ret->tcache.setab, "setab");
term_verify_seq(&ret->tcache.clear, "clear");
term_verify_seq(&ret->tcache.cup, "cup");
term_verify_seq(&ret->tcache.cuu, "cuu"); // move N up
term_verify_seq(&ret->tcache.cuf, "cuf"); // move N right
term_verify_seq(&ret->tcache.cud, "cud"); // move N down
term_verify_seq(&ret->tcache.cub, "cub"); // move N left
term_verify_seq(&ret->tcache.hpa, "hpa");
term_verify_seq(&ret->tcache.vpa, "vpa");
term_verify_seq(&ret->tcache.civis, "civis");
term_verify_seq(&ret->tcache.cnorm, "cnorm");
ret->tcache.RGBflag = query_rgb();
if((ret->tcache.colors = tigetnum("colors")) <= 0){
ret->tcache.colors = 1;
ret->tcache.CCCflag = false;
ret->tcache.RGBflag = false;
ret->tcache.initc = NULL;
}else{
term_verify_seq(&ret->tcache.initc, "initc");
if(ret->tcache.initc){
ret->tcache.CCCflag = tigetflag("ccc") == 1;
}else{
ret->tcache.CCCflag = false;
}
if(interrogate_terminfo(&ret->tcache)){
free(ret);
return NULL;
}
ret->fgdefault = ret->bgdefault = true;
ret->fgrgb = ret->bgrgb = 0;
@ -988,9 +806,27 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
goto err;
}
int dimy, dimx;
if(interrogate_terminfo(ret, opts, &dimy, &dimx)){
update_term_dimensions(ret->ttyfd, &dimy, &dimx);
char* shortname_term = termname();
char* longname_term = longname();
if(!opts->suppress_banner){
fprintf(stderr, "Term: %dx%d %s (%s)\n", dimx, dimy,
shortname_term ? shortname_term : "?",
longname_term ? longname_term : "?");
}
ret->truecols = dimx;
if(interrogate_terminfo(&ret->tcache)){
goto err;
}
if(prep_special_keys(ret)){
goto err;
}
// Neither of these is supported on e.g. the "linux" virtual console.
if(!opts->inhibit_alternate_screen){
term_verify_seq(&ret->tcache.smcup, "smcup");
term_verify_seq(&ret->tcache.rmcup, "rmcup");
}
ret->top = ret->stdscr = NULL;
if(ncvisual_init(ffmpeg_log_level(opts->loglevel))){
goto err;
}

@ -0,0 +1,129 @@
#include <ncurses.h> // needed for some definitions, see terminfo(3ncurses)
#include "internal.h"
static bool
query_rgb(void){
bool rgb = tigetflag("RGB") == 1;
if(!rgb){
// RGB terminfo capability being a new thing (as of ncurses 6.1), it's not commonly found in
// terminal entries today. COLORTERM, however, is a de-facto (if imperfect/kludgy) standard way
// of indicating TrueColor support for a terminal. The variable takes one of two case-sensitive
// values:
//
// truecolor
// 24bit
//
// https://gist.github.com/XVilka/8346728#true-color-detection gives some more information about
// the topic
//
const char* cterm = getenv("COLORTERM");
rgb = cterm && (strcmp(cterm, "truecolor") == 0 || strcmp(cterm, "24bit") == 0);
}
return rgb;
}
int term_verify_seq(char** gseq, const char* name){
char* seq;
if(gseq == NULL){
gseq = &seq;
}
*gseq = tigetstr(name);
if(*gseq == NULL || *gseq == (char*)-1){
return -1;
}
return 0;
}
int interrogate_terminfo(tinfo* ti){
memset(ti, 0, sizeof(*ti));
ti->RGBflag = query_rgb();
if((ti->colors = tigetnum("colors")) <= 0){
ti->colors = 1;
ti->CCCflag = false;
ti->RGBflag = false;
ti->initc = NULL;
}else{
term_verify_seq(&ti->initc, "initc");
if(ti->initc){
ti->CCCflag = tigetflag("ccc") == 1;
}else{
ti->CCCflag = false;
}
}
term_verify_seq(&ti->cup, "cup");
if(ti->cup == NULL){
fprintf(stderr, "Required terminfo capability 'cup' not defined\n");
return -1;
}
ti->AMflag = tigetflag("am") == 1;
if(!ti->AMflag){
fprintf(stderr, "Required terminfo capability 'am' not defined\n");
return -1;
}
term_verify_seq(&ti->civis, "civis");
term_verify_seq(&ti->cnorm, "cnorm");
term_verify_seq(&ti->standout, "smso"); // smso / rmso
term_verify_seq(&ti->uline, "smul");
term_verify_seq(&ti->reverse, "reverse");
term_verify_seq(&ti->blink, "blink");
term_verify_seq(&ti->dim, "dim");
term_verify_seq(&ti->bold, "bold");
term_verify_seq(&ti->italics, "sitm");
term_verify_seq(&ti->italoff, "ritm");
term_verify_seq(&ti->sgr, "sgr");
term_verify_seq(&ti->sgr0, "sgr0");
term_verify_seq(&ti->op, "op");
term_verify_seq(&ti->oc, "oc");
term_verify_seq(&ti->home, "home");
term_verify_seq(&ti->clearscr, "clear");
term_verify_seq(&ti->cleareol, "el");
term_verify_seq(&ti->clearbol, "el1");
term_verify_seq(&ti->cuu, "cuu"); // move N up
term_verify_seq(&ti->cud, "cud"); // move N down
term_verify_seq(&ti->hpa, "hpa");
term_verify_seq(&ti->vpa, "vpa");
term_verify_seq(&ti->cuf, "cuf"); // n non-destructive spaces
term_verify_seq(&ti->cub, "cub"); // n non-destructive backspaces
term_verify_seq(&ti->cuf1, "cuf1"); // non-destructive space
term_verify_seq(&ti->cub1, "cub1"); // non-destructive backspace
term_verify_seq(&ti->smkx, "smkx"); // set application mode
if(ti->smkx){
if(putp(tiparm(ti->smkx)) != OK){
fprintf(stderr, "Error entering application mode\n");
return -1;
}
}
// Some terminals cannot combine certain styles with colors. Don't advertise
// support for the style in that case.
int nocolor_stylemask = tigetnum("ncv");
if(nocolor_stylemask > 0){
if(nocolor_stylemask & WA_STANDOUT){ // ncv is composed of terminfo bits, not ours
ti->standout = NULL;
}
if(nocolor_stylemask & WA_UNDERLINE){
ti->uline = NULL;
}
if(nocolor_stylemask & WA_REVERSE){
ti->reverse = NULL;
}
if(nocolor_stylemask & WA_BLINK){
ti->blink = NULL;
}
if(nocolor_stylemask & WA_DIM){
ti->dim = NULL;
}
if(nocolor_stylemask & WA_BOLD){
ti->bold = NULL;
}
if(nocolor_stylemask & WA_ITALIC){
ti->italics = NULL;
}
}
term_verify_seq(&ti->getm, "getm"); // get mouse events
// Not all terminals support setting the fore/background independently
term_verify_seq(&ti->setaf, "setaf");
term_verify_seq(&ti->setab, "setab");
term_verify_seq(&ti->smkx, "smkx");
term_verify_seq(&ti->rmkx, "rmkx");
return 0;
}
Loading…
Cancel
Save