mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
add ncdirect_detected_terminal() and notcurses_detected_terminal() #1759
This commit is contained in:
parent
e838209d21
commit
d695a8206f
1
NEWS.md
1
NEWS.md
@ -32,6 +32,7 @@ rearrangements of Notcurses.
|
||||
could be in another pile. An error will instead be returned.
|
||||
* Fixed a bug in `ncdirect_box()` where default/palette-indexed colors
|
||||
weren't properly used on the top and bottom borders.
|
||||
* Added `notcurses_detected_terminal()` and `ncdirect_detected_terminal()`.
|
||||
|
||||
* 2.3.2 (2021-06-03)
|
||||
* Fixed a bug affecting certain scalings of `ncvisual` objects created from
|
||||
|
@ -10,6 +10,8 @@ notcurses_capabilities - runtime capability detection
|
||||
|
||||
**#include <notcurses/notcurses.h>**
|
||||
|
||||
**const char* notcurses_detected_terminal(const struct notcurses* ***nc***);**
|
||||
|
||||
**unsigned notcurses_supported_styles(const struct notcurses* ***nc***);**
|
||||
|
||||
**unsigned notcurses_palette_size(const struct notcurses* ***nc***);**
|
||||
@ -38,6 +40,16 @@ notcurses_capabilities - runtime capability detection
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
**notcurses_detected_terminal** returns a free-form string describing
|
||||
the detected terminal. Terminal detection takes into account any
|
||||
specified terminal database (see **notcurses_init(3)**), the **TERM**,
|
||||
**TERM_PROGRAM**, and **TERM_PROGRAM_VERSION** environment variables,
|
||||
the response to a **XTGETTCAP[TN]** Device Control String, the response
|
||||
to Primary, Secondary, and Tertiary Send Device Attributes control
|
||||
sequences, and the phase of the moon. You should not build logic around
|
||||
this response; all relevant properties of the terminal ought be
|
||||
abstracted by Notcurses. This is only made available for diagnostics.
|
||||
|
||||
**notcurses_supported_styles** returns a bitmask representing those styles
|
||||
for which the terminal advertises support.
|
||||
|
||||
|
@ -72,6 +72,8 @@ notcurses_direct - minimal notcurses instances for styling text
|
||||
|
||||
**int ncdirect_printf_aligned(struct ncdirect* ***n***, int ***y***, ncalign_e ***align***, const char* ***fmt***, ***...***);**
|
||||
|
||||
**const char* ncdirect_detected_terminal(const struct ncdirect* ***n***);**
|
||||
|
||||
**bool ncdirect_canopen_images(const struct ncdirect* ***n***);**
|
||||
|
||||
**bool ncdirect_canutf8(const struct ncdirect* ***n***);**
|
||||
|
@ -235,6 +235,9 @@ API int ncdirect_cursor_pop(struct ncdirect* n)
|
||||
API int ncdirect_clear(struct ncdirect* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
API const char* ncdirect_detected_terminal(const struct ncdirect* n)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Can we load images? This requires being built against FFmpeg/OIIO.
|
||||
API bool ncdirect_canopen_images(const struct ncdirect* n)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
@ -1242,21 +1242,29 @@ API bool ncplane_set_scrolling(struct ncplane* n, bool scrollp);
|
||||
// (NCSTYLE_UNDERLINE, NCSTYLE_BOLD, etc.) The attribute is only
|
||||
// indicated as supported if the terminal can support it together with color.
|
||||
// For more information, see the "ncv" capability in terminfo(5).
|
||||
API unsigned notcurses_supported_styles(const struct notcurses* nc);
|
||||
API unsigned notcurses_supported_styles(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Returns the number of simultaneous colors claimed to be supported, or 1 if
|
||||
// there is no color support. Note that several terminal emulators advertise
|
||||
// more colors than they actually support, downsampling internally.
|
||||
API unsigned notcurses_palette_size(const struct notcurses* nc);
|
||||
API unsigned notcurses_palette_size(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
API const char* notcurses_detected_terminal(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Can we directly specify RGB values per cell, or only use palettes?
|
||||
API bool notcurses_cantruecolor(const struct notcurses* nc);
|
||||
API bool notcurses_cantruecolor(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Can we fade? Fading requires either the "rgb" or "ccc" terminfo capability.
|
||||
API bool notcurses_canfade(const struct notcurses* nc);
|
||||
API bool notcurses_canfade(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Can we set the "hardware" palette? Requires the "ccc" terminfo capability.
|
||||
API bool notcurses_canchangecolor(const struct notcurses* nc);
|
||||
API bool notcurses_canchangecolor(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Can we load images? This requires being built against FFmpeg/OIIO.
|
||||
API bool notcurses_canopen_images(const struct notcurses* nc);
|
||||
@ -1265,24 +1273,30 @@ API bool notcurses_canopen_images(const struct notcurses* nc);
|
||||
API bool notcurses_canopen_videos(const struct notcurses* nc);
|
||||
|
||||
// Is our encoding UTF-8? Requires LANG being set to a UTF8 locale.
|
||||
API bool notcurses_canutf8(const struct notcurses* nc);
|
||||
API bool notcurses_canutf8(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Can we reliably use Unicode halfblocks?
|
||||
API bool notcurses_canhalfblock(const struct notcurses* nc);
|
||||
API bool notcurses_canhalfblock(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Can we reliably use Unicode quadrants?
|
||||
API bool notcurses_canquadrant(const struct notcurses* nc);
|
||||
API bool notcurses_canquadrant(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Can we reliably use Unicode 13 sextants?
|
||||
API bool notcurses_cansextant(const struct notcurses* nc);
|
||||
API bool notcurses_cansextant(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Can we reliably use Unicode Braille?
|
||||
API bool notcurses_canbraille(const struct notcurses* nc);
|
||||
API bool notcurses_canbraille(const struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// This function must successfully return before NCBLIT_PIXEL is available.
|
||||
// Returns -1 on error, 0 for no support, or 1 if pixel output is supported.
|
||||
// Must not be called concurrently with either input or rasterization.
|
||||
API int notcurses_check_pixel_support(struct notcurses* nc);
|
||||
API int notcurses_check_pixel_support(struct notcurses* nc)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// whenever a new field is added here, ensure we add the proper rule to
|
||||
// notcurses_stats_reset(), so that values are preserved in the stash stats.
|
||||
|
@ -32,8 +32,8 @@ typedef struct fetched_info {
|
||||
char* kernel; // strdup(uname(2)->name)
|
||||
char* kernver; // strdup(uname(2)->version);
|
||||
char* desktop; // getenv("XDG_CURRENT_DESKTOP")
|
||||
char* shell; // getenv("SHELL")
|
||||
char* term; // getenv("TERM")
|
||||
const char* shell; // getenv("SHELL")
|
||||
const char* term; // ncdirect_detected_terminal()
|
||||
char* lang; // getenv("LANG")
|
||||
int dimy, dimx; // extracted from xrandr
|
||||
char* cpu_model; // FIXME don't handle hetero setups yet
|
||||
@ -49,10 +49,10 @@ free_fetched_info(fetched_info* fi){
|
||||
}
|
||||
|
||||
static int
|
||||
fetch_env_vars(fetched_info* fi){
|
||||
fetch_env_vars(struct ncdirect* nc, fetched_info* fi){
|
||||
fi->desktop = getenv("XDG_CURRENT_DESKTOP");
|
||||
fi->shell = getenv("SHELL");
|
||||
fi->term = getenv("TERM");
|
||||
fi->term = ncdirect_detected_terminal(nc);
|
||||
fi->lang = getenv("LANG");
|
||||
return 0;
|
||||
}
|
||||
@ -628,7 +628,7 @@ ncneofetch(struct ncdirect* nc){
|
||||
const bool launched = !pthread_create(&tid, NULL, display_thread, &display_marshal);
|
||||
unix_gethostname(&fi);
|
||||
unix_getusername(&fi);
|
||||
fetch_env_vars(&fi);
|
||||
fetch_env_vars(nc, &fi);
|
||||
fetch_x_props(&fi);
|
||||
if(kern == NCNEO_LINUX){
|
||||
fetch_cpu_info(&fi);
|
||||
|
@ -1368,3 +1368,7 @@ int ncdirectf_geom(ncdirect* n, ncdirectf* frame,
|
||||
unsigned ncdirect_supported_styles(const ncdirect* nc){
|
||||
return term_supported_styles(&nc->tcache);
|
||||
}
|
||||
|
||||
const char* ncdirect_detected_terminal(const ncdirect* nc){
|
||||
return nc->tcache.termname;
|
||||
}
|
||||
|
@ -858,12 +858,12 @@ init_banner_warnings(const notcurses* nc, FILE* out){
|
||||
// unless the suppress_banner flag was set, print some version information and
|
||||
// (if applicable) warnings to stdout. we are not yet on the alternate screen.
|
||||
static void
|
||||
init_banner(const notcurses* nc, const char* shortname_term){
|
||||
init_banner(const notcurses* nc){
|
||||
if(!nc->suppress_banner){
|
||||
char prefixbuf[BPREFIXSTRLEN + 1];
|
||||
term_fg_palindex(nc, stdout, 50 % nc->tcache.colors);
|
||||
printf("\n notcurses %s by nick black et al", notcurses_version());
|
||||
printf(" on %s", shortname_term ? shortname_term : "?");
|
||||
printf(" on %s", nc->tcache.termname ? nc->tcache.termname : "?");
|
||||
term_fg_palindex(nc, stdout, 12 % nc->tcache.colors);
|
||||
if(nc->tcache.cellpixy && nc->tcache.cellpixx){
|
||||
printf("\n %d rows (%dpx) %d cols (%dpx) (%sB) %zuB crend %d colors",
|
||||
@ -1127,7 +1127,7 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){
|
||||
goto err;
|
||||
}
|
||||
ret->rstate.x = ret->rstate.y = -1;
|
||||
init_banner(ret, shortname_term);
|
||||
init_banner(ret);
|
||||
// flush on the switch to alternate screen, lest initial output be swept away
|
||||
const char* clearscr = get_escape(&ret->tcache, ESCAPE_CLEAR);
|
||||
if(ret->ttyfd >= 0){
|
||||
@ -1652,6 +1652,10 @@ unsigned notcurses_palette_size(const notcurses* nc){
|
||||
return nc->tcache.colors;
|
||||
}
|
||||
|
||||
const char* notcurses_detected_terminal(const notcurses* nc){
|
||||
return nc->tcache.termname;
|
||||
}
|
||||
|
||||
bool notcurses_cantruecolor(const notcurses* nc){
|
||||
return nc->tcache.RGBflag;
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd){
|
||||
}
|
||||
ti->braille = true; // most everyone has working braille, even from fonts
|
||||
if(strstr(termname, "kitty")){ // kitty (https://sw.kovidgoyal.net/kitty/)
|
||||
termname = "Kitty";
|
||||
// see https://sw.kovidgoyal.net/kitty/protocol-extensions.html
|
||||
// FIXME detect the actual default background color; this assumes it to
|
||||
// be RGB(0, 0, 0) (the default). we could also just set it, i guess.
|
||||
@ -96,20 +97,25 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd){
|
||||
ti->RGBflag = true;
|
||||
setup_kitty_bitmaps(ti, fd);
|
||||
}else if(strstr(termname, "alacritty")){
|
||||
termname = "Alacritty";
|
||||
ti->alacritty_sixel_hack = true;
|
||||
ti->quadrants = true;
|
||||
// ti->sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */
|
||||
ti->RGBflag = true;
|
||||
}else if(strstr(termname, "vte") || strstr(termname, "gnome") || strstr(termname, "xfce")){
|
||||
termname = "VTE";
|
||||
ti->sextants = true; // VTE has long enjoyed good sextant support
|
||||
ti->quadrants = true;
|
||||
}else if(strncmp(termname, "foot", 4) == 0){
|
||||
termname = "foot";
|
||||
ti->sextants = true;
|
||||
ti->quadrants = true;
|
||||
ti->RGBflag = true;
|
||||
}else if(strncmp(termname, "st", 2) == 0){
|
||||
termname = "simple terminal";
|
||||
// st had neithersextants nor quadrants last i checked (0.8.4)
|
||||
}else if(strstr(termname, "mlterm")){
|
||||
termname = "MLterm";
|
||||
ti->quadrants = true; // good quadrants, no sextants as of 3.9.0
|
||||
ti->sprixel_cursor_hack = true;
|
||||
}else if(strstr(termname, "xterm")){
|
||||
@ -117,7 +123,21 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd){
|
||||
// of people using xterm when they shouldn't be, or even real database
|
||||
// entries like "xterm-kitty" (if we don't catch them above), giving a
|
||||
// pretty minimal (but safe) experience. set your TERM correctly!
|
||||
// wezterm wants a TERM of xterm-256color, and identifies itself based
|
||||
// off TERM_PROGRAM and TERM_PROGRAM_VERSION.
|
||||
const char* term_program = getenv("TERM_PROGRAM");
|
||||
if(term_program && strcmp(term_program, "WezTerm") == 0){
|
||||
termname = "WezTerm";
|
||||
ti->quadrants = true;
|
||||
const char* termver = getenv("TERM_PROGRAM_VERSION");
|
||||
if(termver && strcmp(termver, "20210610") >= 0){
|
||||
ti->sextants = true; // good sextants as of 2021-06-10
|
||||
}
|
||||
}else{
|
||||
termname = "XTerm";
|
||||
}
|
||||
}else if(strcmp(termname, "linux") == 0){
|
||||
termname = "Linux console";
|
||||
ti->braille = false; // no braille, no sextants in linux console
|
||||
// FIXME if the NCOPTION_NO_FONT_CHANGES, this isn't true
|
||||
// FIXME we probably want to do this based off ioctl()s in linux.c
|
||||
@ -131,6 +151,7 @@ apply_term_heuristics(tinfo* ti, const char* termname, int fd){
|
||||
if(wcwidth(L'🬸') < 0){
|
||||
ti->sextants = false;
|
||||
}
|
||||
ti->termname = termname;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -118,6 +118,7 @@ typedef struct tinfo {
|
||||
int (*pixel_shutdown)(int fd); // called during context shutdown
|
||||
int (*pixel_clear_all)(int fd); // called during startup, kitty only
|
||||
int sprixel_scale_height; // sprixel must be a multiple of this many rows
|
||||
const char* termname; // determined terminal name
|
||||
struct termios tpreserved; // terminal state upon entry
|
||||
ncinputlayer input; // input layer
|
||||
bool bitmap_supported; // do we support bitmaps (post pixel_query_done)?
|
||||
|
Loading…
x
Reference in New Issue
Block a user