1#ifndef NOTCURSES_INTERNAL
2#define NOTCURSES_INTERNAL
10#include "compat/compat.h"
16#define API __attribute__((visibility("default")))
18#define API __declspec(dllexport)
20#define ALLOC __attribute__((malloc)) __attribute__((warn_unused_result))
38#ifndef __STDC_FORMAT_MACROS
39#define __STDC_FORMAT_MACROS
53struct ncvisual_details;
57#define NC_BLITTERSTACK_MASK NC_NOBACKGROUND_MASK
442static inline const ncpile*
443ncplane_pile_const(
const ncplane*
n){
453ncplane_stdplane_const(
const ncplane*
n){
461ncplane_set_widget(
ncplane*
n,
void* w,
void(*wdestruct)(
void*)){
464 logerror(
"plane is already bound to a widget");
471 n->wdestruct = wdestruct;
479fbcellidx(
int row,
int rowlen,
int col){
481 return row * rowlen + col;
486logical_to_virtual(
const ncplane*
n,
int y){
488 return (
y +
n->logrow) %
n->leny;
494nfbcellidx(
const ncplane*
n,
int row,
int col){
495 return fbcellidx(logical_to_virtual(
n, row),
n->lenx, col);
501rgb_greyish_p(
unsigned r,
unsigned g,
unsigned b){
502 const unsigned GREYMASK = 0xf8;
503 if((
r & GREYMASK) == (g & GREYMASK) && (g & GREYMASK) == (b & GREYMASK)){
515rgb_quantize_256(
unsigned r,
unsigned g,
unsigned b){
518 if(rgb_greyish_p(
r, g, b)){
526 return 232 + (
r - 8) / 10;
531 return r * 36 + g * 6 + b + 16;
537rgb_quantize_8(
unsigned r,
unsigned g,
unsigned b){
538 static const int BLACK = 0;
539 static const int RED = 1;
540 static const int GREEN = 2;
541 static const int YELLOW = 3;
542 static const int BLUE = 4;
543 static const int MAGENTA = 5;
544 static const int CYAN = 6;
545 static const int WHITE = 7;
546 if(rgb_greyish_p(
r, g, b)){
578rgb_greyscale(
int r,
int g,
int b){
579 if(r < 0 || r > 255){
582 if(g < 0 || g > 255){
585 if(b < 0 || b > 255){
589 float fg = (0.299 * (
r / 255.0) + 0.587 * (g / 255.0) + 0.114 * (b / 255.0));
593static inline const char*
595 if(cell_simple_p(
c)){
598 return egcpool_extended_gcluster(pool,
c);
602ncplane_cell_ref_yx(
const ncplane*
n,
unsigned y,
unsigned x){
603 return &
n->fb[nfbcellidx(
n,
y,
x)];
608 fprintf(stderr,
"gcluster: %08x %s style: 0x%04x chan: 0x%016" PRIx64
"\n",
614plane_debug(
const ncplane*
n,
bool details){
617 fprintf(stderr,
"p: %p dim: %d/%d poolsize: %d\n",
n, dimy, dimx,
n->pool.poolsize);
619 for(
unsigned y = 0 ;
y < 1 ; ++
y){
620 for(
unsigned x = 0 ;
x < 10 ; ++
x){
621 const nccell*
c = &
n->fb[fbcellidx(
y, dimx,
x)];
622 fprintf(stderr,
"[%03d/%03d] ",
y,
x);
623 cell_debug(&
n->pool,
c);
630ncpile_notcurses(
ncpile* p){
635ncpile_notcurses_const(
const ncpile* p){
641 fbuf_printf(f,
" ************************* %16p pile ****************************\n", p);
646 fbuf_printf(f,
"%04d off y: %3d x: %3d geom y: %3u x: %3u curs y: %3u x: %3u %p %.4s\n",
647 planeidx,
n->absy,
n->absx,
n->leny,
n->lenx,
n->y,
n->x,
n,
n->name);
648 if(
n->boundto ||
n->bnext ||
n->bprev ||
n->blist){
649 fbuf_printf(f,
" bound %p %s %p %s %p binds %p\n",
650 n->boundto, notcurses_canutf8(ncpile_notcurses_const(p)) ?
"←" :
"<",
651 n->bprev, notcurses_canutf8(ncpile_notcurses_const(p)) ?
"→" :
">",
654 if(
n->bprev && (*
n->bprev !=
n)){
655 fbuf_printf(f,
" WARNING: expected *->bprev %p, got %p\n",
n, *
n->bprev);
657 if(
n->above != prev){
658 fbuf_printf(f,
" WARNING: expected ->above %p, got %p\n", prev,
n->above);
660 if(ncplane_pile_const(
n) != p){
661 fbuf_printf(f,
" WARNING: expected pile %p, got %p\n", p, ncplane_pile_const(
n));
668 fbuf_printf(f,
" WARNING: expected ->bottom %p, got %p\n", prev, p->
bottom);
675 fbuf_printf(f,
" -------------------------- notcurses debug state -----------------------------\n");
681 if(p0->
prev != prev){
682 fbuf_printf(f,
"WARNING: expected ->prev %p, got %p\n", prev, p0->
prev);
685 fbuf_printf(f,
" ______________________________________________________________________________\n");
711 return n->tcache.pixel_scrub(p, s);
724 return ti->
pixel_draw(ti, p, s, f, yoff, xoff);
769cleanup_tam(
tament* tam,
int ydim,
int xdim){
770 for(
int y = 0 ;
y < ydim ; ++
y){
771 for(
int x = 0 ;
x < xdim ; ++
x){
772 free(tam[
y * xdim +
x].auxvector);
789 logdebug(
"rebuilding %d %d/%d", s->
id, ycell, xcell);
790 const int idx = s->
dimx * ycell + xcell;
827clamp_to_sixelmax(
const tinfo* t,
unsigned*
y,
unsigned*
x,
unsigned* outy,
ncscale_e scaling){
852scrub_tam_boundaries(
tament* tam,
int leny,
int lenx,
int cdimy,
int cdimx){
855 const int cols = (lenx + cdimx - 1) / cdimx;
856 const int rows = (leny + cdimy - 1) / cdimy;
858 for(
int y = 0 ;
y < rows ; ++
y){
867 const int y = rows - 1;
868 for(
int x = 0 ;
x < cols ; ++
x){
880sprixel_state(
const sprixel* s,
int y,
int x){
894 if(cell_extended_p(
c)){
895 egcpool_release(pool, cell_egc_idx(
c));
903set_gcluster_egc(
nccell*
c,
int eoffset){
910 pool_release(tpool, targ);
914 if(!cell_extended_p(
c)){
920 int eoffset = egcpool_stash(tpool,
egc,
ulen);
924 set_gcluster_egc(targ, eoffset);
929 unsigned keepleny,
unsigned keeplenx,
934 unsigned* cgeo_changed,
unsigned* pgeo_changed)
937ALLOC static inline void*
938memdup(
const void* src,
size_t len){
939 void* ret = malloc(
len);
941 memcpy(ret, src,
len);
946ALLOC void*
bgra_to_rgba(
const void* data,
int rows,
int* rowstride,
int cols,
int alpha);
974 int* offy,
int* offx);
1000calc_gradient_component(
unsigned tl,
unsigned tr,
unsigned bl,
unsigned br,
1001 unsigned y,
unsigned x,
unsigned ylen,
unsigned xlen){
1002 const int avm = (
ylen - 1) -
y;
1003 const int ahm = (
xlen - 1) -
x;
1008 return (tl * avm + bl *
y) / (
ylen - 1);
1011 return (tl * ahm + tr *
x) / (
xlen - 1);
1013 const int tlc = ahm * avm * tl;
1014 const int blc = ahm *
y * bl;
1015 const int trc =
x * avm * tr;
1016 const int brc =
y *
x * br;
1017 const int divisor = (
ylen - 1) * (
xlen - 1);
1018 return ((tlc + blc + trc + brc) + divisor / 2) / divisor;
1022static inline uint32_t
1023calc_gradient_channel(uint32_t
ul, uint32_t
ur, uint32_t
ll, uint32_t
lr,
1024 unsigned y,
unsigned x,
unsigned ylen,
unsigned xlen){
1026 ncchannel_set_rgb8_clipped(&chan,
1027 calc_gradient_component(ncchannel_r(
ul), ncchannel_r(
ur),
1028 ncchannel_r(
ll), ncchannel_r(
lr),
1030 calc_gradient_component(ncchannel_g(
ul), ncchannel_g(
ur),
1031 ncchannel_g(
ll), ncchannel_g(
lr),
1033 calc_gradient_component(ncchannel_b(
ul), ncchannel_b(
ur),
1034 ncchannel_b(
ll), ncchannel_b(
lr),
1036 ncchannel_set_alpha(&chan, ncchannel_alpha(
ul));
1043calc_gradient_channels(uint64_t* channels, uint64_t
ul, uint64_t
ur,
1044 uint64_t
ll, uint64_t
lr,
unsigned y,
unsigned x,
1046 if(!ncchannels_fg_default_p(
ul)){
1047 ncchannels_set_fchannel(channels,
1048 calc_gradient_channel(ncchannels_fchannel(
ul),
1049 ncchannels_fchannel(
ur),
1050 ncchannels_fchannel(
ll),
1051 ncchannels_fchannel(
lr),
1054 ncchannels_set_fg_default(channels);
1056 if(!ncchannels_bg_default_p(
ul)){
1057 ncchannels_set_bchannel(channels,
1058 calc_gradient_channel(ncchannels_bchannel(
ul),
1059 ncchannels_bchannel(
ur),
1060 ncchannels_bchannel(
ll),
1061 ncchannels_bchannel(
lr),
1064 ncchannels_set_bg_default(channels);
1087tty_emit(
const char* seq,
int fd){
1091 size_t slen = strlen(seq);
1092 if(blocking_write(fd, seq, slen)){
1101term_bg_palindex(
const notcurses* nc,
fbuf* f,
unsigned pal){
1104 return fbuf_emit(f, tiparm(setab, pal));
1110term_fg_palindex(
const notcurses* nc,
fbuf* f,
unsigned pal){
1113 return fbuf_emit(f, tiparm(setaf, pal));
1122term_setstyle(
fbuf* f,
unsigned cur,
unsigned targ,
unsigned stylebit,
1123 const char* ton,
const char* toff){
1125 unsigned curon = cur & stylebit;
1126 unsigned targon = targ & stylebit;
1127 if(curon != targon){
1130 ret = fbuf_emit(f, ton);
1134 ret = fbuf_emit(f, toff);
1148coerce_styles(
fbuf* f,
const tinfo* ti, uint16_t* curstyle,
1149 uint16_t newstyle,
unsigned* normalized){
1152 ret |= term_setstyle(f, *curstyle, newstyle,
NCSTYLE_BOLD,
1170 *curstyle = newstyle;
1175#define SET_X10_MOUSE_PROT "9"
1177#define SET_X11_MOUSE_PROT "1000"
1178#define SET_HILITE_MOUSE_PROT "1001"
1179#define SET_BTN_EVENT_MOUSE "1002"
1180#define SET_ALL_EVENT_MOUSE "1003"
1181#define SET_FOCUS_EVENT_MOUSE "1004"
1182#define SET_UTF8_MOUSE_PROT "1005"
1183#define SET_SGR_MOUSE_PROT "1006"
1184#define SET_ALTERNATE_SCROLL "1007"
1185#define SET_TTYOUTPUT_SCROLL "1010"
1186#define SET_KEYPRESS_SCROLL "1011"
1187#define SET_URXVT_MOUSE_PROT "1015"
1188#define SET_PIXEL_MOUSE_PROT "1016"
1189#define SET_ENABLE_ALTSCREEN "1046"
1190#define SET_ALTERNATE_SCREEN "1047"
1191#define SET_SAVE_CURSOR "1048"
1192#define SET_SMCUP "1049"
1194#define DECSET(p) "\x1b[?" p "h"
1195#define DECRST(p) "\x1b[?" p "l"
1223 if(fbuf_emit(f, tiparm(hpa,
x))){
1229 if(fbuf_emit(f, tiparm(cup,
y,
x))){
1240static inline unsigned
1241box_corner_needs(
unsigned ctlword){
1248nccell_nobackground_p(
const nccell*
c){
1255nccell_rgbequal_p(
const nccell*
c){
1256 if(nccell_fg_default_p(
c) || nccell_fg_palindex_p(
c)){
1259 if(nccell_bg_default_p(
c) || nccell_bg_palindex_p(
c)){
1262 return nccell_fg_rgb(
c) == nccell_bg_rgb(
c);
1268static inline unsigned
1269cell_blittedquadrants(
const nccell*
c){
1270 return ((
c->
channels & 0x8000000000000000ull) ? 1 : 0) |
1271 ((
c->channels & 0x0400000000000000ull) ? 2 : 0) |
1272 ((
c->channels & 0x0200000000000000ull) ? 4 : 0) |
1273 ((
c->channels & 0x0100000000000000ull) ? 8 : 0);
1280cell_set_blitquadrants(
nccell*
c,
unsigned tl,
unsigned tr,
unsigned bl,
unsigned br){
1283 uint64_t newval = (tl ? 0x8000000000000000ull : 0) |
1284 (tr ? 0x0400000000000000ull : 0) |
1285 (bl ? 0x0200000000000000ull : 0) |
1286 (br ? 0x0100000000000000ull : 0);
1294static inline uint32_t
1295cell_bchannel(
const nccell* cl){
1296 return ncchannels_bchannel(cl->
channels);
1301static inline uint32_t
1302channel_common(uint32_t channel){
1309static inline uint32_t
1310cell_bchannel_common(
const nccell* cl){
1311 return channel_common(cell_bchannel(cl));
1315static inline uint32_t
1316cell_fchannel(
const nccell* cl){
1317 return ncchannels_fchannel(cl->
channels);
1322static inline uint32_t
1323cell_fchannel_common(
const nccell* cl){
1324 return channel_common(cell_fchannel(cl));
1328static inline uint64_t
1329cell_set_bchannel(
nccell* cl, uint32_t channel){
1330 return ncchannels_set_bchannel(&cl->
channels, channel);
1334static inline uint64_t
1335cell_set_fchannel(
nccell* cl, uint32_t channel){
1336 return ncchannels_set_fchannel(&cl->
channels, channel);
1344static inline unsigned
1345channels_blend(
notcurses* nc,
unsigned c1,
unsigned c2,
unsigned* blends,
1352 if(ncchannel_default_p(c2)){
1353 ncchannel_set_default(&c1);
1354 }
else if(ncchannel_palindex_p(c2)){
1355 ncchannel_set_palindex(&c1, ncchannel_palindex(c2));
1357 ncchannel_set(&c1, ncchannel_rgb(c2));
1359 }
else if(ncchannel_default_p(c1) && ncchannel_default_p(c2)){
1361 }
else if((ncchannel_palindex_p(c1) && ncchannel_palindex_p(c2)) &&
1362 ncchannel_palindex(c1) == ncchannel_palindex(c2)){
1365 unsigned r1, g1, b1;
1366 unsigned r2, g2, b2;
1367 if(ncchannel_default_p(c2)){
1368 ncchannel_rgb8(defchan, &r2, &g2, &b2);
1369 }
else if(ncchannel_palindex_p(c2)){
1370 ncchannel_rgb8(nc->
palette.
chans[ncchannel_palindex(c2)],
1373 ncchannel_rgb8(c2, &r2, &g2, &b2);
1375 if(ncchannel_default_p(c1)){
1376 ncchannel_rgb8(defchan, &r1, &g1, &b1);
1377 }
else if(ncchannel_palindex_p(c1)){
1378 ncchannel_rgb8(nc->
palette.
chans[ncchannel_palindex(c1)],
1381 ncchannel_rgb8(c1, &r1, &g1, &b1);
1383 unsigned r = (r1 * *blends + r2) / (*blends + 1);
1384 unsigned g = (g1 * *blends + g2) / (*blends + 1);
1385 unsigned b = (b1 * *blends + b2) / (*blends + 1);
1386 ncchannel_set_rgb8(&c1,
r, g, b);
1388 ncchannel_set_alpha(&c1, ncchannel_alpha(c2));
1394static inline uint64_t
1395cell_blend_fchannel(
notcurses* nc,
nccell* cl,
unsigned channel,
unsigned* blends){
1396 return cell_set_fchannel(cl, channels_blend(nc, cell_fchannel(cl),
1400static inline uint64_t
1401cell_blend_bchannel(
notcurses* nc,
nccell* cl,
unsigned channel,
unsigned* blends){
1402 return cell_set_bchannel(cl, channels_blend(nc, cell_bchannel(cl),
1409plane_blit_sixel(
sprixel* spx,
fbuf* f,
int leny,
int lenx,
1411 if(
sprixel_load(spx, f, leny, lenx, parse_start, state)){
1429is_control_egc(
const unsigned char*
egc,
int bytes){
1431 if(*
egc < 0x20 || *
egc == 0x7f){
1434 }
else if(bytes == 2){
1451pool_blit_direct(
egcpool* pool,
nccell*
c,
const char* gcluster,
int bytes,
int cols){
1452 pool_release(pool,
c);
1453 if(bytes < 0 || cols < 0){
1458 if(is_control_egc((
const unsigned char*)gcluster, bytes) && *gcluster !=
'\n' && *gcluster !=
'\t'){
1459 logerror(
"not loading control character %u", *(
const unsigned char*)gcluster);
1467 int eoffset = egcpool_stash(pool, gcluster, bytes);
1471 set_gcluster_egc(
c, eoffset);
1479pool_load_direct(
egcpool* pool,
nccell*
c,
const char* gcluster,
int bytes,
int cols){
1481 return pool_blit_direct(pool,
c, gcluster, bytes, cols);
1485cell_load_direct(
ncplane*
n,
nccell*
c,
const char* gcluster,
int bytes,
int cols){
1486 return pool_load_direct(&
n->pool,
c, gcluster, bytes, cols);
1493islinebreak(
wchar_t wchar){
1495 if(wchar == L
'\n' || wchar == L
'\v' || wchar == L
'\f'){
1498 const uint32_t mask = UC_CATEGORY_MASK_Zl | UC_CATEGORY_MASK_Zp;
1499 return uc_is_general_category_withtable(wchar, mask);
1503iswordbreak(
wchar_t wchar){
1504 const uint32_t mask = UC_CATEGORY_MASK_Z |
1505 UC_CATEGORY_MASK_Zs;
1506 return uc_is_general_category_withtable(wchar, mask);
1518 const char* damegc = pool_extended_gcluster(dampool, damcell);
1519 if(strcmp(damegc, srcegc) == 0){
1524 cell_duplicate_far(dampool, damcell, srcplane, srccell);
1548check_geometry_args(
const ncplane*
n,
int y,
int x,
1550 unsigned* ystart,
unsigned* xstart){
1570 unsigned ymax, xmax;
1572 if(*ystart >= ymax || *xstart >= xmax){
1573 logerror(
"invalid starting coordinates: %u/%u", *ystart, *xstart);
1578 *
ylen = ymax - *ystart;
1581 *
xlen = xmax - *xstart;
1593 if(ymax - *
ylen < *ystart){
1594 logerror(
"y + ylen > ymax %u + %u > %u", *ystart, *
ylen, ymax);
1597 if(xmax - *
xlen < *xstart){
1598 logerror(
"x + xlen > xmax %u + %u > %u", *xstart, *
xlen, xmax);
1613rgba_trans_p(uint32_t p, uint32_t transcolor){
1614 if(ncpixel_a(p) < 192){
1618 (ncpixel_r(p) == (transcolor & 0xff0000ull) >> 16) &&
1619 (ncpixel_g(p) == (transcolor & 0xff00ull) >> 8) &&
1620 (ncpixel_b(p) == (transcolor & 0xffull))){
1627static inline uint32_t
1628rgb_diff(
unsigned r1,
unsigned g1,
unsigned b1,
unsigned r2,
unsigned g2,
unsigned b2){
1629 uint32_t distance = 0;
1630 distance += r1 > r2 ? r1 - r2 : r2 - r1;
1631 distance += g1 > g2 ? g1 - g2 : g2 - g1;
1632 distance += b1 > b2 ? b1 - b2 : b2 - b1;
1638static inline unsigned
1643 b1 = y1 + ncplane_dim_y(p1) - 1;
1644 r1 = x1 + ncplane_dim_x(p1) - 1;
1646 b2 = y2 + ncplane_dim_y(p2) - 1;
1647 r2 = x2 + ncplane_dim_x(p2) - 1;
1663static inline uint64_t
1664ncdirect_channels(
const ncdirect* nc){
1669ncdirect_fg_default_p(
const ncdirect* nc){
1670 return ncchannels_fg_default_p(ncdirect_channels(nc));
1674ncdirect_bg_default_p(
const ncdirect* nc){
1675 return ncchannels_bg_default_p(ncdirect_channels(nc));
1679ncdirect_fg_palindex_p(
const ncdirect* nc){
1680 return ncchannels_fg_palindex_p(ncdirect_channels(nc));
1684ncdirect_bg_palindex_p(
const ncdirect* nc){
1685 return ncchannels_bg_palindex_p(ncdirect_channels(nc));
1696 int linesize,
const void* data,
1698 return bset->
blit(nc, linesize, data, leny, lenx, bargs);
1704 unsigned* disppxy,
unsigned* disppxx,
1705 unsigned* outy,
unsigned* outx,
1706 int* placey,
int* placex);
1708static inline const struct blitset*
1709rgba_blitter_low(
const tinfo* tcache,
ncscale_e scale,
bool maydegrade,
1712 blitrec = rgba_blitter_default(tcache, scale);
1719static inline const struct blitset*
1730static inline uint32_t*
1731resize_bitmap(
const uint32_t* bmap,
int srows,
int scols,
size_t sstride,
1732 int drows,
int dcols,
size_t dstride){
1733 if(sstride < scols *
sizeof(*bmap)){
1736 if(dstride < dcols *
sizeof(*bmap)){
1740 size_t size = drows * dstride;
1741 uint32_t* ret = (uint32_t*)malloc(size);
1745 float xrat = (float)dcols / scols;
1746 float yrat = (float)drows / srows;
1748 for(
int y = 0 ;
y < srows ; ++
y){
1749 float ytarg = (
y + 1) * yrat;
1755 for(
int x = 0 ;
x < scols ; ++
x){
1756 float xtarg = (
x + 1) * xrat;
1761 ret[dy * dstride /
sizeof(*ret) + dx] = bmap[
y * sstride /
sizeof(*ret) +
x];
1780create_polyfill_op(
int y,
int x,
struct topolyfill** stck){
1799 struct ncvisual* (*visual_create)(void);
1800 struct ncvisual* (*visual_from_file)(
const char* fname);
1836cancel_and_join(
const char* name, pthread_t tid,
void** res){
1837 if(pthread_cancel(tid)){
1838 logerror(
"couldn't cancel %s thread", name);
1840 if(pthread_join(tid, res)){
1841 logerror(
"error joining %s thread", name);
1848emit_scrolls(
const tinfo* ti,
int count,
fbuf* f){
1849 logdebug(
"emitting %d scrolls", count);
1853 if(fbuf_emit(f, tiparm(indn, count)) < 0){
1859 const char* ind = get_escape(ti,
ESCAPE_IND);
1865 if(fbuf_emit(f, ind) < 0){
1877 if(emit_scrolls(&nc->
tcache, count, f)){
1895encoding_is_utf8(
const char *enc){
1896 if(tolower(enc[0]) ==
'c' && tolower(enc[1]) ==
's'){
1899 const char utfstr[] =
"utf8";
1900 const char* match = utfstr;
1903 if(tolower(*enc) != tolower(*match)){
int(* ncblitter)(struct ncplane *n, int linesize, const void *data, int scaledy, int scaledx, const struct blitterargs *bargs)
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
__attribute__((nonnull(1, 2))) static inline int egcpool_stash(egcpool *pool
void update_render_stats(const struct timespec *time1, const struct timespec *time0, ncstats *stats)
int ncdirect_set_bg_rgb_f(ncdirect *nc, unsigned rgb, fbuf *f)
ncplane * ncplane_new_internal(notcurses *nc, ncplane *n, const ncplane_options *nopts)
int update_term_dimensions(unsigned *rows, unsigned *cols, tinfo *tcache, int margin_b, unsigned *cgeo_changed, unsigned *pgeo_changed) __attribute__((nonnull(3
sprixel * sprixel_recycle(ncplane *n)
int ncdirect_set_fg_rgb_f(ncdirect *nc, unsigned rgb, fbuf *f)
void update_write_stats(const struct timespec *time1, const struct timespec *time0, ncstats *stats, int bytes)
int putenv_term(const char *termname) __attribute__((nonnull(1)))
int term_fg_rgb8(const tinfo *ti, fbuf *f, unsigned r, unsigned g, unsigned b)
ALLOC void * rgb_loose_to_rgba(const void *data, int rows, int *rowstride, int cols, int alpha)
void sprixel_movefrom(sprixel *s, int y, int x)
void sprixel_hide(sprixel *s)
void ncvisual_printbanner(fbuf *f)
int mouse_setup(tinfo *ti, unsigned eventmask)
int sprite_wipe(const notcurses *nc, sprixel *s, int y, int x)
void reset_stats(ncstats *stats)
int ncvisual_init(int loglevel)
int ncplane_destroy_family(ncplane *ncp)
void warn_terminfo(const notcurses *nc, const tinfo *ti)
int reset_term_palette(const tinfo *ti, fbuf *f, unsigned touchedpalette)
void free_plane(ncplane *p)
int set_loglevel_from_env(ncloglevel_e *loglevel) __attribute__((nonnull(1)))
const struct blitset * lookup_blitset(const tinfo *tcache, ncblitter_e setid, bool may_degrade)
int ncplane_resize_internal(ncplane *n, int keepy, int keepx, unsigned keepleny, unsigned keeplenx, int yoff, int xoff, unsigned ylen, unsigned xlen)
int ncvisual_bounding_box(const struct ncvisual *ncv, int *leny, int *lenx, int *offy, int *offx)
int set_fd_nonblocking(int fd, unsigned state, unsigned *oldstate)
ALLOC void * bgra_to_rgba(const void *data, int rows, int *rowstride, int cols, int alpha)
bool check_gradient_args(uint64_t ul, uint64_t ur, uint64_t bl, uint64_t br)
int ncvisual_blit_internal(const struct ncvisual *ncv, int rows, int cols, ncplane *n, const struct blitset *bset, const blitterargs *bargs)
void summarize_stats(notcurses *nc)
void sigwinch_handler(int signo)
int get_tty_fd(FILE *ttyfp)
void sprixel_invalidate(sprixel *s, int y, int x)
void scroll_down(ncplane *n)
void update_raster_stats(const struct timespec *time1, const struct timespec *time0, ncstats *stats)
void sprixel_free(sprixel *s)
int resize_callbacks_children(ncplane *n)
API ncvisual_implementation * visual_implementation
int reset_term_attributes(const tinfo *ti, fbuf *f)
void ncmetric_use_utf8(void)
int sprite_clear_all(const tinfo *t, fbuf *f)
void sprixel_debug(const sprixel *s, FILE *out)
sprixel * sprixel_alloc(ncplane *n, int dimy, int dimx)
int ncvisual_geom_inner(const tinfo *ti, const struct ncvisual *n, const struct ncvisual_options *vopts, ncvgeom *geom, const struct blitset **bset, unsigned *disppxy, unsigned *disppxx, unsigned *outy, unsigned *outx, int *placey, int *placex)
ALLOC char * ncplane_vprintf_prep(const char *format, va_list ap)
void sixelmap_free(struct sixelmap *s)
void update_raster_bytes(ncstats *stats, int bytes)
int clear_and_home(notcurses *nc, tinfo *ti, fbuf *f)
ALLOC void * rgb_packed_to_rgba(const void *data, int rows, int *rowstride, int cols, int alpha)
#define logerror(fmt,...)
#define logdebug(fmt,...)
ncplane * notcurses_stdplane(notcurses *nc)
void ncplane_abs_yx(const ncplane *n, int *RESTRICT y, int *RESTRICT x)
const char * nccell_extended_gcluster(const ncplane *n, const nccell *c)
const notcurses * ncplane_notcurses_const(const ncplane *n)
const ncplane * notcurses_stdplane_const(const notcurses *nc)
notcurses * ncplane_notcurses(const ncplane *n)
void ncplane_dim_yx(const ncplane *n, unsigned *rows, unsigned *cols)
#define NCSTYLE_UNDERCURL
const struct ncplane_options struct ncvisual * ncv
void(* tabcb)(struct nctab *t, struct ncplane *ncp, void *curry)
#define NCBOXCORNER_SHIFT
const struct ncplane_options struct ncvisual struct ncvisual_options * vopts
#define NCSTYLE_UNDERLINE
#define NC_BGDEFAULT_MASK
const struct ncplane_options * opts
int(* tabletcb)(struct nctablet *t, bool drawfromtop)
#define NC_NOBACKGROUND_MASK
#define NCALPHA_TRANSPARENT
int(* ncfdplane_done_cb)(struct ncfdplane *n, int fderrno, void *curry)
int(* ncfdplane_callback)(struct ncfdplane *n, const void *buf, size_t s, void *curry)
int(* ncstreamcb)(struct ncvisual *, struct ncvisual_options *, const struct timespec *, void *)
API int API int const nccell unsigned len
#define NCVISUAL_OPTION_NODEGRADE
int sprixel_load(sprixel *spx, fbuf *f, unsigned pixy, unsigned pixx, int parse_start, sprixel_e state)
@ SPRIXCELL_ANNIHILATED_TRANS
struct blitterargs::@3::@5 pixel
struct blitterargs::@3::@4 cell
uint32_t chans[NCPALETTESIZE]
void(* wdestruct)(void *)
int(* resizecb)(struct ncplane *)
enum ncreel::@1 direction
int(* visual_resize)(struct ncvisual *ncv, unsigned rows, unsigned cols)
int(* visual_stream)(notcurses *nc, struct ncvisual *ncv, float timescale, ncstreamcb streamer, const struct ncvisual_options *vopts, void *curry)
int(* visual_decode)(struct ncvisual *nc)
void(* visual_printbanner)(fbuf *f)
int(* visual_decode_loop)(struct ncvisual *nc)
void(* visual_details_seed)(struct ncvisual *ncv)
int(* visual_blit)(const struct ncvisual *ncv, unsigned rows, unsigned cols, ncplane *n, const struct blitset *bset, const blitterargs *barg)
void(* visual_destroy)(struct ncvisual *ncv)
int(* visual_init)(int loglevel)
bool palette_damage[NCPALETTESIZE]
int(* pixel_rebuild)(struct sprixel *s, int y, int x, uint8_t *auxvec)
uint32_t bg_collides_default
int(* pixel_commit)(fbuf *f, struct sprixel *s, unsigned noscroll)
unsigned sprixel_scale_height
int(* pixel_draw)(const struct tinfo *, const struct ncpile *p, struct sprixel *s, fbuf *f, int y, int x)
unsigned sixel_maxy_pristine
int(* pixel_move)(struct sprixel *s, fbuf *f, unsigned noscroll, int yoff, int xoff)