14restripe_lastframe(
notcurses* nc,
unsigned rows,
unsigned cols){
17 const size_t size =
sizeof(*nc->
lastframe) * (rows * cols);
18 nccell* tmp = malloc(size);
23 size_t maxlinecopy =
sizeof(
nccell) * copycols;
24 size_t minlineset =
sizeof(
nccell) * cols - maxlinecopy;
25 unsigned zorch = nc->
lfdimx > cols ? nc->
lfdimx - cols : 0;
26 for(
unsigned y = 0 ;
y < rows ; ++
y){
32 memset(&tmp[cols *
y + copycols], 0, minlineset);
36 for(
unsigned x = copycols ;
x < copycols + zorch ; ++
x){
41 memset(&tmp[cols *
y], 0,
sizeof(
nccell) * cols);
45 for(
unsigned y = rows ;
y < nc->
lfdimy ; ++
y){
46 for(
unsigned x = 0 ;
x < nc->
lfdimx ; ++
x){
62notcurses_resize_internal(
ncplane* pp,
unsigned* restrict rows,
unsigned* restrict cols){
71 ncpile* pile = ncplane_pile(pp);
72 unsigned oldrows = pile->
dimy;
73 unsigned oldcols = pile->
dimx;
76 unsigned cgeo_changed;
77 unsigned pgeo_changed;
79 &cgeo_changed, &pgeo_changed)){
82 n->stats.s.cell_geo_changes += cgeo_changed;
83 n->stats.s.pixel_geo_changes += pgeo_changed;
84 *rows -=
n->margin_t +
n->margin_b;
88 *cols -=
n->margin_l +
n->margin_r;
92 if(*rows !=
n->lfdimy || *cols !=
n->lfdimx){
93 if(restripe_lastframe(
n, *rows, *cols)){
98 if(*rows == oldrows && *cols == oldcols){
111 for(
ncplane* rootn = pile->
roots ; rootn ; rootn = rootn->bnext){
113 ret |= rootn->resizecb(rootn);
121notcurses_resize(
notcurses*
n,
unsigned* restrict rows,
unsigned* restrict cols){
122 pthread_mutex_lock(&
n->pilelock);
124 pthread_mutex_unlock(&
n->pilelock);
129 pool_release(&
n->pool,
c);
134 if(cell_duplicate_far(&
n->pool, targ,
n,
c) < 0){
135 logerror(
"failed duplicating cell");
143highcontrast(
const tinfo* ti, uint32_t bchannel){
145 if(ncchannel_default_p(bchannel)){
152 r = ncchannel_r(bchannel);
153 g = ncchannel_g(bchannel);
154 b = ncchannel_b(bchannel);
158 ncchannel_set(&conrgb, 0xffffff);
160 ncchannel_set(&conrgb, 0);
169paint_sprixel(
ncplane* p,
struct crender* rvec,
int starty,
int startx,
170 int offy,
int offx,
int dstleny,
int dstlenx){
179 for(
int y = starty ;
y < dimy ; ++
y){
180 const int absy =
y + offy;
182 if(absy >= dstleny || absy < 0){
185 for(
int x = startx ;
x < dimx ; ++
x){
186 const int absx =
x + offx;
187 if(absx >= dstlenx || absx < 0){
212 sprite_rebuild(nc,
s,
y,
x);
237 int dstabsy,
int dstabsx,
sprixel** sprixelstack,
238 unsigned pgeo_changed){
239 unsigned y,
x, dimy, dimx;
242 offy =
p->
absy - dstabsy;
243 offx =
p->
absx - dstabsx;
246 unsigned starty, startx;
265 paint_sprixel(
p, rvec, starty, startx, offy, offx, dstleny, dstlenx);
284 for(
y = starty ;
y < dimy ; ++
y){
285 const int absy =
y + offy;
287 if(absy >= dstleny || absy < 0){
290 for(
x = startx ;
x < dimx ; ++
x){
291 const int absx =
x + offx;
292 if(absx >= dstlenx || absx < 0){
298 if(nccell_wide_right_p(targc)){
304 if(nccell_fg_default_p(vis)){
335 if(nccell_bg_default_p(vis)){
342 if(nccell_fg_default_p(vis)){
361 if(vis->
gcluster == 0 && !nccell_double_wide_p(vis)){
374 if(nccell_double_wide_p(vis)){
376 if(absx >= dstlenx - 1){
393 }
else if(nccell_wide_right_p(vis)){
405init_rvec(
struct crender* rvec,
int totalcells){
409 for(
int t = 0 ; t < totalcells ; ++t){
410 memcpy(&rvec[t], &
c,
sizeof(
c));
420 nccell_set_fg_default(targc);
423 nccell_set_bg_default(targc);
427 if(!nccell_fg_default_p(targc)){
429 uint32_t fchan = cell_fchannel(targc);
430 uint32_t bchan = cell_bchannel(targc);
431 uint32_t hchan = channels_blend(nc,
highcontrast(ti, bchan), fchan,
433 cell_set_fchannel(targc, hchan);
437 cell_set_fchannel(targc, hchan);
439 nccell_set_fg_rgb(targc,
highcontrast(ti, cell_bchannel(targc)));
451 lock_in_highcontrast(nc, ti, targc,
crender);
452 nccell* prevcell = &lastframe[fbcellidx(
y, dimx, *
x)];
453 if(cellcmp_and_dupfar(pool, prevcell,
crender->
p, targc) > 0){
470 assert(!nccell_wide_right_p(targc));
471 const int width = targc->
width;
472 for(
int i = 1 ; i < width ; ++i){
482 if(cellcmp_and_dupfar(pool, prevcell,
crender->
p, targc) > 0){
502 unsigned dimy,
unsigned dimx,
struct crender* rvec,
egcpool* pool){
504 for(
unsigned y = 0 ;
y < dimy ; ++
y){
505 for(
unsigned x = 0 ;
x < dimx ; ++
x){
507 postpaint_cell(nc, ti, lastframe, dimx,
crender, pool,
y, &
x);
515 int begsrcy,
int begsrcx,
unsigned leny,
unsigned lenx,
532 if((
unsigned)dsty >= dst->leny || (
unsigned)dstx >= dst->lenx){
533 logerror(
"dest origin %u/%u ≥ dest dimensions %d/%d",
534 dsty, dstx, dst->leny, dst->lenx);
539 logerror(
"invalid begsrcy %d", begsrcy);
546 logerror(
"invalid begsrcx %d", begsrcx);
551 if((
unsigned)begsrcy >= src->leny || (
unsigned)begsrcx >= src->lenx){
552 logerror(
"source origin %u/%u ≥ source dimensions %d/%d",
553 begsrcy, begsrcx, src->leny, src->lenx);
557 if((leny = src->leny - begsrcy) == 0){
558 logerror(
"source area was zero height");
563 if((lenx = src->lenx - begsrcx) == 0){
564 logerror(
"source area was zero width");
568 if(dst->leny - leny < (
unsigned)dsty || dst->lenx - lenx < (
unsigned)dstx){
569 logerror(
"dest len %u/%u ≥ dest dimensions %d/%d",
570 leny, lenx, dst->leny, dst->lenx);
573 if(src->leny - leny < (
unsigned)begsrcy || src->lenx - lenx < (
unsigned)begsrcx){
574 logerror(
"source len %u/%u ≥ source dimensions %d/%d",
575 leny, lenx, src->leny, src->lenx);
578 if(src->sprite || dst->sprite){
579 logerror(
"can't merge sprixel planes");
582 const int totalcells = dst->leny * dst->lenx;
583 nccell* rendfb = calloc(totalcells,
sizeof(*rendfb));
584 const size_t crenderlen =
sizeof(
struct crender) * totalcells;
585 struct crender* rvec = malloc(crenderlen);
586 if(!rendfb || !rvec){
587 logerror(
"error allocating render state for %ux%u", leny, lenx);
592 init_rvec(rvec, totalcells);
594 paint(src, rvec, dst->leny, dst->lenx, dst->absy, dst->absx, &
s, 0);
596 paint(dst, rvec, dst->leny, dst->lenx, dst->absy, dst->absx, &
s, 0);
600 postpaint(
ncplane_notcurses(dst), ti, rendfb, dst->leny, dst->lenx, rvec, &dst->pool);
615 if(cell_simple_p(
c)){
620 if(fbuf_putc(f,
' ') < 0){
623 }
else if(fbuf_puts(f, (
const char*)&
c->
gcluster) == EOF){
627 if(fbuf_puts(f, egcpool_extended_gcluster(
e,
c)) == EOF){
637 unsigned normalized =
false;
639 nccell_styles(
c), &normalized);
652static const char*
const NUMBERS[] = {
653"0;",
"1;",
"2;",
"3;",
"4;",
"5;",
"6;",
"7;",
"8;",
"9;",
"10;",
"11;",
"12;",
"13;",
"14;",
"15;",
"16;",
654"17;",
"18;",
"19;",
"20;",
"21;",
"22;",
"23;",
"24;",
"25;",
"26;",
"27;",
"28;",
"29;",
"30;",
"31;",
"32;",
655"33;",
"34;",
"35;",
"36;",
"37;",
"38;",
"39;",
"40;",
"41;",
"42;",
"43;",
"44;",
"45;",
"46;",
"47;",
"48;",
656"49;",
"50;",
"51;",
"52;",
"53;",
"54;",
"55;",
"56;",
"57;",
"58;",
"59;",
"60;",
"61;",
"62;",
"63;",
"64;",
657"65;",
"66;",
"67;",
"68;",
"69;",
"70;",
"71;",
"72;",
"73;",
"74;",
"75;",
"76;",
"77;",
"78;",
"79;",
"80;",
658"81;",
"82;",
"83;",
"84;",
"85;",
"86;",
"87;",
"88;",
"89;",
"90;",
"91;",
"92;",
"93;",
"94;",
"95;",
"96;",
659"97;",
"98;",
"99;",
"100;",
"101;",
"102;",
"103;",
"104;",
"105;",
"106;",
"107;",
"108;",
"109;",
"110;",
"111;",
"112;",
660"113;",
"114;",
"115;",
"116;",
"117;",
"118;",
"119;",
"120;",
"121;",
"122;",
"123;",
"124;",
"125;",
"126;",
"127;",
"128;",
661"129;",
"130;",
"131;",
"132;",
"133;",
"134;",
"135;",
"136;",
"137;",
"138;",
"139;",
"140;",
"141;",
"142;",
"143;",
"144;",
662"145;",
"146;",
"147;",
"148;",
"149;",
"150;",
"151;",
"152;",
"153;",
"154;",
"155;",
"156;",
"157;",
"158;",
"159;",
"160;",
663"161;",
"162;",
"163;",
"164;",
"165;",
"166;",
"167;",
"168;",
"169;",
"170;",
"171;",
"172;",
"173;",
"174;",
"175;",
"176;",
664"177;",
"178;",
"179;",
"180;",
"181;",
"182;",
"183;",
"184;",
"185;",
"186;",
"187;",
"188;",
"189;",
"190;",
"191;",
"192;",
665"193;",
"194;",
"195;",
"196;",
"197;",
"198;",
"199;",
"200;",
"201;",
"202;",
"203;",
"204;",
"205;",
"206;",
"207;",
"208;",
666"209;",
"210;",
"211;",
"212;",
"213;",
"214;",
"215;",
"216;",
"217;",
"218;",
"219;",
"220;",
"221;",
"222;",
"223;",
"224;",
667"225;",
"226;",
"227;",
"228;",
"229;",
"230;",
"231;",
"232;",
"233;",
"234;",
"235;",
"236;",
"237;",
"238;",
"239;",
"240;",
668"241;",
"242;",
"243;",
"244;",
"245;",
"246;",
"247;",
"248;",
"249;",
"250;",
"251;",
"252;",
"253;",
"254;",
"255;", };
671term_esc_rgb(
fbuf* f,
bool foreground,
unsigned r,
unsigned g,
unsigned b){
683 #define RGBESC1 "\x1b" "["
686 #define RGBESC2 "8;2;"
690 fbuf_putc(f, foreground ?
'3' :
'4');
692 const char* s = NUMBERS[
r];
709term_bg_rgb8(
const tinfo* ti,
fbuf* f,
unsigned r,
unsigned g,
unsigned b){
725 return term_esc_rgb(f,
false,
r, g, b);
734 return fbuf_emit(f, tiparm(setab, rgb_quantize_256(
r, g, b)));
736 return fbuf_emit(f, tiparm(setab, rgb_quantize_8(
r, g, b)));
750 return term_esc_rgb(f,
true,
r, g, b);
759 return fbuf_emit(f, tiparm(setaf, rgb_quantize_256(
r, g, b)));
761 return fbuf_emit(f, tiparm(setaf, rgb_quantize_8(
r, g, b)));
782 if(fbuf_emit(f, tiparm(initc, damageidx,
r, g, b)) < 0){
795raster_defaults(
notcurses* nc,
bool fgdef,
bool bgdef,
fbuf* f){
804 if(!mustsetfg && !mustsetbg){
807 }
else if((mustsetfg && mustsetbg) || !fgop || !bgop){
808 if(fbuf_emit(f, op)){
818 if(fbuf_emit(f, fgop)){
825 if(fbuf_emit(f, bgop)){
839 unsigned palfg = nccell_fg_palindex(srccell);
844 if(term_fg_palindex(nc, f, palfg)){
858 unsigned palbg = nccell_bg_palindex(srccell);
862 if(term_bg_palindex(nc, f, palbg)){
890 int64_t bytesemitted = 0;
891 while( (s = *parent) ){
892 loginfo(
"phase 1 sprixel %u state %d loc %d/%d", s->
id,
900 int r = sprite_scrub(nc, p, s);
904 if( (*parent = s->
next) ){
950scroll_lastframe(
notcurses* nc,
unsigned rows){
956 for(
unsigned targy = 0 ; targy < rows ; ++targy){
957 for(
unsigned targx = 0 ; targx < nc->
lfdimx ; ++targx){
958 const size_t damageidx = targy * nc->
lfdimx + targx;
960 pool_release(&nc->
pool,
c);
966 for(
unsigned targy = 0 ; targy < nc->
lfdimy - rows ; ++targy){
967 const size_t dstidx = targy * nc->
lfdimx;
969 const size_t srcidx = dstidx + rows * nc->
lfdimx;
971 memcpy(dst, src,
sizeof(*dst) * nc->
lfdimx);
974 unsigned targy = nc->
lfdimy - rows;
975 while(targy < nc->lfdimy){
976 const size_t dstidx = targy * nc->
lfdimx;
978 memset(dst, 0,
sizeof(*dst) * nc->
lfdimx);
990 logdebug(
"order-%d scroll", scrolls);
1002 if(goto_location(p->
nc, f, p->
dimy, 0,
NULL)){
1008 if(raster_defaults(p->
nc,
false,
true, f)){
1012 return emit_scrolls_track(p->
nc, scrolls, f);
1026 int64_t bytesemitted = 0;
1029 while( (s = *parent) ){
1049 if(sprite_commit(&nc->
tcache, f, s,
false)){
1060 if( (*parent = s->
next) ){
1069 return bytesemitted;
1080 int64_t bytesemitted = 0;
1083 while( (s = *parent) ){
1097 return bytesemitted;
1118 bool saw_linefeed = 0;
1121 const size_t damageidx = innery * nc->
lfdimx + innerx;
1122 unsigned r, g, b, br, bg, bb;
1124 if(!rvec[damageidx].
s.damaged){
1128 if(nccell_wide_left_p(srccell)){
1131 }
else if(phase != 0 || !rvec[damageidx].
s.p_beats_sprixel){
1137 if(goto_location(nc, f,
y,
x, rvec[damageidx].
p)){
1142 if(term_setstyles(f, nc, srccell)){
1150 bool nobackground = nccell_nobackground_p(srccell);
1151 bool rgbequal = nccell_rgbequal_p(srccell);
1152 if((nccell_fg_default_p(srccell)) || (!nobackground && nccell_bg_default_p(srccell))){
1153 if(raster_defaults(nc, nccell_fg_default_p(srccell),
1154 !nobackground && nccell_bg_default_p(srccell), f)){
1158 if(nccell_fg_palindex_p(srccell)){
1159 if(emit_fg_palindex(nc, f, srccell)){
1162 }
else if(!nccell_fg_default_p(srccell)){
1167 nccell_fg_rgb8(srccell, &
r, &g, &b);
1187 }
else if(nccell_bg_palindex_p(srccell)){
1188 if(emit_bg_palindex(nc, f, srccell)){
1191 }
else if(!nccell_bg_default_p(srccell)){
1196 nccell_bg_rgb8(srccell, &br, &bg, &bb);
1200 if(term_bg_rgb8(&nc->
tcache, f, br, bg, bb)){
1213 pool_load_direct(&nc->
pool, srccell,
" ", 1, 1);
1222 && !rvec[damageidx].
s.p_beats_sprixel){
1227 if(term_putc(f, &nc->
pool, srccell)){
1231 saw_linefeed =
true;
1252 saw_linefeed =
false;
1280 update_palette(nc, f);
1281 int scrolls =
p->scrolls;
1283 int64_t sprixelbytes = clean_sprixels(nc,
p, f, scrolls);
1284 if(sprixelbytes < 0){
1288 if(rasterize_core(nc,
p, f, 0)){
1292 int64_t rasprixelbytes = rasterize_sprixels(nc,
p, f);
1293 if(rasprixelbytes < 0){
1296 sprixelbytes += rasprixelbytes;
1301 if(rasterize_scrolls(
p, f)){
1305 if(rasterize_core(nc,
p, f, 1)){
1308#define MIN_SUMODE_SIZE BUFSIZ
1313 if(fbuf_puts(f, endasu) < 0){
1323#undef MIN_SUMODE_SIZE
1335 unsigned useasu = basu ? 1 : 0;
1339 if(fbuf_puts(f, basu) < 0){
1343 if(notcurses_rasterize_inner(nc,
p, f, &useasu) < 0){
1353 moffset = strlen(basu);
1364 rasterize_sprixels_post(nc,
p);
1378 const int cursory = nc->
cursory;
1379 const int cursorx = nc->
cursorx;
1383 int ret = raster_and_write(nc,
p, f);
1389 if(fbuf_flush(f, nc->
ttyfp)){
1403 if(fbuf_emit(f, clearscr) == 0){
1411 if(goto_location(nc, f, 0, 0,
NULL)){
1418 if(notcurses_resize(nc, dimy, dimx)){
1434 const int count =
p.dimy *
p.dimx;
1435 p.crender = malloc(count *
sizeof(*
p.crender));
1436 if(
p.crender ==
NULL){
1439 init_rvec(
p.crender, count);
1440 for(
int i = 0 ; i < count ; ++i){
1441 p.crender[i].s.damaged = 1;
1443 int ret = notcurses_rasterize(nc, &
p, &nc->
rstate.
f);
1462 const unsigned count = (nc->
lfdimx >
p->dimx ? nc->
lfdimx :
p->dimx) *
1464 p->crender = malloc(count *
sizeof(*
p->crender));
1465 if(
p->crender ==
NULL){
1469 init_rvec(
p->crender, count);
1470 for(
unsigned i = 0 ; i < count ; ++i){
1471 p->crender[i].s.damaged = 1;
1473 int ret = raster_and_write(nc,
p, &f);
1476 if(fwrite(f.
buf, f.
used, 1, fp) == 1){
1494ncpile_render_internal(
ncpile*
p,
unsigned pgeo_changed){
1500 paint(pl, rvec,
p->dimy,
p->dimx, 0, 0, &sprixel_list, pgeo_changed);
1504 if(
p->sprixelcache){
1509 if( (
s->next =
p->sprixelcache) ){
1510 p->sprixelcache->prev =
s;
1513 p->sprixelcache = sprixel_list;
1518 struct timespec start, rasterdone, writedone;
1519 clock_gettime(CLOCK_MONOTONIC, &start);
1520 ncpile* pile = ncplane_pile(
n);
1521 struct notcurses* nc = ncpile_notcurses(pile);
1524 clock_gettime(CLOCK_MONOTONIC, &rasterdone);
1525 int bytes = notcurses_rasterize(nc, pile, &nc->
rstate.
f);
1526 clock_gettime(CLOCK_MONOTONIC, &writedone);
1549engorge_crender_vector(
ncpile* p){
1553 const size_t crenderlen = p->
dimy * p->
dimx;
1556 loginfo(
"resizing rvec (%" PRIuPTR
") for %p to %" PRIuPTR,
1558 struct crender* tmp = realloc(
p->crender,
sizeof(*tmp) * crenderlen);
1563 p->crenderlen = crenderlen;
1565 init_rvec(
p->crender, crenderlen);
1571 struct timespec start, renderdone;
1572 clock_gettime(CLOCK_MONOTONIC, &start);
1574 ncpile* pile = ncplane_pile(
n);
1576 unsigned pgeo_changed = 0;
1577 notcurses_resize_internal(
n,
NULL,
NULL);
1583 if(engorge_crender_vector(pile)){
1586 ncpile_render_internal(pile, pgeo_changed);
1587 clock_gettime(CLOCK_MONOTONIC, &renderdone);
1600 unsigned useasu =
false;
1602 int bytes = notcurses_rasterize_inner(nc, ncplane_pile(p), &nc->
rstate.
f, &useasu);
1619 if(cell_simple_p(
c)){
1620 return strdup((
const char*)&
c->
gcluster);
1622 return strdup(egcpool_extended_gcluster(
e,
c));
1631 logerror(
"invalid coordinates: %u/%u", yoff, xoff);
1635 logerror(
"invalid coordinates: %u/%u", yoff, xoff);
1639 if(nccell_wide_right_p(srccell)){
1649 return pool_egc_copy(&nc->
pool, srccell);
1653 if(rgb > 0xffffffu){
1656 if(!ncdirect_bg_default_p(nc) && !ncdirect_bg_palindex_p(nc)
1657 && ncchannels_bg_rgb(nc->
channels) == rgb){
1660 if(term_bg_rgb8(&nc->
tcache, f, (rgb & 0xff0000u) >> 16u, (rgb & 0xff00u) >> 8u, rgb & 0xffu)){
1663 ncchannels_set_bg_rgb(&nc->
channels, rgb);
1669 if(fbuf_init_small(&f)){
1676 if(fbuf_finalize(&f, nc->
ttyfp) < 0){
1683 if(rgb > 0xffffffu){
1686 if(!ncdirect_fg_default_p(nc) && !ncdirect_fg_palindex_p(nc)
1687 && ncchannels_fg_rgb(nc->
channels) == rgb){
1690 if(
term_fg_rgb8(&nc->
tcache, f, (rgb & 0xff0000u) >> 16u, (rgb & 0xff00u) >> 8u, rgb & 0xffu)){
1693 ncchannels_set_fg_rgb(&nc->
channels, rgb);
1699 if(fbuf_init_small(&f)){
1706 if(fbuf_finalize(&f, nc->
ttyfp) < 0){
1715 logerror(
"default foreground could not be determined");
1725 logerror(
"default background could not be determined");
1740 logerror(
"illegal cursor placement: %d, %d",
y,
x);
1749 if(fbuf_init_small(&f)){
1759 if(!cnorm || fbuf_emit(&f, cnorm)){
1764 if(fbuf_finalize(&f, nc->
ttyfp)){
void update_render_stats(const struct timespec *time1, const struct timespec *time0, ncstats *stats)
int update_term_dimensions(unsigned *rows, unsigned *cols, tinfo *tcache, int margin_b, unsigned *cgeo_changed, unsigned *pgeo_changed) __attribute__((nonnull(3
void update_write_stats(const struct timespec *time1, const struct timespec *time0, ncstats *stats, int bytes)
int sprite_wipe(const notcurses *nc, sprixel *s, int y, int x)
void sprixel_invalidate(sprixel *s, int y, int x)
void update_raster_stats(const struct timespec *time1, const struct timespec *time0, ncstats *stats)
void sprixel_free(sprixel *s)
void update_raster_bytes(ncstats *stats, int bytes)
#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 notcurses * ncplane_notcurses_const(const ncplane *n)
int ncplane_resize_maximize(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 NCALPHA_TRANSPARENT
#define NCALPHA_HIGHCONTRAST
int notcurses_cursor_yx(const notcurses *nc, int *y, int *x)
int ncdirect_set_bg_rgb_f(ncdirect *nc, unsigned rgb, fbuf *f)
int ncdirect_set_fg_rgb_f(ncdirect *nc, unsigned rgb, fbuf *f)
int notcurses_cursor_enable(notcurses *nc, int y, int x)
char * notcurses_at_yx(notcurses *nc, unsigned yoff, unsigned xoff, uint16_t *stylemask, uint64_t *channels)
int term_fg_rgb8(const tinfo *ti, fbuf *f, unsigned r, unsigned g, unsigned b)
void nccell_release(ncplane *n, nccell *c)
int ncpile_render(ncplane *n)
int ncplane_mergedown(ncplane *restrict src, ncplane *restrict dst, int begsrcy, int begsrcx, unsigned leny, unsigned lenx, int dsty, int dstx)
int notcurses_default_foreground(const struct notcurses *nc, uint32_t *fg)
int ncpile_rasterize(ncplane *n)
int ncdirect_set_bg_rgb(ncdirect *nc, unsigned rgb)
int ncdirect_set_fg_rgb(ncdirect *nc, unsigned rgb)
int ncpile_render_to_buffer(ncplane *p, char **buf, size_t *buflen)
int notcurses_cursor_disable(notcurses *nc)
int nccell_duplicate(ncplane *n, nccell *targ, const nccell *c)
int ncpile_render_to_file(ncplane *n, FILE *fp)
sig_atomic_t sigcont_seen_for_render
__attribute__((nonnull(1, 2, 7)))
int ncplane_mergedown_simple(ncplane *restrict src, ncplane *restrict dst)
int notcurses_refresh(notcurses *nc, unsigned *restrict dimy, unsigned *restrict dimx)
int notcurses_default_background(const struct notcurses *nc, uint32_t *bg)
int clear_and_home(notcurses *nc, tinfo *ti, fbuf *f)
int sprixel_rescale(sprixel *spx, unsigned ncellpxy, unsigned ncellpxx)
@ SPRIXCELL_ANNIHILATED_TRANS
uint32_t chans[NCPALETTESIZE]
uint64_t defaultemissions
uint64_t sprixelemissions
bool palette_damage[NCPALETTESIZE]
int(* pixel_draw_late)(const struct tinfo *, struct sprixel *s, int yoff, int xoff)
int(* pixel_remove)(int id, fbuf *f)
uint32_t bg_collides_default
int(* pixel_commit)(fbuf *f, struct sprixel *s, unsigned noscroll)
void(* pixel_refresh)(const struct ncpile *p, struct sprixel *s)
void(* pixel_scroll)(const struct ncpile *p, struct tinfo *, int rows)
int block_signals(sigset_t *old_blocked_signals)
int unblock_signals(const sigset_t *old_blocked_signals)