17#include "compat/compat.h"
25 *major = NOTCURSES_VERNUM_MAJOR;
26 *minor = NOTCURSES_VERNUM_MINOR;
27 *patch = NOTCURSES_VERNUM_PATCH;
28 *tweak = atoi(NOTCURSES_VERSION_TWEAK);
63 if((esc = get_escape(ti,
ESCAPE_OP)) && fbuf_emit(f, esc)){
66 if((esc = get_escape(ti,
ESCAPE_SGR0)) && fbuf_emit(f, esc)){
82 loginfo(
"restoring palette via xtpopcolors");
83 if(fbuf_emit(f, esc)){
101 if(fbuf_emit(f, tiparm(esc, z,
r, g, b)) < 0){
105 }
else if((esc = get_escape(ti,
ESCAPE_OC))){
107 if(fbuf_emit(f, esc)){
111 logwarn(
"no method known to restore palette");
121notcurses_stop_minimal(
void* vnc,
void** altstack,
int errret){
138 if(cnorm && fbuf_emit(f, cnorm)){
141 if(fbuf_flush(f, nc->
ttyfp)){
145 ret |= notcurses_mice_disable(nc);
176 logdebug(
"restored terminal, returning %d", ret);
180static const char NOTCURSES_VERSION[] =
181 NOTCURSES_VERSION_MAJOR
"."
182 NOTCURSES_VERSION_MINOR
"."
183 NOTCURSES_VERSION_PATCH;
186 return NOTCURSES_VERSION;
190 void* ret =
n->userptr;
207 if(
n->y >=
n->leny ||
n->x >=
n->lenx){
232 if((
unsigned)
y >=
n->leny || (
unsigned)
x >=
n->lenx){
243 return strdup(
n->sprite->glyph.buf);
245 const nccell* yx = &
n->fb[nfbcellidx(
n,
y,
x)];
247 if(nccell_wide_right_p(yx)){
250 char* ret = nccell_extract(
n, yx, stylemask, channels);
255 if(strcmp(ret,
"") == 0){
257 ret = nccell_strdup(
n, &
n->basecell);
262 *stylemask =
n->basecell.stylemask;
275 logerror(
"invoked on a sprixel plane");
292 if((
unsigned)
y >=
n->leny || (
unsigned)
x >=
n->lenx){
296 nccell* targ = ncplane_cell_ref_yx(
n,
y,
x);
320 int margin_b,
unsigned* cgeo_changed,
unsigned* pgeo_changed){
324 if(tcache->
ttyfd < 0){
335 unsigned rowsafe, colsafe;
338 rowsafe = tcache->
dimy;
342 colsafe = tcache->
dimx;
354 if(tcache->linux_fb_fd >= 0){
356 cpixy = tcache->
pixy / *rows;
357 cpixx = tcache->
pixx / *cols;
366 tcache->
pixy = ws.ws_ypixel;
367 tcache->
pixx = ws.ws_xpixel;
371 cpixy = ws.ws_row ? tcache->
pixy / ws.ws_row : 0;
372 cpixx = ws.ws_col ? tcache->
pixx / ws.ws_col : 0;
386 CONSOLE_SCREEN_BUFFER_INFO csbi;
414 if(GetConsoleScreenBufferInfo(tcache->outhandle, &csbi)){
415 *cols = csbi.dwSize.X;
416 *rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
422 if(tcache->
dimy != *rows){
423 tcache->
dimy = *rows;
426 if(tcache->
dimx != *cols){
427 tcache->
dimx = *cols;
431 int sixelrows = *rows - 1;
448 while(
n->sprixelcache){
451 n->sprixelcache = tmp;
457ncpile_destroy(
ncpile* pile){
478 ncpile_destroy(ncplane_pile(p));
479 pthread_mutex_unlock(&nc->
pilelock);
487 logdebug(
"calling widget destructor %p(%p)", wdestruct, w);
495 egcpool_dump(&p->
pool);
507 ncpile* ret = malloc(
sizeof(*ret));
518 ncplane_pile(nc->
stdplane)->prev = ret;
539static inline size_t ncplane_sizeof_cellarray(
size_t rows,
size_t cols)
543 if( ! rows || (cols > SIZE_MAX / rows))
563 logwarn(
"provided unsupported flags %016" PRIx64, nopts->
flags);
567 logerror(
"alignment requires a parent plane");
572 if(nopts->
rows != 0 || nopts->
cols != 0){
573 logerror(
"geometry specified with margins (r=%u, c=%u)",
578 ncplane* p = malloc(
sizeof(*p));
591 p->
leny = ncplane_dim_y(
n);
592 p->
lenx = ncplane_dim_x(
n);
594 notcurses_term_dim_yx(nc, &p->
leny, &p->
lenx);
607 size_t fbsize = ncplane_sizeof_cellarray(p->
leny, p->
lenx);
608 if(!fbsize || (p->
fb = calloc(fbsize,
sizeof(
struct nccell))) ==
NULL){
609 logerror(
"error allocating cellmatrix (r=%u, c=%u)",
630 p->
absx = ncplane_halign(
n, nopts->
x, nopts->
cols);
637 p->
absy = ncplane_valign(
n, nopts->
y, nopts->
rows);
644 n->blist->bprev = &p->
bnext;
654 egcpool_init(&p->
pool);
664 if( (p->
pile = pile) ){
679 pthread_mutex_unlock(&nc->
pilelock);
681 loginfo(
"created new %ux%u plane \"%s\" @ %dx%d",
689create_initial_ncplane(
notcurses* nc,
int dimy,
int dimx){
729 }
else if((
unsigned)
x >=
n->lenx){
730 logerror(
"target x %d >= width %u",
x,
n->lenx);
740 }
else if((
unsigned)
y >=
n->leny){
741 logerror(
"target y %d >= height %u",
y,
n->leny);
746 if(cursor_invalid_p(
n)){
747 logerror(
"invalid cursor following move (%d/%d)",
n->y,
n->x);
754 if((
int)
n->y +
y == -1){
757 }
else if((
int)
n->x +
x == -1){
766 const int placey =
n->absy;
767 const int placex =
n->absx;
783 size_t fbsize =
sizeof(*
n->fb) * dimx * dimy;
784 if(egcpool_dup(&
newn->pool, &
n->pool)){
788 memmove(
newn->fb,
n->fb, fbsize);
793 newn->halign =
n->halign;
797 newn->basecell =
n->basecell;
806 for(
struct ncplane* child =
n->
blist ; child ; child = child->bnext){
808 ret |= child->resizecb(child);
816ncplane_resize_internal_check(
const ncplane*
n,
int keepy,
int keepx,
817 unsigned keepleny,
unsigned keeplenx,
818 int yoff,
int xoff,
unsigned ylen,
unsigned xlen,
820 if(keepy < 0 || keepx < 0){
821 logerror(
"can't retain negative offset %dx%d", keepy, keepx);
824 if((!keepleny && keeplenx) || (keepleny && !keeplenx)){
825 logerror(
"can't retain null dimension %ux%u", keepleny, keeplenx);
830 logerror(
"can't map in y dimension: %u < %u",
ylen, keepleny);
834 logerror(
"can't map in x dimension: %u < %u",
xlen, keeplenx);
842 if(keepleny + keepy > *
rows){
843 logerror(
"can't keep %u@%d rows from %u", keepleny, keepy, *
rows);
846 if(keeplenx + keepx > *
cols){
847 logerror(
"can't keep %u@%d cols from %u", keeplenx, keepx, *
cols);
850 loginfo(
"%ux%u @ %d/%d → %u/%u @ %d/%d (want %ux%u@%d/%d)", *
rows, *
cols,
851 n->absy,
n->absx,
ylen,
xlen,
n->absy + keepy + yoff,
n->absx + keepx + xoff,
852 keepleny, keeplenx, keepy, keepx);
858 unsigned keepleny,
unsigned keeplenx,
862 if(ncplane_resize_internal_check(
n, keepy, keepx, keepleny, keeplenx,
867 if(
n->absy ==
n->absy + keepy &&
n->absx ==
n->absx + keepx &&
879 int keptarea = keepleny * keeplenx;
881 size_t fbsize =
sizeof(
nccell) * newarea;
899 if(
cols ==
xlen &&
cols == keeplenx && keepleny && !keepy){
904 if(
n->leny > keepleny){
905 for(
unsigned y = keepleny ;
y <
n->leny ; ++
y){
906 for(
unsigned x = 0 ;
x <
n->lenx ; ++
x){
911 if((fb = realloc(
n->fb, fbsize)) ==
NULL){
916 if((fb = malloc(fbsize)) ==
NULL){
921 loginfo(
"tam realloc to %d entries", newarea);
923 tament* tmptam = realloc(
n->tam,
sizeof(*tmptam) * newarea);
931 if(newarea > oldarea){
932 memset(
n->tam + oldarea, 0,
sizeof(*
n->tam) * (newarea - oldarea));
946 const int oldabsy =
n->absy;
950 n->absy += keepy + yoff;
951 n->absx += keepx + xoff;
956 memset(fb, 0,
sizeof(*fb) * newarea);
957 egcpool_dump(&
n->pool);
958 }
else if(!preserved){
962 unsigned tozorch = (
ylen - keepleny) *
xlen *
sizeof(*fb);
964 unsigned zorchoff = keepleny *
xlen;
965 memset(fb + zorchoff, 0, tozorch);
972 for(
unsigned itery = 0 ; itery <
ylen ; ++itery){
973 int truey = itery +
n->absy;
974 int sourceoffy = truey - oldabsy;
977 if(sourceoffy < keepy || sourceoffy >= keepy + (
int)keepleny){
979 memset(fb + (itery *
xlen), 0,
sizeof(*fb) *
xlen);
981 int copyoff = itery *
xlen;
985 memset(fb + copyoff, 0,
sizeof(*fb) * -xoff);
989 const int sourceidx = nfbcellidx(
n, sourceoffy, keepx);
991 memcpy(fb + copyoff, preserved + sourceidx,
sizeof(*fb) * keeplenx);
994 unsigned perline =
xlen - copied;
995 for(
unsigned x = copyoff ;
x <
n->lenx ; ++
x){
998 memset(fb + copyoff, 0,
sizeof(*fb) * perline);
1010 unsigned keepleny,
unsigned keeplenx,
1026 logerror(
"won't destroy standard plane");
1030 loginfo(
"destroying %dx%d plane \"%s\" @ %dx%d",
1039 }
else if(ncp->
bnext){
1060 ncplane_pile(ncp)->top = ncp->
below;
1065 ncplane_pile(ncp)->bottom = ncp->
above;
1076 logerror(
"won't destroy standard plane");
1099 if(setlocale(LC_ALL,
".UTF8") ==
NULL){
1100 logwarn(
"couldn't set LC_ALL to utf8");
1103 const char* encoding = nl_langinfo(CODESET);
1104 if(encoding && encoding_is_utf8(encoding)){
1107 const char* lang = getenv(
"LANG");
1109 if(lang && (!strcmp(lang,
"C") || !strcmp(lang,
"POSIX"))){
1110 loginfo(
"LANG was explicitly set to %s, not changing locale", lang);
1114 if(setlocale(LC_ALL,
"") ==
NULL){
1115 logwarn(
"setting locale based on LANG failed");
1118 encoding = nl_langinfo(CODESET);
1119 if(encoding && encoding_is_utf8(encoding)){
1120 loginfo(
"set locale from LANG; client should call setlocale(2)!");
1123 setlocale(LC_CTYPE,
"C.UTF-8");
1124 encoding = nl_langinfo(CODESET);
1125 if(encoding && encoding_is_utf8(encoding)){
1126 loginfo(
"forced UTF-8 encoding; client should call setlocale(2)!");
1133recursive_lock_init(pthread_mutex_t *lock){
1135#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
1137 pthread_mutexattr_t attr;
1138 if(pthread_mutexattr_init(&attr)){
1142 pthread_mutexattr_destroy(&attr);
1145 if(pthread_mutex_init(lock, &attr)){
1146 pthread_mutexattr_destroy(&attr);
1149 pthread_mutexattr_destroy(&attr);
1152#undef PTHREAD_MUTEX_RECURSIVE_NP
1174 if(fwide(fp, 0) > 0){
1175 fprintf(stderr,
"error: output stream is wide-oriented");
1182 memset(ret, 0,
sizeof(*ret));
1185 fprintf(stderr,
"warning: unknown Notcurses options %016" PRIu64,
opts->
flags);
1205 const char* encoding = nl_langinfo(CODESET);
1206 if(encoding && encoding_is_utf8(encoding)){
1210 if(encoding && (strcmp(encoding,
"ANSI_X3.4-1968") &&
1211 strcmp(encoding,
"US-ASCII") &&
1212 strcmp(encoding,
"ASCII"))){
1213 fprintf(stderr,
"encoding (\"%s\") was neither ANSI_X3.4-1968 nor UTF-8, refusing to start\n did you call setlocale()?\n",
1214 encoding ? encoding :
"none found");
1223 egcpool_init(&ret->
pool);
1225 fprintf(stderr,
"invalid loglevel %d", ret->
loglevel);
1229 if(recursive_lock_init(&ret->
pilelock)){
1230 fprintf(stderr,
"couldn't initialize pile mutex");
1235 pthread_mutex_destroy(&ret->
pilelock);
1257 if(fbuf_init(&ret->
rstate.
f)){
1258 pthread_mutex_destroy(&ret->
pilelock);
1259 pthread_mutex_destroy(&ret->
stats.
lock);
1265 notcurses_stop_minimal)){
1267 pthread_mutex_destroy(&ret->
pilelock);
1268 pthread_mutex_destroy(&ret->
stats.
lock);
1287 cursory, cursorx, &ret->
stats,
1293 pthread_mutex_destroy(&ret->
pilelock);
1294 pthread_mutex_destroy(&ret->
stats.
lock);
1309 if(*cursory < 0 || *cursorx < 0){
1312 logwarn(
"couldn't preserve cursor");
1318 if(*cursory >= 0 && *cursorx >= 0){
1319 if(goto_location(ret, &ret->
rstate.
f, *cursory, *cursorx,
NULL)){
1324 unsigned dimy, dimx, cgeo, pgeo;
1332 if((ret->
stdplane = create_initial_ncplane(ret, dimy, dimx)) ==
NULL){
1333 logpanic(
"couldn't create the initial plane (bad margins?)");
1341 if(cinvis && fbuf_emit(&ret->
rstate.
f, cinvis) < 0){
1346 if(pushcolors && fbuf_emit(&ret->
rstate.
f, pushcolors)){
1357 unsigned uendy, uendx;
1395 logpanic(
"alas, you will not be going to space today.");
1396 notcurses_stop_minimal(ret, &altstack, -1);
1402 del_curterm(cur_term);
1403 pthread_mutex_destroy(&ret->
stats.
lock);
1404 pthread_mutex_destroy(&ret->
pilelock);
1414 bool sawstdplane =
false;
1419 logdebug(
"killing plane %p, next is %p", p, tmp);
1443 ncpile_drop(nc, &p);
1445 pthread_mutex_unlock(&nc->
pilelock);
1455 ret |= notcurses_stop_minimal(nc, &altstack, 0);
1463 fbuf_finalize(&nc->
rstate.
f, stdout);
1472 egcpool_dump(&nc->
pool);
1482 del_curterm(cur_term);
1484 ret |= pthread_mutex_destroy(&nc->
stats.
lock);
1485 ret |= pthread_mutex_destroy(&nc->
pilelock);
1494 return ncchannels_channels(
n->channels);
1498 ncchannels_set_channels(&
n->channels,
channels);
1502 return n->stylemask;
1506 ncchannels_set_fg_default(&
n->channels);
1510 ncchannels_set_bg_default(&
n->channels);
1514 ncchannels_set_bg_rgb8_clipped(&
n->channels,
r, g, b);
1518 return ncchannels_set_bg_rgb8(&
n->channels,
r, g, b);
1522 ncchannels_set_fg_rgb8_clipped(&
n->channels,
r, g, b);
1526 return ncchannels_set_fg_rgb8(&
n->channels,
r, g, b);
1530 return ncchannels_set_fg_rgb(&
n->channels, channel);
1534 return ncchannels_set_bchannel(&
n->channels, channel);
1538 return ncchannels_set_fchannel(&
n->channels, channel);
1542 return ncchannels_set_bg_rgb(&
n->channels, channel);
1546 return ncchannels_set_fg_alpha(&
n->channels, alpha);
1550 return ncchannels_set_bg_alpha(&
n->channels, alpha);
1554 return ncchannels_set_fg_palindex(&
n->channels,
idx);
1558 return ncchannels_set_bg_palindex(&
n->channels,
idx);
1562 if(nccell_wide_right_p(
c)){
1577 if(cell_simple_p(
c)){
1580 return egcpool_extended_gcluster(&
n->pool,
c);
1591 if( (
n->below->above =
n->above) ){
1592 n->above->below =
n->below;
1605 if(p != ncplane_pile(
above)){
1638 if( (
n->above->below =
n->below) ){
1639 n->below->above =
n->above;
1644 if( (
n->below = p->
top) ){
1652 if(p != ncplane_pile(
below)){
1689 if(ncplane_descendant_p(
above,
n)){
1697 const ncplane* topmost = targ;
1701 if(ncplane_descendant_p(
below,
n)){
1723 if(ncplane_descendant_p(
below,
n)){
1731 const ncplane* bottommost = targ;
1735 if(ncplane_descendant_p(
above,
n)){
1764 if(
n->y ==
n->leny - 1){
1767 ncplane_resize_simple(
n,
n->leny + 1,
n->lenx);
1775 ncplane_pile(
n)->scrolls++;
1777 n->logrow = (
n->logrow + 1) %
n->leny;
1778 nccell* row =
n->fb + nfbcellidx(
n,
n->y, 0);
1779 for(
unsigned clearx = 0 ; clearx <
n->lenx ; ++clearx){
1782 memset(row, 0,
sizeof(*row) *
n->lenx);
1785 if(ncplanes_intersect_p(
n,
c)){
1786 ncplane_move_rel(
c, -1, 0);
1797 logerror(
"can't scroll %d on non-scrolling plane",
r);
1817 if(!ncplane_descendant_p(child,
n)){
1818 logerror(
"not a descendant of specified plane");
1826 int chend =
ncplane_abs_y(child) + ncplane_dim_y(child) - 1;
1827 if(chend <= parend){
1830 int r = chend - parend;
1838 int bytes = utf8_egc_len(gcluster, &cols);
1839 return pool_load_direct(&
n->pool,
c, gcluster, bytes, cols);
1848ncplane_put(
ncplane*
n,
int y,
int x,
const char*
egc,
int cols,
1851 logerror(
"can't write [%s] to sprixelated plane",
egc);
1856 if(is_control_egc((
const unsigned char*)
egc, bytes)){
1861 logerror(
"rejecting newline on non-scrolling plane");
1864 }
else if(*
egc !=
'\t'){
1865 logerror(
"rejecting %dB control character", bytes);
1873 bool linesend =
false;
1878 if(
n->x + cols - 1 >=
n->lenx){
1883 if((
unsigned)
x + cols - 1 >=
n->lenx){
1887 bool scrolled =
false;
1892 }
else if(
n->autogrow){
1893 ncplane_resize_simple(
n,
n->leny,
n->lenx + cols);
1895 logerror(
"target x %d [%.*s] > length %d",
n->x, bytes,
egc,
n->lenx);
1911 nccell* targ = ncplane_cell_ref_yx(
n,
n->y,
n->x);
1917 while(nccell_wide_right_p(lmc)){
1918 nccell_obliterate(
n, &
n->fb[nfbcellidx(
n,
n->y,
idx)]);
1919 lmc = ncplane_cell_ref_yx(
n,
n->y, --
idx);
1922 int twidth = nccell_cols(lmc);
1924 twidth -=
n->x -
idx;
1925 while(--twidth > 0){
1926 nccell_obliterate(
n, &
n->fb[nfbcellidx(
n,
n->y,
n->x + twidth)]);
1937 if(
n->x + 1 >=
n->lenx){
1938 if(!
n->scrolling &&
n->autogrow){
1939 ncplane_resize_simple(
n,
n->leny,
n->lenx + (cols ? cols - 1 :
TABSTOP - 1));
1941 targ = ncplane_cell_ref_yx(
n,
n->y,
n->x);
1944 if(cell_load_direct(
n, targ,
" ", bytes, 1) < 0){
1948 if(cell_load_direct(
n, targ,
egc, bytes, cols) < 0){
1956 for(
int i = 1 ; i < cols ; ++i){
1957 nccell* candidate = &
n->fb[nfbcellidx(
n,
n->y,
n->x)];
1958 int off = nccell_cols(candidate);
1961 nccell_obliterate(
n, &
n->fb[nfbcellidx(
n,
n->y,
n->x + off)]);
1968 if(cell_load_direct(
n, candidate,
" ", bytes, 1) < 0){
1973 if(++
n->x >=
n->lenx){
1987 const int cols = nccell_cols(
c);
1991 char*
egc = nccell_strdup(
n,
c);
1993 logerror(
"couldn't duplicate cell");
2003 int bytes = utf8_egc_len(gclust, &cols);
2011 return ncplane_put(
n,
y,
x, gclust, cols,
n->stylemask,
n->channels, bytes);
2017 const nccell* targ = &
n->fb[nfbcellidx(
n,
n->y,
n->x)];
2020 int ret = ncplane_putchar(
n,
c);
2029 const nccell* targ = &
n->fb[nfbcellidx(
n,
n->y,
n->x)];
2032 int ret = ncplane_putwegc(
n, gclust, sbytes);
2041 const nccell* targ = &
n->fb[nfbcellidx(
n,
n->y,
n->x)];
2044 int ret = ncplane_putegc(
n, gclust, sbytes);
2051 if(
n->y >=
n->leny ||
n->x >=
n->lenx){
2054 const nccell* src = &
n->fb[nfbcellidx(
n,
n->y,
n->x)];
2055 memcpy(
c, src,
sizeof(*src));
2056 if(cell_simple_p(
c)){
2065 return term_supported_styles(&nc->
tcache);
2094 const size_t size = BUFSIZ;
2095 char* buf = malloc(size);
2100 va_copy(vacopy, ap);
2101 int ret = vsnprintf(buf, size, format, ap);
2107 if((
size_t)ret >= size){
2108 char* tmp = realloc(buf, ret + 1);
2115 vsprintf(buf, format, vacopy);
2126 int ret = ncplane_putstr_yx(
n,
y,
x,
r);
2132 const char* format, va_list ap){
2137 int ret = ncplane_putstr_aligned(
n,
y, align,
r);
2147 int ret = ncplane_putstr_stained(
n,
r);
2153 char* chopped = strndup(str, s);
2154 int ret = ncplane_putstr_aligned(
n,
y, align, chopped);
2160 uint64_t c1, uint64_t c2){
2165 unsigned ur, ug, ub;
2166 int r1, g1, b1, r2, g2, b2;
2167 int br1, bg1, bb1, br2, bg2, bb2;
2168 ncchannels_fg_rgb8(c1, &
ur, &ug, &ub);
2169 r1 =
ur; g1 = ug; b1 = ub;
2170 ncchannels_fg_rgb8(c2, &
ur, &ug, &ub);
2171 r2 =
ur; g2 = ug; b2 = ub;
2172 ncchannels_bg_rgb8(c1, &
ur, &ug, &ub);
2173 br1 =
ur; bg1 = ug; bb1 = ub;
2174 ncchannels_bg_rgb8(c2, &
ur, &ug, &ub);
2175 br2 =
ur; bg2 = ug; bb2 = ub;
2176 int deltr = r2 - r1;
2177 int deltg = g2 - g1;
2178 int deltb = b2 - b1;
2179 int deltbr = br2 - br1;
2180 int deltbg = bg2 - bg1;
2181 int deltbb = bb2 - bb1;
2187 bool fgdef =
false, bgdef =
false;
2188 if(ncchannels_fg_default_p(c1) && ncchannels_fg_default_p(c2)){
2191 if(ncchannels_bg_default_p(c1) && ncchannels_bg_default_p(c2)){
2194 for(ret = 0 ; ret <
len ; ++ret){
2195 int r = (deltr * (int)ret) / (int)
len + r1;
2196 int g = (deltg * (int)ret) / (int)
len + g1;
2197 int b = (deltb * (int)ret) / (int)
len + b1;
2198 int br = (deltbr * (int)ret) / (int)
len + br1;
2199 int bg = (deltbg * (int)ret) / (int)
len + bg1;
2200 int bb = (deltbb * (int)ret) / (int)
len + bb1;
2202 nccell_set_fg_rgb8(&dupc,
r, g, b);
2205 nccell_set_bg_rgb8(&dupc, br, bg, bb);
2207 if(ncplane_putc(
n, &dupc) <= 0){
2216 uint64_t c1, uint64_t c2){
2221 unsigned ur, ug, ub;
2222 int r1, g1, b1, r2, g2, b2;
2223 int br1, bg1, bb1, br2, bg2, bb2;
2224 ncchannels_fg_rgb8(c1, &
ur, &ug, &ub);
2225 r1 =
ur; g1 = ug; b1 = ub;
2226 ncchannels_fg_rgb8(c2, &
ur, &ug, &ub);
2227 r2 =
ur; g2 = ug; b2 = ub;
2228 ncchannels_bg_rgb8(c1, &
ur, &ug, &ub);
2229 br1 =
ur; bg1 = ug; bb1 = ub;
2230 ncchannels_bg_rgb8(c2, &
ur, &ug, &ub);
2231 br2 =
ur; bg2 = ug; bb2 = ub;
2232 int deltr = (r2 - r1) / ((
int)
len + 1);
2233 int deltg = (g2 - g1) / ((
int)
len + 1);
2234 int deltb = (b2 - b1) / ((
int)
len + 1);
2235 int deltbr = (br2 - br1) / ((
int)
len + 1);
2236 int deltbg = (bg2 - bg1) / ((
int)
len + 1);
2237 int deltbb = (bb2 - bb1) / ((
int)
len + 1);
2238 unsigned ypos, xpos;
2245 bool fgdef =
false, bgdef =
false;
2246 if(ncchannels_fg_default_p(c1) && ncchannels_fg_default_p(c2)){
2249 if(ncchannels_bg_default_p(c1) && ncchannels_bg_default_p(c2)){
2252 for(ret = 0 ; ret <
len ; ++ret){
2263 nccell_set_fg_rgb8(&dupc, r1, g1, b1);
2266 nccell_set_bg_rgb8(&dupc, br1, bg1, bb1);
2268 if(ncplane_putc(
n, &dupc) <= 0){
2279 const nccell* vl,
unsigned ystop,
unsigned xstop,
2281 unsigned yoff, xoff;
2284 if(ystop < yoff + 1){
2285 logerror(
"ystop (%u) insufficient for yoff (%d)", ystop, yoff);
2288 if(xstop < xoff + 1){
2289 logerror(
"xstop (%u) insufficient for xoff (%d)", xstop, xoff);
2292 unsigned ymax, xmax;
2295 if(xstop >= xmax || ystop >= ymax){
2296 logerror(
"boundary (%ux%u) beyond plane (%dx%d)", ystop, xstop, ymax, xmax);
2301 if(edges >= box_corner_needs(
ctlword)){
2302 if(ncplane_putc(
n,
ul) < 0){
2307 if(xstop - xoff >= 2){
2312 if(ncplane_hline(
n, hl, xstop - xoff - 1) < 0){
2323 if(edges >= box_corner_needs(
ctlword)){
2327 if(ncplane_putc(
n,
ur) < 0){
2343 if(ncplane_vline(
n, vl, ystop - yoff) < 0){
2357 if(ncplane_vline(
n, vl, ystop - yoff) < 0){
2366 if(edges >= box_corner_needs(
ctlword)){
2370 if(ncplane_putc(
n,
ll) < 0){
2375 if(xstop - xoff >= 2){
2380 if(ncplane_hline(
n, hl, xstop - xoff - 1) < 0){
2391 if(edges >= box_corner_needs(
ctlword)){
2395 if(ncplane_putc(
n,
lr) < 0){
2405move_bound_planes(
ncplane*
n,
int dy,
int dx){
2412 move_bound_planes(
n->blist, dy, dx);
2422 if(
n->boundto ==
n){
2426 dy = (
n->boundto->absy +
y) -
n->absy;
2427 dx = (
n->boundto->absx +
x) -
n->absx;
2435 move_bound_planes(
n->blist, dy, dx);
2441 if(
n->boundto ==
n){
2444 return n->absy -
n->boundto->absy;
2448 if(
n->boundto ==
n){
2451 return n->absx -
n->boundto->absx;
2465 loginfo(
"erasing %dx%d plane",
n->leny,
n->lenx);
2473 char*
egc = nccell_strdup(
n, &
n->basecell);
2474 memset(
n->fb, 0,
sizeof(*
n->fb) *
n->leny *
n->lenx);
2475 egcpool_dump(&
n->pool);
2478 n->basecell.gcluster = 0;
2491 if(ystart < 0 || xstart < 0){
2492 logerror(
"illegal start of erase (%d, %d)", ystart, xstart);
2495 if(ystart >= (
int)ncplane_dim_y(
n) || xstart >= (
int)ncplane_dim_x(
n)){
2496 logerror(
"illegal start of erase (%d, %d)", ystart, xstart);
2500 if(
xlen + 1 < -xstart){
2503 xstart = xstart +
xlen + 1;
2505 }
else if(
xlen == 0){
2507 xlen = ncplane_dim_x(
n);
2509 if(
xlen > (
int)ncplane_dim_x(
n) || xstart +
xlen > (
int)ncplane_dim_x(
n)){
2510 xlen = ncplane_dim_x(
n) - xstart;
2513 if(
ylen + 1 < -ystart){
2516 ystart = ystart +
ylen + 1;
2518 }
else if(
ylen == 0){
2520 ylen = ncplane_dim_y(
n);
2522 if(
ylen > (
int)ncplane_dim_y(
n) || ystart +
ylen > (
int)ncplane_dim_y(
n)){
2523 ylen = ncplane_dim_y(
n) - ystart;
2526 if(ystart == 0 && xstart == 0 &&
2527 ylen == (
int)ncplane_dim_y(
n) &&
xlen == (
int)ncplane_dim_x(
n)){
2535 loginfo(
"erasing %d/%d - %d/%d", ystart, xstart, ystart +
ylen, xstart +
xlen);
2536 for(
int y = ystart ;
y < ystart +
ylen ; ++
y){
2537 for(
int x = xstart ;
x < xstart +
xlen ; ++
x){
2539 nccell_init(&
n->fb[nfbcellidx(
n,
y,
x)]);
2546 return ncplane_pile(
n)->top;
2550 return ncplane_pile(
n)->bottom;
2571 memcpy(p, &nc->
palette,
sizeof(*p));
2578 if(!notcurses_canchangecolor(nc)){
2581 for(
size_t z = 0 ; z <
sizeof(p->
chans) /
sizeof(*p->
chans) ; ++z){
2602 if(yval >=
n->leny){
2611 if(xval >=
n->lenx){
2619 int* restrict
y,
int* restrict
x){
2621 dst = ncplane_stdplane_const(src);
2632 return ncplane_pile(
n)->nc;
2636 return ncplane_pile_const(
n)->nc;
2675 return n->name ? strdup(
n->name) :
NULL;
2687 if(
n->boundto ==
n){
2693 if(
absy + ncplane_dim_y(
n) > ncplane_dim_y(
n->boundto)){
2694 const int dy = (
absy + ncplane_dim_y(
n)) - ncplane_dim_y(
n->boundto);
2696 if(ncplane_move_rel(
n, -dy, 0)){
2701 if(
absx + ncplane_dim_x(
n) > ncplane_dim_x(
n->boundto)){
2702 const int dx = ncplane_dim_x(
n->boundto) - (
absx + ncplane_dim_x(
n));
2704 if(ncplane_move_rel(
n, 0, dx)){
2714 if(ncplane_move_rel(
n, -
absy, 0)){
2721 if(ncplane_move_rel(
n, 0, -
absx)){
2731 unsigned maxy, maxx;
2739 if((maxy -= (
n->margin_b + (
n->absy -
n->boundto->absy))) < 1){
2742 if((maxx -= (
n->margin_r + (
n->absx -
n->boundto->absx))) < 1){
2745 unsigned oldy, oldx;
2747 unsigned keepleny = oldy > maxy ? maxy : oldy;
2748 unsigned keeplenx = oldx > maxx ? maxx : oldx;
2752 int targy = maxy -
n->margin_b;
2753 int targx = maxx -
n->margin_b;
2754 loginfo(
"marg %d/%d, pdim %d/%d, move %d/%d",
n->margin_b,
n->margin_r, maxy, maxx, targy, targx);
2762 unsigned oldy, oldx;
2764 unsigned keepleny = oldy > rows ? rows : oldy;
2765 unsigned keeplenx = oldx > cols ? cols : oldx;
2772 logerror(
"can't realign a root plane");
2776 logerror(
"passed a non-aligned plane");
2781 xpos = ncplane_halign(parent,
n->
halign, ncplane_dim_x(
n));
2785 ypos = ncplane_valign(parent,
n->
valign, ncplane_dim_y(
n));
2799 logerror(
"won't reparent standard plane");
2802 if(
n->boundto == newparent){
2803 loginfo(
"won't reparent plane to itself");
2808 if(
n->boundto ==
n){
2814 child = child->
bnext;
2816 if( (lastlink->
bnext = ncplane_pile(
n)->roots) ){
2820 ncplane_pile(
n)->roots =
n->
blist;
2827 child = child->
bnext;
2844unsplice_zaxis_recursive(
ncplane*
n){
2846 if(ncplane_pile(
n)->top ==
n){
2847 ncplane_pile(
n)->top =
n->below;
2849 n->above->below =
n->below;
2851 if(ncplane_pile(
n)->bottom ==
n){
2852 ncplane_pile(
n)->bottom =
n->above;
2854 n->below->above =
n->above;
2856 for(
ncplane* child =
n->
blist ; child ; child = child->bnext){
2857 unsplice_zaxis_recursive(child);
2859 n->below =
n->above =
NULL;
2872 ncplane_pile(
n)->sprixelcache = s->
next;
2877 if( (s->
prev = prev) ){
2883 for(
ncplane* child =
n->
blist ; child ; child = child->bnext){
2884 unsplice_sprixels_recursive(child, prev);
2885 while(prev && prev->
next){
2895splice_zaxis_recursive(
ncplane*
n,
ncpile* p,
unsigned ocellpxy,
unsigned ocellpxx,
2896 unsigned ncellpxy,
unsigned ncellpxx){
2898 if(
n !=
n->boundto){
2899 if((
n->above =
n->boundto->above) ==
NULL){
2908 if(ocellpxy != ncellpxy || ocellpxx != ncellpxx){
2913 for(
ncplane* child =
n->
blist ; child ; child = child->bnext){
2914 splice_zaxis_recursive(child, p, ocellpxy, ocellpxx, ncellpxy, ncellpxx);
2925 if(
n->boundto == newparent){
2928 if(ncplane_descendant_p(newparent,
n)){
2933 if( (*
n->bprev =
n->bnext) ){
2934 n->bnext->bprev =
n->bprev;
2937 n->bnext->bprev =
NULL;
2943 if(
n == newparent || ncplane_pile(
n) != ncplane_pile(newparent)){
2944 unsplice_zaxis_recursive(
n);
2945 s = unsplice_sprixels_recursive(
n,
NULL);
2947 const unsigned ocellpxy = ncplane_pile(
n)->cellpxy;
2948 const unsigned ocellpxx = ncplane_pile(
n)->cellpxx;
2949 n->boundto = newparent;
2950 if(
n ==
n->boundto){
2951 logdebug(
"reparenting new root plane %p",
n);
2952 unsplice_zaxis_recursive(
n);
2956 if(ncplane_pile(
n)->top ==
NULL){
2957 ncpile_destroy(ncplane_pile(
n));
2960 unsigned ncellpxy = ncplane_pile(
n)->cellpxy;
2961 unsigned ncellpxx = ncplane_pile(
n)->cellpxx;
2962 pthread_mutex_unlock(&nc->
pilelock);
2963 if(ncplane_pile(
n)){
2964 splice_zaxis_recursive(
n, ncplane_pile(
n), ocellpxy, ocellpxx, ncellpxy, ncellpxx);
2967 if( (
n->bnext = newparent->
blist) ){
2968 n->bnext->bprev = &
n->bnext;
2970 n->bprev = &newparent->
blist;
2973 if(ncplane_pile(
n) != ncplane_pile(
n->boundto)){
2974 unsigned ncellpxy = ncplane_pile(
n->boundto)->cellpxy;
2975 unsigned ncellpxx = ncplane_pile(
n->boundto)->cellpxx;
2977 if(ncplane_pile(
n)->top ==
NULL){
2978 ncpile_destroy(ncplane_pile(
n));
2980 n->pile = ncplane_pile(
n->boundto);
2981 pthread_mutex_unlock(&nc->
pilelock);
2982 splice_zaxis_recursive(
n, ncplane_pile(
n), ocellpxy, ocellpxx, ncellpxy, ncellpxx);
2990 if( (lame->
next =
n->pile->sprixelcache) ){
2991 n->pile->sprixelcache->
prev = lame;
2993 n->pile->sprixelcache = s;
2999 bool old =
n->scrolling;
3000 n->scrolling = scrollp;
3005 return n->scrolling;
3010 logerror(
"can't set the standard plane autogrow");
3013 bool old =
n->autogrow;
3014 n->autogrow = growp;
3025lex_ulong(
const char* op,
unsigned* i,
char** endptr){
3027 long l = strtol(op, endptr, 10);
3028 if(l < 0 || (l == LONG_MAX && errno == ERANGE) || (l > INT_MAX)){
3029 fprintf(stderr,
"invalid margin: %s", op);
3032 if((**endptr !=
',' && **endptr) || *endptr == op){
3033 fprintf(stderr,
"invalid margin: %s", op);
3041 if(strcasecmp(op,
"stretch") == 0){
3043 }
else if(strcasecmp(op,
"scalehi") == 0){
3045 }
else if(strcasecmp(op,
"hires") == 0){
3047 }
else if(strcasecmp(op,
"scale") == 0){
3049 }
else if(strcasecmp(op,
"none") == 0){
3074 if(lex_ulong(op, &
opts->margin_t, &eptr)){
3090 if(lex_ulong(op, &
opts->margin_l, &eptr) || *eptr){
3107get_blitter_egc_idx(
const struct blitset* bset,
const char*
egc){
3109 mbstate_t mbs = {0};
3110 size_t sret = mbrtowc(&wc,
egc, strlen(
egc), &mbs);
3111 if(sret == (
size_t)-1 || sret == (
size_t)-2){
3114 wchar_t* wptr = wcsrchr(bset->
egcs, wc);
3120 return wptr - bset->
egcs;
3124is_bg_p(
int idx,
int py,
int px,
int width){
3126 const int bpos = py * width + px;
3127 const unsigned mask = 1u << bpos;
3134static inline uint32_t*
3136 int begy,
int begx,
unsigned leny,
unsigned lenx,
3137 unsigned* pxdimy,
unsigned* pxdimx){
3139 unsigned ystart, xstart;
3140 if(check_geometry_args(nc, begy, begx, &
leny, &
lenx, &ystart, &xstart)){
3144 logerror(
"pixel blitter %d not yet supported", blit);
3148 logerror(
"must specify exact blitter, not NCBLIT_DEFAULT");
3153 logerror(
"blitter %d invalid in current environment",
blit);
3158 *pxdimy = leny * bset->
height;
3161 *pxdimx = lenx * bset->
width;
3163 uint32_t* ret = malloc(
sizeof(*ret) * lenx * bset->
width * leny * bset->
height);
3166 for(
unsigned y = ystart, targy = 0 ;
y < ystart + leny ; ++
y, targy += bset->
height){
3167 for(
unsigned x = xstart, targx = 0 ;
x < xstart + lenx ; ++
x, targx += bset->
width){
3175 int idx = get_blitter_egc_idx(bset,
c);
3181 unsigned fr, fg, fb, br, bg, bb, fa, ba;
3182 ncchannels_fg_rgb8(channels, &fr, &fb, &fg);
3183 fa = ncchannels_fg_alpha(channels);
3184 ncchannels_bg_rgb8(channels, &br, &bb, &bg);
3185 ba = ncchannels_bg_alpha(channels);
3187 for(
unsigned py = 0 ; py < bset->
height ; ++py){
3188 for(
unsigned px = 0 ; px < bset->
width ; ++px){
3189 uint32_t* p = &ret[(targy + py) * (lenx * bset->
width) + (targx + px)];
3190 bool background = is_bg_p(
idx, py, px, bset->
width);
3194 ncpixel_set_a(p, 0xff);
3195 ncpixel_set_r(p, br);
3196 ncpixel_set_g(p, bb);
3197 ncpixel_set_b(p, bg);
3201 ncpixel_set_a(p, 0xff);
3202 ncpixel_set_r(p, fr);
3203 ncpixel_set_g(p, fb);
3204 ncpixel_set_b(p, fg);
3217 int begy,
int begx,
unsigned leny,
3218 unsigned lenx,
unsigned* pxdimy,
unsigned* pxdimx){
3226 return ncplane_as_rgba_internal(nc,
blit, begy, begx, leny, lenx, pxdimy, pxdimx);
3231 unsigned ystart, xstart;
3232 if(check_geometry_args(nc, begy, begx, &leny, &lenx, &ystart, &xstart)){
3236 char* ret = malloc(retlen);
3238 for(
unsigned y = ystart, targy = 0 ;
y < ystart + leny ; ++
y, targy += 2){
3239 for(
unsigned x = xstart, targx = 0 ;
x < xstart + lenx ; ++
x, ++targx){
3250 char* tmp = realloc(ret, retlen + clen);
3256 memcpy(ret + retlen - 1,
c, clen);
3261 ret[retlen - 1] =
'\0';
3271 ncplane_center(
n,
y,
x);
3282 const wchar_t** wset = &gclustarr;
3283 size_t mbytes = wcsrtombs(
NULL, wset, 0, &ps);
3284 if(mbytes == (
size_t)-1){
3285 logerror(
"error converting wide string");
3289 char* mbstr = malloc(mbytes);
3293 size_t s = wcsrtombs(mbstr, wset, mbytes, &ps);
3294 if(s == (
size_t)-1){
3298 int r = ncplane_putstr_stained(
n, mbstr);
3304 unsigned char* resultbuf,
size_t buflen){
3305 if(u32_to_u8(ucs32, ucs32count, resultbuf, &buflen) ==
NULL){
3313 if(validwidth ==
NULL){
3318 if(validbytes ==
NULL){
3319 validbytes = &bytes;
3323 int thesecols, thesebytes;
3324 thesebytes = utf8_egc_len(
egcs, &thesecols);
3329 *validbytes += thesebytes;
3330 *validwidth += thesecols;
3340 const ncpile* p = ncplane_pile_const(
n);
3348 *pxy = p->
cellpxy * ncplane_dim_y(
n);
3351 *pxx = p->
cellpxx * ncplane_dim_x(
n);
3355 *maxbmapy = p->
cellpxy * ncplane_dim_y(
n);
3361 *maxbmapx = p->
cellpxx * ncplane_dim_x(
n);
3377 return &
n->tcache.caps;
int init_banner(const notcurses *nc, fbuf *f)
const struct blitset * lookup_blitset(const tinfo *tcache, ncblitter_e setid, bool may_degrade)
API int API int API int uint64_t uint64_t uint64_t uint64_t lr
API int API int API int uint64_t uint64_t uint64_t uint64_t unsigned unsigned unsigned ctlword
API int API int API int uint64_t uint64_t uint64_t ll
API int API int API int uint64_t uint64_t uint64_t uint64_t unsigned unsigned xlen
API int API int API int uint64_t uint64_t uint64_t uint64_t unsigned ylen
API int API int API int uint64_t ul
API int API int API int uint64_t uint64_t ur
int inputready_fd(const inputctx *ictx)
int putenv_term(const char *termname) __attribute__((nonnull(1)))
void sprixel_movefrom(sprixel *s, int y, int x)
void sprixel_hide(sprixel *s)
int mouse_setup(tinfo *ti, unsigned eventmask)
void reset_stats(ncstats *stats)
int ncvisual_init(int loglevel)
int set_loglevel_from_env(ncloglevel_e *loglevel) __attribute__((nonnull(1)))
void summarize_stats(notcurses *nc)
void sprixel_free(sprixel *s)
void ncmetric_use_utf8(void)
int sprite_clear_all(const tinfo *t, fbuf *f)
int clear_and_home(notcurses *nc, tinfo *ti, fbuf *f)
int get_linux_fb_pixelgeom(tinfo *ti, unsigned *ypix, unsigned *xpix)
#define logerror(fmt,...)
#define logdebug(fmt,...)
#define logpanic(fmt,...)
ncplane * ncpile_top(ncplane *n)
int ncplane_abs_x(const ncplane *n)
int ncplane_putwstr_stained(ncplane *n, const wchar_t *gclustarr)
void ncplane_on_styles(ncplane *n, unsigned stylebits)
void ncplane_set_fg_default(ncplane *n)
void ncpalette_free(ncpalette *p)
const char * notcurses_version(void)
ncplane * ncplane_new_internal(notcurses *nc, ncplane *n, const ncplane_options *nopts)
int ncplane_set_fg_rgb(ncplane *n, unsigned channel)
int ncplane_cursor_move_yx(ncplane *n, int y, int x)
void ncplane_set_fg_rgb8_clipped(ncplane *n, int r, int g, int b)
void ncplane_home(ncplane *n)
int ncplane_x(const ncplane *n)
int ncplane_cursor_move_rel(ncplane *n, int y, int x)
void * ncplane_userptr(ncplane *n)
int ncplane_y(const ncplane *n)
char * ncplane_contents(ncplane *nc, int begy, int begx, unsigned leny, unsigned lenx)
void ncplane_cursor_yx(const ncplane *n, unsigned *y, unsigned *x)
ncplane * notcurses_stdplane(notcurses *nc)
#define PTHREAD_MUTEX_RECURSIVE_NP
int ncplane_erase_region(ncplane *n, int ystart, int xstart, int ylen, int xlen)
ncplane * ncpile_create(notcurses *nc, const struct ncplane_options *nopts)
char * notcurses_detected_terminal(const notcurses *nc)
bool ncplane_autogrow_p(const ncplane *n)
int update_term_dimensions(unsigned *rows, unsigned *cols, tinfo *tcache, int margin_b, unsigned *cgeo_changed, unsigned *pgeo_changed)
int ncplane_scrollup(ncplane *n, int r)
void ncplane_set_channels(ncplane *n, uint64_t channels)
int notcurses_ucs32_to_utf8(const uint32_t *ucs32, unsigned ucs32count, unsigned char *resultbuf, size_t buflen)
void ncplane_abs_yx(const ncplane *n, int *RESTRICT y, int *RESTRICT x)
ncplane * ncplane_dup(const ncplane *n, void *opaque)
void ncplane_set_bg_rgb8_clipped(ncplane *n, int r, int g, int b)
int ncplane_putchar_stained(ncplane *n, char c)
int ncplane_putnstr_aligned(struct ncplane *n, int y, ncalign_e align, size_t s, const char *str)
int ncplane_vprintf_aligned(ncplane *n, int y, ncalign_e align, const char *format, va_list ap)
int ncplane_set_bg_alpha(ncplane *n, int alpha)
void ncplane_set_styles(ncplane *n, unsigned stylebits)
const char * notcurses_str_scalemode(ncscale_e scalemode)
int ncplane_destroy(ncplane *ncp)
int ncplane_resize_marginalized(ncplane *n)
int ncplane_scrollup_child(ncplane *n, const ncplane *child)
void ncplane_pixel_geom(const ncplane *n, unsigned *RESTRICT pxy, unsigned *RESTRICT pxx, unsigned *RESTRICT celldimy, unsigned *RESTRICT celldimx, unsigned *RESTRICT maxbmapy, unsigned *RESTRICT maxbmapx)
void notcurses_version_components(int *major, int *minor, int *patch, int *tweak)
const char * nccell_extended_gcluster(const ncplane *n, const nccell *c)
void ncplane_off_styles(ncplane *n, unsigned stylebits)
void * ncplane_set_userptr(ncplane *n, void *opaque)
char * ncplane_at_yx(const ncplane *n, int y, int x, uint16_t *stylemask, uint64_t *channels)
int ncplane_set_fg_palindex(ncplane *n, unsigned idx)
int ncplane_putegc_stained(ncplane *n, const char *gclust, size_t *sbytes)
int ncplane_abs_y(const ncplane *n)
int ncplane_resize_placewithin(ncplane *n)
uint16_t ncplane_styles(const ncplane *n)
int ncplane_move_family_above(ncplane *restrict n, ncplane *restrict bpoint)
int ncplane_set_fg_alpha(ncplane *n, int alpha)
int ncpalette_use(notcurses *nc, const ncpalette *p)
int ncplane_set_bg_rgb(ncplane *n, unsigned channel)
const notcurses * ncplane_notcurses_const(const ncplane *n)
const nccapabilities * notcurses_capabilities(const notcurses *n)
ncplane * ncplane_reparent_family(ncplane *n, ncplane *newparent)
uint64_t ncplane_set_fchannel(ncplane *n, uint32_t channel)
int ncplane_move_yx(ncplane *n, int y, int x)
int ncplane_base(ncplane *ncp, nccell *c)
int reset_term_palette(const tinfo *ti, fbuf *f, unsigned touchedpalette)
void free_plane(ncplane *p)
int ncplane_resize_maximize(ncplane *n)
int nccell_load(ncplane *n, nccell *c, const char *gcluster)
int ncdirect_inputready_fd(ncdirect *n)
int ncplane_putwegc_stained(ncplane *n, const wchar_t *gclust, size_t *sbytes)
int notcurses_inputready_fd(notcurses *n)
void ncplane_translate(const ncplane *src, const ncplane *dst, int *restrict y, int *restrict x)
int ncplane_putegc_yx(ncplane *n, int y, int x, const char *gclust, size_t *sbytes)
int ncplane_set_base(ncplane *ncp, const char *egc, uint16_t stylemask, uint64_t channels)
int ncplane_set_bg_rgb8(ncplane *n, unsigned r, unsigned g, unsigned b)
int ncplane_move_family_below(ncplane *restrict n, ncplane *restrict bpoint)
int notcurses_mice_enable(notcurses *n, unsigned eventmask)
int ncplane_resize_internal(ncplane *n, int keepy, int keepx, unsigned keepleny, unsigned keeplenx, int yoff, int xoff, unsigned ylen, unsigned xlen)
const ncplane * notcurses_stdplane_const(const notcurses *nc)
uint64_t ncplane_set_bchannel(ncplane *n, uint32_t channel)
int ncplane_vprintf_stained(struct ncplane *n, const char *format, va_list ap)
const ncplane * ncplane_parent_const(const ncplane *n)
int ncplane_vprintf_yx(ncplane *n, int y, int x, const char *format, va_list ap)
ncplane * ncplane_above(ncplane *n)
int(*)(ncplane *) ncplane_resizecb(const ncplane *n)
notcurses * notcurses_core_init(const notcurses_options *opts, FILE *outfp)
void ncplane_set_resizecb(ncplane *n, int(*resizecb)(ncplane *))
bool ncplane_set_scrolling(ncplane *n, unsigned scrollp)
ncplane * ncplane_below(ncplane *n)
uint32_t * ncplane_as_rgba(const ncplane *nc, ncblitter_e blit, int begy, int begx, unsigned leny, unsigned lenx, unsigned *pxdimy, unsigned *pxdimx)
bool ncplane_scrolling_p(const ncplane *n)
int notcurses_stop(notcurses *nc)
char * ncplane_at_cursor(const ncplane *n, uint16_t *stylemask, uint64_t *channels)
void ncplane_set_bg_default(ncplane *n)
void ncplane_yx(const ncplane *n, int *y, int *x)
int ncplane_set_bg_palindex(ncplane *n, unsigned idx)
void scroll_down(ncplane *n)
int ncplane_hline_interp(ncplane *n, const nccell *c, unsigned len, uint64_t c1, uint64_t c2)
ncplane * ncplane_reparent(ncplane *n, ncplane *newparent)
int ncplane_set_name(ncplane *n, const char *name)
ncpixelimpl_e notcurses_check_pixel_support(const notcurses *nc)
int ncplane_at_cursor_cell(ncplane *n, nccell *c)
int notcurses_lex_scalemode(const char *op, ncscale_e *scalemode)
int ncplane_cursor_at(const ncplane *n, nccell *c, char **gclust)
int resize_callbacks_children(ncplane *n)
int ncplane_resize_realign(ncplane *n)
int reset_term_attributes(const tinfo *ti, fbuf *f)
char * ncplane_vprintf_prep(const char *format, va_list ap)
unsigned notcurses_palette_size(const notcurses *nc)
int notcurses_leave_alternate_screen(notcurses *nc)
ncplane * ncpile_bottom(ncplane *n)
int ncplane_move_below(ncplane *restrict n, ncplane *restrict below)
int ncplane_at_yx_cell(ncplane *n, int y, int x, nccell *c)
int ncstrwidth(const char *egcs, int *validbytes, int *validwidth)
int ncplane_set_fg_rgb8(ncplane *n, unsigned r, unsigned g, unsigned b)
int ncplane_resize(ncplane *n, int keepy, int keepx, unsigned keepleny, unsigned keeplenx, int yoff, int xoff, unsigned ylen, unsigned xlen)
bool ncplane_translate_abs(const ncplane *n, int *restrict y, int *restrict x)
int ncplane_vline_interp(ncplane *n, const nccell *c, unsigned len, uint64_t c1, uint64_t c2)
uint64_t ncplane_channels(const ncplane *n)
notcurses * ncplane_notcurses(const ncplane *n)
ncplane * ncplane_create(ncplane *n, const ncplane_options *nopts)
const void * ncplane_userptr_const(const ncplane *n)
bool ncplane_set_autogrow(ncplane *n, unsigned growp)
void ncplane_erase(ncplane *n)
char * ncplane_name(const ncplane *n)
ncplane * ncplane_parent(ncplane *n)
uint16_t notcurses_supported_styles(const notcurses *nc)
int ncplane_move_above(ncplane *restrict n, ncplane *restrict above)
int ncplane_family_destroy(ncplane *ncp)
int ncplane_box(ncplane *n, const nccell *ul, const nccell *ur, const nccell *ll, const nccell *lr, const nccell *hl, const nccell *vl, unsigned ystop, unsigned xstop, unsigned ctlword)
int notcurses_enter_alternate_screen(notcurses *nc)
void notcurses_drop_planes(notcurses *nc)
int ncplane_putc_yx(ncplane *n, int y, int x, const nccell *c)
int notcurses_lex_margins(const char *op, notcurses_options *opts)
void ncplane_center_abs(const ncplane *n, int *RESTRICT y, int *RESTRICT x)
int ncplane_set_base_cell(ncplane *ncp, const nccell *c)
ncpalette * ncpalette_new(notcurses *nc)
void ncplane_dim_yx(const ncplane *n, unsigned *rows, unsigned *cols)
#define NCOPTION_SUPPRESS_BANNERS
#define NCOPTION_INHIBIT_SETLOCALE
#define NCPLANE_OPTION_HORALIGNED
#define NCPLANE_OPTION_AUTOGROW
#define NCOPTION_NO_CLEAR_BITMAPS
#define NCPLANE_OPTION_MARGINALIZED
#define NCPLANE_OPTION_VSCROLL
const struct ncplane_options * opts
#define NCOPTION_DRAIN_INPUT
#define NCPLANE_OPTION_VERALIGNED
#define NCOPTION_PRESERVE_CURSOR
#define NCOPTION_SCROLLING
#define NCOPTION_NO_QUIT_SIGHANDLERS
#define NCOPTION_NO_WINCH_SIGHANDLER
#define NCCELL_TRIVIAL_INITIALIZER
#define NCPLANE_OPTION_FIXED
#define NCOPTION_NO_ALTERNATE_SCREEN
API int API int const nccell unsigned len
#define NCOPTION_NO_FONT_CHANGES
void nccell_release(ncplane *n, nccell *c)
int nccell_duplicate(ncplane *n, nccell *targ, const nccell *c)
int sprixel_rescale(sprixel *spx, unsigned ncellpxy, unsigned ncellpxx)
void notcurses_stats_reset(notcurses *nc, ncstats *stats)
uint32_t chans[NCPALETTESIZE]
int(* resizecb)(struct ncplane *)
void(* wdestruct)(void *)
int(* resizecb)(struct ncplane *)
bool palette_damage[NCPALETTESIZE]
ncpixelimpl_e pixel_implementation
ncpalette originalpalette
struct termios * tpreserved
int(* pixel_draw)(const struct tinfo *, const struct ncpile *p, struct sprixel *s, fbuf *f, int y, int x)
unsigned sixel_maxy_pristine
int enter_alternate_screen(int fd, FILE *ttyfp, tinfo *ti, unsigned drain)
int locate_cursor(tinfo *ti, unsigned *cursor_y, unsigned *cursor_x)
void free_terminfo_cache(tinfo *ti)
int interrogate_terminfo(tinfo *ti, FILE *out, unsigned utf8, unsigned noaltscreen, unsigned nocbreak, unsigned nonewfonts, int *cursor_y, int *cursor_x, ncsharedstats *stats, int lmargin, int tmargin, int rmargin, int bmargin, unsigned draininput)
int leave_alternate_screen(int fd, FILE *fp, tinfo *ti, unsigned drain)
char * termdesc_longterm(const tinfo *ti)
int tiocgwinsz(int fd, struct winsize *ws)
int setup_signals(void *vnc, bool no_quit_sigs, bool no_winch_sigs, int(*handler)(void *, void **, int))
int drop_signals(void *nc, void **altstack)