Notcurses 3.0.13
a blingful library for TUIs and character graphics
Loading...
Searching...
No Matches
notcurses.c File Reference
#include "linux.h"
#include "version.h"
#include "egcpool.h"
#include "internal.h"
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <unistr.h>
#include <locale.h>
#include <uniwbrk.h>
#include <inttypes.h>
#include "compat/compat.h"
#include "unixsig.h"
#include "banner.h"
Include dependency graph for notcurses.c:

Go to the source code of this file.

Macros

#define ESC   "\x1b"
 
#define TABSTOP   8
 
#define PTHREAD_MUTEX_RECURSIVE_NP   PTHREAD_MUTEX_RECURSIVE
 

Functions

void notcurses_version_components (int *major, int *minor, int *patch, int *tweak)
 
int notcurses_enter_alternate_screen (notcurses *nc)
 
int notcurses_leave_alternate_screen (notcurses *nc)
 
int reset_term_attributes (const tinfo *ti, fbuf *f)
 
int reset_term_palette (const tinfo *ti, fbuf *f, unsigned touchedpalette)
 
const char * notcurses_version (void)
 
void * ncplane_set_userptr (ncplane *n, void *opaque)
 
void * ncplane_userptr (ncplane *n)
 
const void * ncplane_userptr_const (const ncplane *n)
 
char * ncplane_at_cursor (const ncplane *n, uint16_t *stylemask, uint64_t *channels)
 
char * ncplane_at_yx (const ncplane *n, int y, int x, uint16_t *stylemask, uint64_t *channels)
 
int ncplane_at_cursor_cell (ncplane *n, nccell *c)
 
int ncplane_at_yx_cell (ncplane *n, int y, int x, nccell *c)
 
void ncplane_dim_yx (const ncplane *n, unsigned *rows, unsigned *cols)
 
int update_term_dimensions (unsigned *rows, unsigned *cols, tinfo *tcache, int margin_b, unsigned *cgeo_changed, unsigned *pgeo_changed)
 
void free_plane (ncplane *p)
 
 __attribute__ ((malloc))
 
ncplanencplane_new_internal (notcurses *nc, ncplane *n, const ncplane_options *nopts)
 
ncplanenotcurses_stdplane (notcurses *nc)
 
const ncplanenotcurses_stdplane_const (const notcurses *nc)
 
ncplanencplane_create (ncplane *n, const ncplane_options *nopts)
 
ncplanencpile_create (notcurses *nc, const struct ncplane_options *nopts)
 
void ncplane_home (ncplane *n)
 
int ncplane_cursor_move_yx (ncplane *n, int y, int x)
 
int ncplane_cursor_move_rel (ncplane *n, int y, int x)
 
ncplanencplane_dup (const ncplane *n, void *opaque)
 
int resize_callbacks_children (ncplane *n)
 
int ncplane_resize_internal (ncplane *n, int keepy, int keepx, unsigned keepleny, unsigned keeplenx, int yoff, int xoff, unsigned ylen, unsigned xlen)
 
int ncplane_resize (ncplane *n, int keepy, int keepx, unsigned keepleny, unsigned keeplenx, int yoff, int xoff, unsigned ylen, unsigned xlen)
 
int ncplane_destroy (ncplane *ncp)
 
int ncplane_destroy_family (ncplane *ncp)
 
void init_lang (void)
 
ncpixelimpl_e notcurses_check_pixel_support (const notcurses *nc)
 
 __attribute__ ((nonnull(2)))
 
notcursesnotcurses_core_init (const notcurses_options *opts, FILE *outfp)
 
void notcurses_drop_planes (notcurses *nc)
 
int notcurses_stop (notcurses *nc)
 
uint64_t ncplane_channels (const ncplane *n)
 
void ncplane_set_channels (ncplane *n, uint64_t channels)
 
uint16_t ncplane_styles (const ncplane *n)
 
void ncplane_set_fg_default (ncplane *n)
 
void ncplane_set_bg_default (ncplane *n)
 
void ncplane_set_bg_rgb8_clipped (ncplane *n, int r, int g, int b)
 
int ncplane_set_bg_rgb8 (ncplane *n, unsigned r, unsigned g, unsigned b)
 
void ncplane_set_fg_rgb8_clipped (ncplane *n, int r, int g, int b)
 
int ncplane_set_fg_rgb8 (ncplane *n, unsigned r, unsigned g, unsigned b)
 
int ncplane_set_fg_rgb (ncplane *n, unsigned channel)
 
uint64_t ncplane_set_bchannel (ncplane *n, uint32_t channel)
 
uint64_t ncplane_set_fchannel (ncplane *n, uint32_t channel)
 
int ncplane_set_bg_rgb (ncplane *n, unsigned channel)
 
int ncplane_set_fg_alpha (ncplane *n, int alpha)
 
int ncplane_set_bg_alpha (ncplane *n, int alpha)
 
int ncplane_set_fg_palindex (ncplane *n, unsigned idx)
 
int ncplane_set_bg_palindex (ncplane *n, unsigned idx)
 
int ncplane_set_base_cell (ncplane *ncp, const nccell *c)
 
int ncplane_set_base (ncplane *ncp, const char *egc, uint16_t stylemask, uint64_t channels)
 
int ncplane_base (ncplane *ncp, nccell *c)
 
const char * nccell_extended_gcluster (const ncplane *n, const nccell *c)
 
int ncplane_move_above (ncplane *restrict n, ncplane *restrict above)
 
int ncplane_move_below (ncplane *restrict n, ncplane *restrict below)
 
int ncplane_move_family_above (ncplane *restrict n, ncplane *restrict bpoint)
 
int ncplane_move_family_below (ncplane *restrict n, ncplane *restrict bpoint)
 
void ncplane_cursor_yx (const ncplane *n, unsigned *y, unsigned *x)
 
void scroll_down (ncplane *n)
 
int ncplane_scrollup (ncplane *n, int r)
 
int ncplane_scrollup_child (ncplane *n, const ncplane *child)
 
int nccell_load (ncplane *n, nccell *c, const char *gcluster)
 
int ncplane_putc_yx (ncplane *n, int y, int x, const nccell *c)
 
int ncplane_putegc_yx (ncplane *n, int y, int x, const char *gclust, size_t *sbytes)
 
int ncplane_putchar_stained (ncplane *n, char c)
 
int ncplane_putwegc_stained (ncplane *n, const wchar_t *gclust, size_t *sbytes)
 
int ncplane_putegc_stained (ncplane *n, const char *gclust, size_t *sbytes)
 
int ncplane_cursor_at (const ncplane *n, nccell *c, char **gclust)
 
uint16_t notcurses_supported_styles (const notcurses *nc)
 
unsigned notcurses_palette_size (const notcurses *nc)
 
char * notcurses_detected_terminal (const notcurses *nc)
 
void ncplane_set_styles (ncplane *n, unsigned stylebits)
 
void ncplane_on_styles (ncplane *n, unsigned stylebits)
 
void ncplane_off_styles (ncplane *n, unsigned stylebits)
 
char * ncplane_vprintf_prep (const char *format, va_list ap)
 
int ncplane_vprintf_yx (ncplane *n, int y, int x, const char *format, va_list ap)
 
int ncplane_vprintf_aligned (ncplane *n, int y, ncalign_e align, const char *format, va_list ap)
 
int ncplane_vprintf_stained (struct ncplane *n, const char *format, va_list ap)
 
int ncplane_putnstr_aligned (struct ncplane *n, int y, ncalign_e align, size_t s, const char *str)
 
int ncplane_hline_interp (ncplane *n, const nccell *c, unsigned len, uint64_t c1, uint64_t c2)
 
int ncplane_vline_interp (ncplane *n, const nccell *c, unsigned len, uint64_t c1, uint64_t c2)
 
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 ncplane_move_yx (ncplane *n, int y, int x)
 
int ncplane_y (const ncplane *n)
 
int ncplane_x (const ncplane *n)
 
void ncplane_yx (const ncplane *n, int *y, int *x)
 
void ncplane_erase (ncplane *n)
 
int ncplane_erase_region (ncplane *n, int ystart, int xstart, int ylen, int xlen)
 
ncplanencpile_top (ncplane *n)
 
ncplanencpile_bottom (ncplane *n)
 
ncplanencplane_below (ncplane *n)
 
ncplanencplane_above (ncplane *n)
 
int notcurses_mice_enable (notcurses *n, unsigned eventmask)
 
ncpalettencpalette_new (notcurses *nc)
 
int ncpalette_use (notcurses *nc, const ncpalette *p)
 
void ncpalette_free (ncpalette *p)
 
bool ncplane_translate_abs (const ncplane *n, int *restrict y, int *restrict x)
 
void ncplane_translate (const ncplane *src, const ncplane *dst, int *restrict y, int *restrict x)
 
notcursesncplane_notcurses (const ncplane *n)
 
const notcursesncplane_notcurses_const (const ncplane *n)
 
int ncplane_abs_y (const ncplane *n)
 
int ncplane_abs_x (const ncplane *n)
 
void ncplane_abs_yx (const ncplane *n, int *RESTRICT y, int *RESTRICT x)
 
ncplanencplane_parent (ncplane *n)
 
const ncplanencplane_parent_const (const ncplane *n)
 
int ncplane_set_name (ncplane *n, const char *name)
 
char * ncplane_name (const ncplane *n)
 
void ncplane_set_resizecb (ncplane *n, int(*resizecb)(ncplane *))
 
int ncplane_resize_placewithin (ncplane *n)
 
int ncplane_resize_marginalized (ncplane *n)
 
int ncplane_resize_maximize (ncplane *n)
 
int ncplane_resize_realign (ncplane *n)
 
ncplanencplane_reparent (ncplane *n, ncplane *newparent)
 
ncplanencplane_reparent_family (ncplane *n, ncplane *newparent)
 
bool ncplane_set_scrolling (ncplane *n, unsigned scrollp)
 
bool ncplane_scrolling_p (const ncplane *n)
 
bool ncplane_set_autogrow (ncplane *n, unsigned growp)
 
bool ncplane_autogrow_p (const ncplane *n)
 
int notcurses_lex_scalemode (const char *op, ncscale_e *scalemode)
 
const char * notcurses_str_scalemode (ncscale_e scalemode)
 
int notcurses_lex_margins (const char *op, notcurses_options *opts)
 
int notcurses_inputready_fd (notcurses *n)
 
int ncdirect_inputready_fd (ncdirect *n)
 
uint32_t * ncplane_as_rgba (const ncplane *nc, ncblitter_e blit, int begy, int begx, unsigned leny, unsigned lenx, unsigned *pxdimy, unsigned *pxdimx)
 
char * ncplane_contents (ncplane *nc, int begy, int begx, unsigned leny, unsigned lenx)
 
void ncplane_center_abs (const ncplane *n, int *RESTRICT y, int *RESTRICT x)
 
int ncplane_putwstr_stained (ncplane *n, const wchar_t *gclustarr)
 
int notcurses_ucs32_to_utf8 (const uint32_t *ucs32, unsigned ucs32count, unsigned char *resultbuf, size_t buflen)
 
int ncstrwidth (const char *egcs, int *validbytes, int *validwidth)
 
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)
 
const nccapabilitiesnotcurses_capabilities (const notcurses *n)
 

Variables

int(*)(ncplane *) ncplane_resizecb (const ncplane *n)
 

Macro Definition Documentation

◆ ESC

#define ESC   "\x1b"

Definition at line 21 of file notcurses.c.

◆ PTHREAD_MUTEX_RECURSIVE_NP

#define PTHREAD_MUTEX_RECURSIVE_NP   PTHREAD_MUTEX_RECURSIVE

◆ TABSTOP

#define TABSTOP   8

Definition at line 22 of file notcurses.c.

Function Documentation

◆ __attribute__() [1/2]

__attribute__ ( (malloc)  )

Definition at line 501 of file notcurses.c.

503 {
504 ncpile* ret = malloc(sizeof(*ret));
505 if(ret){
506 ret->nc = nc;
507 ret->top = n;
508 ret->bottom = n;
509 ret->roots = n;
510 n->bprev = &ret->roots;
511 if(nc->stdplane){ // stdplane (and thus stdpile) has already been created
512 ret->prev = ncplane_pile(nc->stdplane)->prev;
513 ncplane_pile(nc->stdplane)->prev->next = ret;
514 ret->next = ncplane_pile(nc->stdplane);
515 ncplane_pile(nc->stdplane)->prev = ret;
516 }else{
517 ret->prev = ret;
518 ret->next = ret;
519 }
520 n->above = NULL;
521 n->below = NULL;
522 ret->dimy = nc->tcache.dimy;
523 ret->dimx = nc->tcache.dimx;
524 ret->cellpxy = nc->tcache.cellpxy;
525 ret->cellpxx = nc->tcache.cellpxx;
526 ret->crender = NULL;
527 ret->crenderlen = 0;
528 ret->sprixelcache = NULL;
529 ret->scrolls = 0;
530 }
531 n->pile = ret;
532 return ret;
533}
vopts n
Definition notcurses.h:3502
unsigned cellpxx
Definition internal.h:326
struct ncpile * next
Definition internal.h:323
ncplane * bottom
Definition internal.h:319
sprixel * sprixelcache
Definition internal.h:328
unsigned dimx
Definition internal.h:325
struct ncpile * prev
Definition internal.h:323
size_t crenderlen
Definition internal.h:324
struct notcurses * nc
Definition internal.h:322
ncplane * roots
Definition internal.h:320
unsigned dimy
Definition internal.h:325
struct crender * crender
Definition internal.h:321
int scrolls
Definition internal.h:327
unsigned cellpxy
Definition internal.h:326
ncplane * top
Definition internal.h:318
struct ncplane ** bprev
Definition internal.h:101
return NULL
Definition termdesc.h:229

◆ __attribute__() [2/2]

__attribute__ ( (nonnull(2))  )

Definition at line 1169 of file notcurses.c.

1170 {
1171 if(fwide(fp, 0) > 0){
1172 fprintf(stderr, "error: output stream is wide-oriented");
1173 return NULL;
1174 }
1175 notcurses* ret = malloc(sizeof(*ret));
1176 if(ret == NULL){
1177 return ret;
1178 }
1179 memset(ret, 0, sizeof(*ret));
1180 if(opts){
1181 if(opts->flags >= (NCOPTION_SCROLLING << 1u)){
1182 fprintf(stderr, "warning: unknown Notcurses options %016" PRIu64, opts->flags);
1183 }
1184 if(opts->termtype){
1185 if(putenv_term(opts->termtype)){
1186 free(ret);
1187 return NULL;
1188 }
1189 }
1190 ret->flags = opts->flags;
1191 ret->margin_t = opts->margin_t;
1192 ret->margin_b = opts->margin_b;
1193 ret->margin_l = opts->margin_l;
1194 ret->margin_r = opts->margin_r;
1195 ret->loglevel = opts->loglevel;
1196 }
1198 if(!(ret->flags & NCOPTION_INHIBIT_SETLOCALE)){
1199 init_lang();
1200 }
1201//fprintf(stderr, "getenv LC_ALL: %s LC_CTYPE: %s\n", getenv("LC_ALL"), getenv("LC_CTYPE"));
1202 const char* encoding = nl_langinfo(CODESET);
1203 if(encoding && encoding_is_utf8(encoding)){
1204 *utf8 = true;
1205 }else{
1206 *utf8 = false;
1207 if(encoding && (strcmp(encoding, "ANSI_X3.4-1968") &&
1208 strcmp(encoding, "US-ASCII") &&
1209 strcmp(encoding, "ASCII"))){
1210 fprintf(stderr, "encoding (\"%s\") was neither ANSI_X3.4-1968 nor UTF-8, refusing to start\n did you call setlocale()?\n",
1211 encoding ? encoding : "none found");
1212 free(ret);
1213 return NULL;
1214 }
1215 }
1216 ret->cursory = ret->cursorx = -1;
1217 reset_stats(&ret->stats.s);
1219 ret->ttyfp = fp;
1220 egcpool_init(&ret->pool);
1222 fprintf(stderr, "invalid loglevel %d", ret->loglevel);
1223 free(ret);
1224 return NULL;
1225 }
1226 if(recursive_lock_init(&ret->pilelock)){
1227 fprintf(stderr, "couldn't initialize pile mutex");
1228 free(ret);
1229 return NULL;
1230 }
1231 if(pthread_mutex_init(&ret->stats.lock, NULL)){
1232 pthread_mutex_destroy(&ret->pilelock);
1233 free(ret);
1234 return NULL;
1235 }
1236 if(*utf8){
1238 }
1239 return ret;
1240}
free(duplicated)
int putenv_term(const char *termname) __attribute__((nonnull(1)))
Definition termdesc.c:1632
void reset_stats(ncstats *stats)
Definition stats.c:74
int set_loglevel_from_env(ncloglevel_e *loglevel) __attribute__((nonnull(1)))
Definition util.c:19
void ncmetric_use_utf8(void)
Definition metric.c:24
void init_lang(void)
Definition notcurses.c:1094
#define NCOPTION_INHIBIT_SETLOCALE
Definition notcurses.h:990
const struct ncplane_options * opts
Definition notcurses.h:3483
#define NCOPTION_SCROLLING
Definition notcurses.h:1034
@ NCLOGLEVEL_SILENT
Definition notcurses.h:969
@ NCLOGLEVEL_TRACE
Definition notcurses.h:977
unsigned margin_r
Definition notcurses.h:1473
unsigned margin_b
Definition notcurses.h:1473
ncstats s
Definition internal.h:247
pthread_mutex_t lock
Definition internal.h:246
ncstats stashed_stats
Definition internal.h:357
pthread_mutex_t pilelock
Definition internal.h:361
int cursorx
Definition internal.h:354
uint64_t flags
Definition internal.h:369
int margin_l
Definition internal.h:364
ncsharedstats stats
Definition internal.h:356
int cursory
Definition internal.h:353
FILE * ttyfp
Definition internal.h:359
int margin_t
Definition internal.h:364
int margin_b
Definition internal.h:364
egcpool pool
Definition internal.h:348
int margin_r
Definition internal.h:364
int loglevel
Definition internal.h:365
Here is the call graph for this function:

◆ free_plane()

void free_plane ( ncplane p)

Definition at line 464 of file notcurses.c.

464 {
465 if(p){
466 // ncdirect fakes an ncplane with no ->pile
467 if(ncplane_pile(p)){
469 pthread_mutex_lock(&nc->stats.lock);
471 ncplane_notcurses(p)->stats.s.fbbytes -= sizeof(*p->fb) * p->leny * p->lenx;
472 pthread_mutex_unlock(&nc->stats.lock);
473 if(p->above == NULL && p->below == NULL){
474 pthread_mutex_lock(&nc->pilelock);
475 ncpile_destroy(ncplane_pile(p));
476 pthread_mutex_unlock(&nc->pilelock);
477 }
478 }
479 if(p->widget){
480 void* w = p->widget;
481 void (*wdestruct)(void*) = p->wdestruct;
482 p->widget = NULL;
483 p->wdestruct = NULL;
484 logdebug("calling widget destructor %p(%p)", wdestruct, w);
485 wdestruct(w);
486 logdebug("got the widget");
487 }
488 if(p->sprite){
490 }
491 destroy_tam(p);
492 egcpool_dump(&p->pool);
493 free(p->name);
494 free(p->fb);
495 free(p);
496 }
497}
void sprixel_hide(sprixel *s)
Definition sprite.c:83
#define logdebug(fmt,...)
Definition logging.h:52
notcurses * ncplane_notcurses(const ncplane *n)
Definition notcurses.c:2626
struct ncplane * below
Definition internal.h:94
sprixel * sprite
Definition internal.h:105
unsigned lenx
Definition internal.h:86
struct ncplane * above
Definition internal.h:93
char * name
Definition internal.h:111
void(* wdestruct)(void *)
Definition internal.h:124
unsigned leny
Definition internal.h:86
void * widget
Definition internal.h:123
egcpool pool
Definition internal.h:87
nccell * fb
Definition internal.h:77
unsigned planes
Definition notcurses.h:1820
uint64_t fbbytes
Definition notcurses.h:1819
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_lang()

void init_lang ( void  )

Definition at line 1094 of file notcurses.c.

1094 {
1095#ifdef __MINGW32__
1096 if(setlocale(LC_ALL, ".UTF8") == NULL){
1097 logwarn("couldn't set LC_ALL to utf8");
1098 }
1099#endif
1100 const char* encoding = nl_langinfo(CODESET);
1101 if(encoding && encoding_is_utf8(encoding)){
1102 return; // already utf-8, great!
1103 }
1104 const char* lang = getenv("LANG");
1105 // if LANG was explicitly set to C/POSIX, life sucks, roll with it
1106 if(lang && (!strcmp(lang, "C") || !strcmp(lang, "POSIX"))){
1107 loginfo("LANG was explicitly set to %s, not changing locale", lang);
1108 return;
1109 }
1110#ifndef __MINGW32__
1111 if(setlocale(LC_ALL, "") == NULL){
1112 logwarn("setting locale based on LANG failed");
1113 }
1114#endif
1115 encoding = nl_langinfo(CODESET);
1116 if(encoding && encoding_is_utf8(encoding)){
1117 loginfo("set locale from LANG; client should call setlocale(2)!");
1118 return;
1119 }
1120 setlocale(LC_CTYPE, "C.UTF-8");
1121 encoding = nl_langinfo(CODESET);
1122 if(encoding && encoding_is_utf8(encoding)){
1123 loginfo("forced UTF-8 encoding; client should call setlocale(2)!");
1124 return;
1125 }
1126}
#define loginfo(fmt,...)
Definition logging.h:42
#define logwarn(fmt,...)
Definition logging.h:37
Here is the caller graph for this function:

◆ nccell_extended_gcluster()

const char * nccell_extended_gcluster ( const ncplane n,
const nccell c 
)

Definition at line 1573 of file notcurses.c.

1573 {
1574 if(cell_simple_p(c)){
1575 return (const char*)&c->gcluster;
1576 }
1577 return egcpool_extended_gcluster(&n->pool, c);
1578}
const nccell * c
Definition egcpool.h:296
uint32_t gcluster
Definition notcurses.h:693
Here is the caller graph for this function:

◆ nccell_load()

int nccell_load ( ncplane n,
nccell c,
const char *  gcluster 
)

Definition at line 1833 of file notcurses.c.

1833 {
1834 int cols;
1835 int bytes = utf8_egc_len(gcluster, &cols);
1836 return pool_load_direct(&n->pool, c, gcluster, bytes, cols);
1837}
Here is the caller graph for this function:

◆ ncdirect_inputready_fd()

int ncdirect_inputready_fd ( ncdirect n)

Definition at line 3095 of file notcurses.c.

3095 {
3096 return inputready_fd(n->tcache.ictx);
3097}
int inputready_fd(const inputctx *ictx)
Definition in.c:2661
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncpalette_free()

void ncpalette_free ( ncpalette p)

Definition at line 2586 of file notcurses.c.

2586 {
2587 free(p);
2588}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncpalette_new()

ncpalette * ncpalette_new ( notcurses nc)

Definition at line 2563 of file notcurses.c.

2563 {
2564 ncpalette* p = malloc(sizeof(*p));
2565 if(p){
2566 memcpy(p, &nc->palette, sizeof(*p));
2567 }
2568 return p;
2569}
ncpalette palette
Definition internal.h:366
Here is the caller graph for this function:

◆ ncpalette_use()

int ncpalette_use ( notcurses nc,
const ncpalette p 
)

Definition at line 2571 of file notcurses.c.

2571 {
2572 int ret = -1;
2573 if(!notcurses_canchangecolor(nc)){
2574 return -1;
2575 }
2576 for(size_t z = 0 ; z < sizeof(p->chans) / sizeof(*p->chans) ; ++z){
2577 if(nc->palette.chans[z] != p->chans[z]){
2578 nc->palette.chans[z] = p->chans[z];
2579 nc->palette_damage[z] = true;
2580 }
2581 }
2582 ret = 0;
2583 return ret;
2584}
uint32_t chans[NCPALETTESIZE]
Definition notcurses.h:1585
bool palette_damage[NCPALETTESIZE]
Definition internal.h:367
Here is the caller graph for this function:

◆ ncpile_bottom()

ncplane * ncpile_bottom ( ncplane n)

Definition at line 2544 of file notcurses.c.

2544 {
2545 return ncplane_pile(n)->bottom;
2546}
Here is the caller graph for this function:

◆ ncpile_create()

ncplane * ncpile_create ( notcurses nc,
const struct ncplane_options nopts 
)

Definition at line 711 of file notcurses.c.

711 {
712 return ncplane_new_internal(nc, NULL, nopts);
713}
ncplane * ncplane_new_internal(notcurses *nc, ncplane *n, const ncplane_options *nopts)
Definition notcurses.c:557
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncpile_top()

ncplane * ncpile_top ( ncplane n)

Definition at line 2540 of file notcurses.c.

2540 {
2541 return ncplane_pile(n)->top;
2542}
Here is the caller graph for this function:

◆ ncplane_above()

ncplane * ncplane_above ( ncplane n)

Definition at line 2552 of file notcurses.c.

2552 {
2553 return n->above;
2554}
Here is the caller graph for this function:

◆ ncplane_abs_x()

int ncplane_abs_x ( const ncplane n)

Definition at line 2638 of file notcurses.c.

2638 {
2639 return n->absx;
2640}
Here is the caller graph for this function:

◆ ncplane_abs_y()

int ncplane_abs_y ( const ncplane n)

Definition at line 2634 of file notcurses.c.

2634 {
2635 return n->absy;
2636}
Here is the caller graph for this function:

◆ ncplane_abs_yx()

void ncplane_abs_yx ( const ncplane n,
int *RESTRICT  y,
int *RESTRICT  x 
)

Definition at line 2642 of file notcurses.c.

2642 {
2643 if(y){
2644 *y = ncplane_abs_y(n);
2645 }
2646 if(x){
2647 *x = ncplane_abs_x(n);
2648 }
2649}
int ncplane_abs_x(const ncplane *n)
Definition notcurses.c:2638
int ncplane_abs_y(const ncplane *n)
Definition notcurses.c:2634
int y
Definition notcurses.h:1905
int int x
Definition notcurses.h:1905
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_as_rgba()

uint32_t * ncplane_as_rgba ( const ncplane nc,
ncblitter_e  blit,
int  begy,
int  begx,
unsigned  leny,
unsigned  lenx,
unsigned *  pxdimy,
unsigned *  pxdimx 
)

Definition at line 3214 of file notcurses.c.

3216 {
3217 unsigned px, py;
3218 if(!pxdimy){
3219 pxdimy = &py;
3220 }
3221 if(!pxdimx){
3222 pxdimx = &px;
3223 }
3224 return ncplane_as_rgba_internal(nc, blit, begy, begx, leny, lenx, pxdimy, pxdimx);
3225}
Here is the caller graph for this function:

◆ ncplane_at_cursor()

char * ncplane_at_cursor ( const ncplane n,
uint16_t *  stylemask,
uint64_t *  channels 
)

Definition at line 210 of file notcurses.c.

210 {
211 return ncplane_at_yx(n, n->y, n->x, stylemask, channels);
212}
char * ncplane_at_yx(const ncplane *n, int y, int x, uint16_t *stylemask, uint64_t *channels)
Definition notcurses.c:214
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_at_cursor_cell()

int ncplane_at_cursor_cell ( ncplane n,
nccell c 
)

Definition at line 266 of file notcurses.c.

266 {
267 return ncplane_at_yx_cell(n, n->y, n->x, c);
268}
int ncplane_at_yx_cell(ncplane *n, int y, int x, nccell *c)
Definition notcurses.c:270
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_at_yx()

char * ncplane_at_yx ( const ncplane n,
int  y,
int  x,
uint16_t *  stylemask,
uint64_t *  channels 
)

Definition at line 214 of file notcurses.c.

214 {
215 if(y < 0){
216 if(y != -1){
217 logerror("invalid y: %d", y);
218 return NULL;
219 }
220 y = n->y;
221 }
222 if(x < 0){
223 if(x != -1){
224 logerror("invalid x: %d", x);
225 return NULL;
226 }
227 x = n->x;
228 }
229 if((unsigned)y >= n->leny || (unsigned)x >= n->lenx){
230 logerror("invalid coordinates: %d/%d", y, x);
231 return NULL;
232 }
233 if(n->sprite){
234 if(stylemask){
235 *stylemask = 0;
236 }
237 if(channels){
238 *channels = 0;
239 }
240 return strdup(n->sprite->glyph.buf);
241 }
242 const nccell* yx = &n->fb[nfbcellidx(n, y, x)];
243 // if we're the right side of a wide glyph, we return the main glyph
244 if(nccell_wide_right_p(yx)){
245 return ncplane_at_yx(n, y, x - 1, stylemask, channels);
246 }
247 char* ret = nccell_extract(n, yx, stylemask, channels);
248 if(ret == NULL){
249 return NULL;
250 }
251//fprintf(stderr, "GOT [%s]\n", ret);
252 if(strcmp(ret, "") == 0){
253 free(ret);
254 ret = nccell_strdup(n, &n->basecell);
255 if(ret == NULL){
256 return NULL;
257 }
258 if(stylemask){
259 *stylemask = n->basecell.stylemask;
260 }
261 }
262 // FIXME load basecell channels if appropriate
263 return ret;
264}
#define logerror(fmt,...)
Definition logging.h:32
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_at_yx_cell()

int ncplane_at_yx_cell ( ncplane n,
int  y,
int  x,
nccell c 
)

Definition at line 270 of file notcurses.c.

270 {
271 if(n->sprite){
272 logerror("invoked on a sprixel plane");
273 return -1;
274 }
275 if(y < 0){
276 if(y != -1){
277 logerror("invalid y: %d", y);
278 return -1;
279 }
280 y = n->y;
281 }
282 if(x < 0){
283 if(x != -1){
284 logerror("invalid x: %d", x);
285 return -1;
286 }
287 x = n->x;
288 }
289 if((unsigned)y >= n->leny || (unsigned)x >= n->lenx){
290 logerror("invalid coordinates: %d/%d", y, x);
291 return -1;
292 }
293 nccell* targ = ncplane_cell_ref_yx(n, y, x);
294 if(nccell_duplicate(n, c, targ)){
295 return -1;
296 }
297 // FIXME take base cell into account where necessary!
298 return strlen(nccell_extended_gcluster(n, targ));
299}
const char * nccell_extended_gcluster(const ncplane *n, const nccell *c)
Definition notcurses.c:1573
int nccell_duplicate(ncplane *n, nccell *targ, const nccell *c)
Definition render.c:133
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_autogrow_p()

bool ncplane_autogrow_p ( const ncplane n)

Definition at line 3013 of file notcurses.c.

3013 {
3014 return n->autogrow;
3015}

◆ ncplane_base()

int ncplane_base ( ncplane ncp,
nccell c 
)

Definition at line 1569 of file notcurses.c.

1569 {
1570 return nccell_duplicate(ncp, c, &ncp->basecell);
1571}
nccell basecell
Definition internal.h:110
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_below()

ncplane * ncplane_below ( ncplane n)

Definition at line 2548 of file notcurses.c.

2548 {
2549 return n->below;
2550}
Here is the caller graph for this function:

◆ ncplane_box()

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 
)

Definition at line 2271 of file notcurses.c.

2274 {
2275 unsigned yoff, xoff;
2276 ncplane_cursor_yx(n, &yoff, &xoff);
2277 // must be at least 2x2, with its upper-left corner at the current cursor
2278 if(ystop < yoff + 1){
2279 logerror("ystop (%u) insufficient for yoff (%d)", ystop, yoff);
2280 return -1;
2281 }
2282 if(xstop < xoff + 1){
2283 logerror("xstop (%u) insufficient for xoff (%d)", xstop, xoff);
2284 return -1;
2285 }
2286 unsigned ymax, xmax;
2287 ncplane_dim_yx(n, &ymax, &xmax);
2288 // must be within the ncplane
2289 if(xstop >= xmax || ystop >= ymax){
2290 logerror("boundary (%ux%u) beyond plane (%dx%d)", ystop, xstop, ymax, xmax);
2291 return -1;
2292 }
2293 unsigned edges;
2294 edges = !(ctlword & NCBOXMASK_TOP) + !(ctlword & NCBOXMASK_LEFT);
2295 if(edges >= box_corner_needs(ctlword)){
2296 if(ncplane_putc(n, ul) < 0){
2297 return -1;
2298 }
2299 }
2300 if(!(ctlword & NCBOXMASK_TOP)){ // draw top border, if called for
2301 if(xstop - xoff >= 2){
2302 if(ncplane_cursor_move_yx(n, yoff, xoff + 1)){
2303 return -1;
2304 }
2305 if(!(ctlword & NCBOXGRAD_TOP)){ // cell styling, hl
2306 if(ncplane_hline(n, hl, xstop - xoff - 1) < 0){
2307 return -1;
2308 }
2309 }else{ // gradient, ul -> ur
2310 if(ncplane_hline_interp(n, hl, xstop - xoff - 1, ul->channels, ur->channels) < 0){
2311 return -1;
2312 }
2313 }
2314 }
2315 }
2316 edges = !(ctlword & NCBOXMASK_TOP) + !(ctlword & NCBOXMASK_RIGHT);
2317 if(edges >= box_corner_needs(ctlword)){
2318 if(ncplane_cursor_move_yx(n, yoff, xstop)){
2319 return -1;
2320 }
2321 if(ncplane_putc(n, ur) < 0){
2322 return -1;
2323 }
2324 }
2325 ++yoff;
2326 // middle rows (vertical lines)
2327 if(yoff < ystop){
2328 if(!(ctlword & NCBOXMASK_LEFT)){
2329 if(ncplane_cursor_move_yx(n, yoff, xoff)){
2330 return -1;
2331 }
2332 if((ctlword & NCBOXGRAD_LEFT)){ // grad styling, ul->ll
2333 if(ncplane_vline_interp(n, vl, ystop - yoff, ul->channels, ll->channels) < 0){
2334 return -1;
2335 }
2336 }else{
2337 if(ncplane_vline(n, vl, ystop - yoff) < 0){
2338 return -1;
2339 }
2340 }
2341 }
2342 if(!(ctlword & NCBOXMASK_RIGHT)){
2343 if(ncplane_cursor_move_yx(n, yoff, xstop)){
2344 return -1;
2345 }
2346 if((ctlword & NCBOXGRAD_RIGHT)){ // grad styling, ur->lr
2347 if(ncplane_vline_interp(n, vl, ystop - yoff, ur->channels, lr->channels) < 0){
2348 return -1;
2349 }
2350 }else{
2351 if(ncplane_vline(n, vl, ystop - yoff) < 0){
2352 return -1;
2353 }
2354 }
2355 }
2356 }
2357 // bottom line
2358 yoff = ystop;
2359 edges = !(ctlword & NCBOXMASK_BOTTOM) + !(ctlword & NCBOXMASK_LEFT);
2360 if(edges >= box_corner_needs(ctlword)){
2361 if(ncplane_cursor_move_yx(n, yoff, xoff)){
2362 return -1;
2363 }
2364 if(ncplane_putc(n, ll) < 0){
2365 return -1;
2366 }
2367 }
2368 if(!(ctlword & NCBOXMASK_BOTTOM)){
2369 if(xstop - xoff >= 2){
2370 if(ncplane_cursor_move_yx(n, yoff, xoff + 1)){
2371 return -1;
2372 }
2373 if(!(ctlword & NCBOXGRAD_BOTTOM)){ // cell styling, hl
2374 if(ncplane_hline(n, hl, xstop - xoff - 1) < 0){
2375 return -1;
2376 }
2377 }else{
2378 if(ncplane_hline_interp(n, hl, xstop - xoff - 1, ll->channels, lr->channels) < 0){
2379 return -1;
2380 }
2381 }
2382 }
2383 }
2384 edges = !(ctlword & NCBOXMASK_BOTTOM) + !(ctlword & NCBOXMASK_RIGHT);
2385 if(edges >= box_corner_needs(ctlword)){
2386 if(ncplane_cursor_move_yx(n, yoff, xstop)){
2387 return -1;
2388 }
2389 if(ncplane_putc(n, lr) < 0){
2390 return -1;
2391 }
2392 }
2393 return 0;
2394}
API int API int API int uint64_t uint64_t uint64_t uint64_t lr
Definition direct.h:216
API int API int API int uint64_t uint64_t uint64_t uint64_t unsigned unsigned unsigned ctlword
Definition direct.h:217
API int API int API int uint64_t uint64_t uint64_t ll
Definition direct.h:216
API int API int API int uint64_t ul
Definition direct.h:215
API int API int API int uint64_t uint64_t ur
Definition direct.h:215
int ncplane_cursor_move_yx(ncplane *n, int y, int x)
Definition notcurses.c:720
void ncplane_cursor_yx(const ncplane *n, unsigned *y, unsigned *x)
Definition notcurses.c:1741
int ncplane_hline_interp(ncplane *n, const nccell *c, unsigned len, uint64_t c1, uint64_t c2)
Definition notcurses.c:2153
int ncplane_vline_interp(ncplane *n, const nccell *c, unsigned len, uint64_t c1, uint64_t c2)
Definition notcurses.c:2209
void ncplane_dim_yx(const ncplane *n, unsigned *rows, unsigned *cols)
Definition notcurses.c:301
#define NCBOXMASK_TOP
Definition notcurses.h:2601
#define NCBOXGRAD_RIGHT
Definition notcurses.h:2606
#define NCBOXMASK_LEFT
Definition notcurses.h:2604
#define NCBOXGRAD_BOTTOM
Definition notcurses.h:2607
#define NCBOXGRAD_LEFT
Definition notcurses.h:2608
#define NCBOXMASK_BOTTOM
Definition notcurses.h:2603
#define NCBOXMASK_RIGHT
Definition notcurses.h:2602
#define NCBOXGRAD_TOP
Definition notcurses.h:2605
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_center_abs()

void ncplane_center_abs ( const ncplane n,
int *RESTRICT  y,
int *RESTRICT  x 
)

Definition at line 3268 of file notcurses.c.

3268 {
3269 ncplane_center(n, y, x);
3270 if(y){
3271 *y += n->absy;
3272 }
3273 if(x){
3274 *x += n->absx;
3275 }
3276}
Here is the caller graph for this function:

◆ ncplane_channels()

uint64_t ncplane_channels ( const ncplane n)

Definition at line 1490 of file notcurses.c.

1490 {
1491 return ncchannels_channels(n->channels);
1492}
Here is the caller graph for this function:

◆ ncplane_contents()

char * ncplane_contents ( ncplane nc,
int  begy,
int  begx,
unsigned  leny,
unsigned  lenx 
)

Definition at line 3228 of file notcurses.c.

3228 {
3229 unsigned ystart, xstart;
3230 if(check_geometry_args(nc, begy, begx, &leny, &lenx, &ystart, &xstart)){
3231 return NULL;
3232 }
3233 size_t retlen = 1;
3234 char* ret = malloc(retlen);
3235 if(ret){
3236 for(unsigned y = ystart, targy = 0 ; y < ystart + leny ; ++y, targy += 2){
3237 for(unsigned x = xstart, targx = 0 ; x < xstart + lenx ; ++x, ++targx){
3239 // we need ncplane_at_yx_cell() here instead of ncplane_at_yx(),
3240 // because we should only have one copy of each wide EGC.
3241 int clen;
3242 if((clen = ncplane_at_yx_cell(nc, y, x, &ncl)) < 0){
3243 free(ret);
3244 return NULL;
3245 }
3246 const char* c = nccell_extended_gcluster(nc, &ncl);
3247 if(clen){
3248 char* tmp = realloc(ret, retlen + clen);
3249 if(!tmp){
3250 free(ret);
3251 return NULL;
3252 }
3253 ret = tmp;
3254 memcpy(ret + retlen - 1, c, clen);
3255 retlen += clen;
3256 }
3257 }
3258 }
3259 ret[retlen - 1] = '\0';
3260 }
3261 return ret;
3262}
#define NCCELL_TRIVIAL_INITIALIZER
Definition notcurses.h:737
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_create()

ncplane * ncplane_create ( ncplane n,
const ncplane_options nopts 
)

Definition at line 707 of file notcurses.c.

707 {
708 return ncplane_new_internal(ncplane_notcurses(n), n, nopts);
709}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_cursor_at()

int ncplane_cursor_at ( const ncplane n,
nccell c,
char **  gclust 
)

Definition at line 2044 of file notcurses.c.

2044 {
2045 if(n->y >= n->leny || n->x >= n->lenx){
2046 return -1;
2047 }
2048 const nccell* src = &n->fb[nfbcellidx(n, n->y, n->x)];
2049 memcpy(c, src, sizeof(*src));
2050 if(cell_simple_p(c)){
2051 *gclust = NULL;
2052 }else if((*gclust = strdup(nccell_extended_gcluster(n, src))) == NULL){
2053 return -1;
2054 }
2055 return 0;
2056}
Here is the call graph for this function:

◆ ncplane_cursor_move_rel()

int ncplane_cursor_move_rel ( ncplane n,
int  y,
int  x 
)

Definition at line 750 of file notcurses.c.

750 {
751 if((int)n->y + y == -1){
752 logerror("invalid target y -1");
753 return -1;
754 }else if((int)n->x + x == -1){
755 logerror("invalid target x -1");
756 return -1;
757 }else return ncplane_cursor_move_yx(n, n->y + y, n->x + x);
758}
Here is the call graph for this function:

◆ ncplane_cursor_move_yx()

int ncplane_cursor_move_yx ( ncplane n,
int  y,
int  x 
)

Definition at line 720 of file notcurses.c.

720 {
721 if(x < 0){
722 if(x < -1){
723 logerror("negative target x %d", x);
724 return -1;
725 }
726 }else if((unsigned)x >= n->lenx){
727 logerror("target x %d >= width %u", x, n->lenx);
728 return -1;
729 }else{
730 n->x = x;
731 }
732 if(y < 0){
733 if(y < -1){
734 logerror("negative target y %d", y);
735 return -1;
736 }
737 }else if((unsigned)y >= n->leny){
738 logerror("target y %d >= height %u", y, n->leny);
739 return -1;
740 }else{
741 n->y = y;
742 }
743 if(cursor_invalid_p(n)){
744 logerror("invalid cursor following move (%d/%d)", n->y, n->x);
745 return -1;
746 }
747 return 0;
748}
Here is the caller graph for this function:

◆ ncplane_cursor_yx()

void ncplane_cursor_yx ( const ncplane n,
unsigned *  y,
unsigned *  x 
)

Definition at line 1741 of file notcurses.c.

1741 {
1742 if(y){
1743 *y = n->y;
1744 }
1745 if(x){
1746 *x = n->x;
1747 }
1748}
Here is the caller graph for this function:

◆ ncplane_destroy()

int ncplane_destroy ( ncplane ncp)

Definition at line 1018 of file notcurses.c.

1018 {
1019 if(ncp == NULL){
1020 return 0;
1021 }
1022 if(ncplane_notcurses(ncp)->stdplane == ncp){
1023 logerror("won't destroy standard plane");
1024 return -1;
1025 }
1026//notcurses_debug(ncplane_notcurses(ncp), stderr);
1027 loginfo("destroying %dx%d plane \"%s\" @ %dx%d",
1028 ncp->leny, ncp->lenx, ncp->name ? ncp->name : NULL, ncp->absy, ncp->absx);
1029 int ret = 0;
1030 // dissolve our binding from behind (->bprev is either NULL, or its
1031 // predecessor on the bound list's ->bnext, or &ncp->boundto->blist)
1032 if(ncp->bprev){
1033 if( (*ncp->bprev = ncp->bnext) ){
1034 ncp->bnext->bprev = ncp->bprev;
1035 }
1036 }else if(ncp->bnext){
1037 //assert(ncp->boundto->blist == ncp);
1038 ncp->bnext->bprev = NULL;
1039 }
1040 // recursively reparent our children to the plane to which we are bound.
1041 // this will extract each one from the sibling list.
1042 struct ncplane* bound = ncp->blist;
1043 while(bound){
1044 struct ncplane* tmp = bound->bnext;
1045 ncplane* bindto = ((ncp == ncp->boundto) ? bound : ncp->boundto);
1046 if(ncplane_reparent_family(bound, bindto) == NULL){
1047 ret = -1;
1048 }
1049 bound = tmp;
1050 }
1051 // extract ourselves from the z-axis. do this *after* reparenting, in case
1052 // reparenting shifts up the z-axis somehow (though i don't think it can,
1053 // at least not within a pile?).
1054 if(ncp->above){
1055 ncp->above->below = ncp->below;
1056 }else{
1057 ncplane_pile(ncp)->top = ncp->below;
1058 }
1059 if(ncp->below){
1060 ncp->below->above = ncp->above;
1061 }else{
1062 ncplane_pile(ncp)->bottom = ncp->above;
1063 }
1064 free_plane(ncp);
1065 return ret;
1066}
ncplane * ncplane_reparent_family(ncplane *n, ncplane *newparent)
Definition notcurses.c:2913
void free_plane(ncplane *p)
Definition notcurses.c:464
struct ncplane * blist
Definition internal.h:102
struct ncplane * boundto
Definition internal.h:103
struct ncplane * bnext
Definition internal.h:100
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_destroy_family()

int ncplane_destroy_family ( ncplane ncp)

Definition at line 1068 of file notcurses.c.

1068 {
1069 if(ncp == NULL){
1070 return 0;
1071 }
1072 if(ncplane_notcurses(ncp)->stdplane == ncp){
1073 logerror("won't destroy standard plane");
1074 return -1;
1075 }
1076 int ret = 0;
1077 while(ncp->blist){
1078 ret |= ncplane_destroy_family(ncp->blist);
1079 }
1080 ret |= ncplane_destroy(ncp);
1081 return ret;
1082}
int ncplane_destroy(ncplane *ncp)
Definition notcurses.c:1018
int ncplane_destroy_family(ncplane *ncp)
Definition notcurses.c:1068
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_dim_yx()

void ncplane_dim_yx ( const ncplane n,
unsigned *  rows,
unsigned *  cols 
)

Definition at line 301 of file notcurses.c.

301 {
302 if(rows){
303 *rows = n->leny;
304 }
305 if(cols){
306 *cols = n->lenx;
307 }
308}
Here is the caller graph for this function:

◆ ncplane_dup()

ncplane * ncplane_dup ( const ncplane n,
void *  opaque 
)

Definition at line 760 of file notcurses.c.

760 {
761 int dimy = n->leny;
762 int dimx = n->lenx;
763 const int placey = n->absy;
764 const int placex = n->absx;
765 struct ncplane_options nopts = {
766 .y = placey,
767 .x = placex,
768 .rows = dimy,
769 .cols = dimx,
770 .userptr = opaque,
771 .name = n->name,
772 .resizecb = ncplane_resizecb(n),
773 .flags = 0,
774 };
775 ncplane* newn = ncplane_create(n->boundto, &nopts);
776 if(newn == NULL){
777 return NULL;
778 }
779 // we don't duplicate sprites...though i'm unsure why not
780 size_t fbsize = sizeof(*n->fb) * dimx * dimy;
781 if(egcpool_dup(&newn->pool, &n->pool)){
783 return NULL;
784 }
785 memmove(newn->fb, n->fb, fbsize);
786 // don't use ncplane_cursor_move_yx() here; the cursor could be in an
787 // invalid location, which will be disallowed, failing out.
788 newn->y = n->y;
789 newn->x = n->x;
790 newn->halign = n->halign;
791 newn->stylemask = ncplane_styles(n);
792 newn->channels = ncplane_channels(n);
793 // we dupd the egcpool, so just dup the goffset
794 newn->basecell = n->basecell;
795 return newn;
796}
uint16_t ncplane_styles(const ncplane *n)
Definition notcurses.c:1498
int(*)(ncplane *) ncplane_resizecb(const ncplane *n)
Definition notcurses.c:2677
uint64_t ncplane_channels(const ncplane *n)
Definition notcurses.c:1490
ncplane * ncplane_create(ncplane *n, const ncplane_options *nopts)
Definition notcurses.c:707
return newn
Definition notcurses.h:3508
Here is the call graph for this function:

◆ ncplane_erase()

void ncplane_erase ( ncplane n)

Definition at line 2458 of file notcurses.c.

2458 {
2459 loginfo("erasing %dx%d plane", n->leny, n->lenx);
2460 if(n->sprite){
2461 sprixel_hide(n->sprite);
2462 destroy_tam(n);
2463 }
2464 // we must preserve the background, but a pure nccell_duplicate() would be
2465 // wiped out by the egcpool_dump(). do a duplication (to get the stylemask
2466 // and channels), and then reload.
2467 char* egc = nccell_strdup(n, &n->basecell);
2468 memset(n->fb, 0, sizeof(*n->fb) * n->leny * n->lenx);
2469 egcpool_dump(&n->pool);
2470 egcpool_init(&n->pool);
2471 // we need to zero out the EGC before handing this off to nccell_load, but
2472 // we don't want to lose the channels/attributes, so explicit gcluster load.
2473 n->basecell.gcluster = 0;
2474 nccell_load(n, &n->basecell, egc);
2475 free(egc);
2476 n->y = n->x = 0;
2477}
const char * egc
Definition egcpool.h:173
int nccell_load(ncplane *n, nccell *c, const char *gcluster)
Definition notcurses.c:1833
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_erase_region()

int ncplane_erase_region ( ncplane n,
int  ystart,
int  xstart,
int  ylen,
int  xlen 
)

Definition at line 2479 of file notcurses.c.

2479 {
2480 if(ystart == -1){
2481 ystart = n->y;
2482 }
2483 if(xstart == -1){
2484 xstart = n->x;
2485 }
2486 if(ystart < 0 || xstart < 0){
2487 logerror("illegal start of erase (%d, %d)", ystart, xstart);
2488 return -1;
2489 }
2490 if(ystart >= (int)ncplane_dim_y(n) || xstart >= (int)ncplane_dim_x(n)){
2491 logerror("illegal start of erase (%d, %d)", ystart, xstart);
2492 return -1;
2493 }
2494 if(xlen < 0){
2495 if(xlen + 1 < -xstart){
2496 xlen = -xstart - 1;
2497 }
2498 xstart = xstart + xlen + 1;
2499 xlen = -xlen;
2500 }else if(xlen == 0){
2501 xstart = 0;
2502 xlen = ncplane_dim_x(n);
2503 }
2504 if(xlen > (int)ncplane_dim_x(n) || xstart + xlen > (int)ncplane_dim_x(n)){
2505 xlen = ncplane_dim_x(n) - xstart;
2506 }
2507 if(ylen < 0){
2508 if(ylen + 1 < -ystart){
2509 ylen = -ystart - 1;
2510 }
2511 ystart = ystart + ylen + 1;
2512 ylen = -ylen;
2513 }else if(ylen == 0){
2514 ystart = 0;
2515 ylen = ncplane_dim_y(n);
2516 }
2517 if(ylen > (int)ncplane_dim_y(n) || ystart + ylen > (int)ncplane_dim_y(n)){
2518 ylen = ncplane_dim_y(n) - ystart;
2519 }
2520 // special-case the full plane erasure, as it's powerfully optimized (O(1))
2521 if(ystart == 0 && xstart == 0 &&
2522 ylen == (int)ncplane_dim_y(n) && xlen == (int)ncplane_dim_x(n)){
2523 int tmpy = n->y; // preserve cursor location
2524 int tmpx = n->x;
2526 n->y = tmpy;
2527 n->x = tmpx;
2528 return 0;
2529 }
2530 loginfo("erasing %d/%d - %d/%d", ystart, xstart, ystart + ylen, xstart + xlen);
2531 for(int y = ystart ; y < ystart + ylen ; ++y){
2532 for(int x = xstart ; x < xstart + xlen ; ++x){
2533 nccell_release(n, &n->fb[nfbcellidx(n, y, x)]);
2534 nccell_init(&n->fb[nfbcellidx(n, y, x)]);
2535 }
2536 }
2537 return 0;
2538}
API int API int API int uint64_t uint64_t uint64_t uint64_t unsigned unsigned xlen
Definition direct.h:217
API int API int API int uint64_t uint64_t uint64_t uint64_t unsigned ylen
Definition direct.h:217
void ncplane_erase(ncplane *n)
Definition notcurses.c:2458
void nccell_release(ncplane *n, nccell *c)
Definition render.c:128
Here is the call graph for this function:

◆ ncplane_hline_interp()

int ncplane_hline_interp ( ncplane n,
const nccell c,
unsigned  len,
uint64_t  c1,
uint64_t  c2 
)

Definition at line 2153 of file notcurses.c.

2154 {
2155 if(len <= 0){
2156 logerror("passed invalid length %u", len);
2157 return -1;
2158 }
2159 unsigned ur, ug, ub;
2160 int r1, g1, b1, r2, g2, b2;
2161 int br1, bg1, bb1, br2, bg2, bb2;
2162 ncchannels_fg_rgb8(c1, &ur, &ug, &ub);
2163 r1 = ur; g1 = ug; b1 = ub;
2164 ncchannels_fg_rgb8(c2, &ur, &ug, &ub);
2165 r2 = ur; g2 = ug; b2 = ub;
2166 ncchannels_bg_rgb8(c1, &ur, &ug, &ub);
2167 br1 = ur; bg1 = ug; bb1 = ub;
2168 ncchannels_bg_rgb8(c2, &ur, &ug, &ub);
2169 br2 = ur; bg2 = ug; bb2 = ub;
2170 int deltr = r2 - r1;
2171 int deltg = g2 - g1;
2172 int deltb = b2 - b1;
2173 int deltbr = br2 - br1;
2174 int deltbg = bg2 - bg1;
2175 int deltbb = bb2 - bb1;
2176 unsigned ret;
2178 if(nccell_duplicate(n, &dupc, c) < 0){
2179 return -1;
2180 }
2181 bool fgdef = false, bgdef = false;
2182 if(ncchannels_fg_default_p(c1) && ncchannels_fg_default_p(c2)){
2183 fgdef = true;
2184 }
2185 if(ncchannels_bg_default_p(c1) && ncchannels_bg_default_p(c2)){
2186 bgdef = true;
2187 }
2188 for(ret = 0 ; ret < len ; ++ret){
2189 int r = (deltr * (int)ret) / (int)len + r1;
2190 int g = (deltg * (int)ret) / (int)len + g1;
2191 int b = (deltb * (int)ret) / (int)len + b1;
2192 int br = (deltbr * (int)ret) / (int)len + br1;
2193 int bg = (deltbg * (int)ret) / (int)len + bg1;
2194 int bb = (deltbb * (int)ret) / (int)len + bb1;
2195 if(!fgdef){
2196 nccell_set_fg_rgb8(&dupc, r, g, b);
2197 }
2198 if(!bgdef){
2199 nccell_set_bg_rgb8(&dupc, br, bg, bb);
2200 }
2201 if(ncplane_putc(n, &dupc) <= 0){
2202 return -1;
2203 }
2204 }
2205 nccell_release(n, &dupc);
2206 return ret;
2207}
int r
Definition fbuf.h:226
API int API int const nccell unsigned len
Definition notcurses.h:2588
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_home()

void ncplane_home ( ncplane n)

Definition at line 715 of file notcurses.c.

715 {
716 n->x = 0;
717 n->y = 0;
718}
Here is the caller graph for this function:

◆ ncplane_move_above()

int ncplane_move_above ( ncplane *restrict  n,
ncplane *restrict  above 
)

Definition at line 1581 of file notcurses.c.

1581 {
1582 if(n == above){ // probably gets optimized out =/
1583 return -1;
1584 }
1585 ncpile* p = ncplane_pile(n);
1586 if(above == NULL){
1587 if(n->below){
1588 if( (n->below->above = n->above) ){
1589 n->above->below = n->below;
1590 }else{
1591 p->top = n->below;
1592 }
1593 n->below = NULL;
1594 if( (n->above = p->bottom) ){
1595 n->above->below = n;
1596 }
1597 p->bottom = n;
1598 }
1599 return 0;
1600 }
1601 if(n->below != above){
1602 if(p != ncplane_pile(above)){ // can't move among piles
1603 return -1;
1604 }
1605 // splice out 'n'
1606 if(n->below){
1607 n->below->above = n->above;
1608 }else{
1609 p->bottom = n->above;
1610 }
1611 if(n->above){
1612 n->above->below = n->below;
1613 }else{
1614 p->top = n->below;
1615 }
1616 if( (n->above = above->above) ){
1617 above->above->below = n;
1618 }else{
1619 p->top = n;
1620 }
1621 above->above = n;
1622 n->below = above;
1623 }
1624 return 0;
1625}
Here is the caller graph for this function:

◆ ncplane_move_below()

int ncplane_move_below ( ncplane *restrict  n,
ncplane *restrict  below 
)

Definition at line 1628 of file notcurses.c.

1628 {
1629 if(n == below){ // probably gets optimized out =/
1630 return -1;
1631 }
1632 ncpile* p = ncplane_pile(n);
1633 if(below == NULL){
1634 if(n->above){
1635 if( (n->above->below = n->below) ){
1636 n->below->above = n->above;
1637 }else{
1638 p->bottom = n->above;
1639 }
1640 n->above = NULL;
1641 if( (n->below = p->top) ){
1642 n->below->above = n;
1643 }
1644 p->top = n;
1645 }
1646 return 0;
1647 }
1648 if(n->above != below){
1649 if(p != ncplane_pile(below)){ // can't move among piles
1650 return -1;
1651 }
1652 if(n->below){
1653 n->below->above = n->above;
1654 }else{
1655 p->bottom = n->above;
1656 }
1657 if(n->above){
1658 n->above->below = n->below;
1659 }else{
1660 p->top = n->below;
1661 }
1662 if( (n->below = below->below) ){
1663 below->below->above = n;
1664 }else{
1665 p->bottom = n;
1666 }
1667 below->below = n;
1668 n->above = below;
1669 }
1670 return 0;
1671}
Here is the caller graph for this function:

◆ ncplane_move_family_above()

int ncplane_move_family_above ( ncplane *restrict  n,
ncplane *restrict  bpoint 
)

Definition at line 1674 of file notcurses.c.

1674 {
1675 ncplane* above = ncplane_above(n);
1676 ncplane* below = ncplane_below(n);
1677 if(ncplane_move_above(n, bpoint)){
1678 return -1;
1679 }
1680 // traverse the planes above n, until we hit NULL. do the planes above n
1681 // first, so that we know the topmost element of our new ensplicification.
1682 // at this point, n is the bottommost plane, and we're inserting above it.
1683 ncplane* targ = n;
1684 while(above && above != n){
1685 ncplane* tmp = ncplane_above(above);
1686 if(ncplane_descendant_p(above, n)){
1687 ncplane_move_above(above, targ);
1688 targ = above;
1689 }
1690 above = tmp;
1691 }
1692 // n remains the topmost plane, and we're inserting above it. we have to be
1693 // careful this time not to cross into any we moved below n.
1694 const ncplane* topmost = targ;
1695 targ = n;
1696 while(below && below != topmost){
1697 ncplane* tmp = ncplane_below(below);
1698 if(ncplane_descendant_p(below, n)){
1699 ncplane_move_below(below, targ);
1700 targ = below;
1701 }
1702 below = tmp;
1703 }
1704 return 0;
1705}
ncplane * ncplane_above(ncplane *n)
Definition notcurses.c:2552
ncplane * ncplane_below(ncplane *n)
Definition notcurses.c:2548
int ncplane_move_below(ncplane *restrict n, ncplane *restrict below)
Definition notcurses.c:1628
int ncplane_move_above(ncplane *restrict n, ncplane *restrict above)
Definition notcurses.c:1581
Here is the call graph for this function:

◆ ncplane_move_family_below()

int ncplane_move_family_below ( ncplane *restrict  n,
ncplane *restrict  bpoint 
)

Definition at line 1708 of file notcurses.c.

1708 {
1709 ncplane* below = ncplane_below(n);
1710 ncplane* above = ncplane_above(n);
1711 if(ncplane_move_below(n, bpoint)){
1712 return -1;
1713 }
1714 // traverse the planes below n, until we hit NULL. do the planes below n
1715 // first, so that we know the bottommost element of our new ensplicification.
1716 // we're inserting below n...
1717 ncplane* targ = n;
1718 while(below && below != n){
1719 ncplane* tmp = ncplane_below(below);
1720 if(ncplane_descendant_p(below, n)){
1721 ncplane_move_below(below, targ);
1722 targ = below;
1723 }
1724 below = tmp;
1725 }
1726 // n remains the topmost plane, and we're inserting above it. we have to be
1727 // careful this time not to cross into any we moved below n.
1728 const ncplane* bottommost = targ;
1729 targ = n;
1730 while(above && above != bottommost){
1731 ncplane* tmp = ncplane_above(above);
1732 if(ncplane_descendant_p(above, n)){
1733 ncplane_move_above(above, targ);
1734 targ = above;
1735 }
1736 above = tmp;
1737 }
1738 return 0;
1739}
Here is the call graph for this function:

◆ ncplane_move_yx()

int ncplane_move_yx ( ncplane n,
int  y,
int  x 
)

Definition at line 2411 of file notcurses.c.

2411 {
2412 if(n == ncplane_notcurses(n)->stdplane){
2413 return -1;
2414 }
2415 int dy, dx; // amount moved
2416 if(n->boundto == n){
2417 dy = y - n->absy;
2418 dx = x - n->absx;
2419 }else{
2420 dy = (n->boundto->absy + y) - n->absy;
2421 dx = (n->boundto->absx + x) - n->absx;
2422 }
2423 if(dy || dx){ // don't want to trigger sprixel_movefrom() if unneeded
2424 if(n->sprite){
2425 sprixel_movefrom(n->sprite, n->absy, n->absx);
2426 }
2427 n->absx += dx;
2428 n->absy += dy;
2429 move_bound_planes(n->blist, dy, dx);
2430 }
2431 return 0;
2432}
void sprixel_movefrom(sprixel *s, int y, int x)
Definition sprite.c:68
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_name()

char * ncplane_name ( const ncplane n)

Definition at line 2669 of file notcurses.c.

2669 {
2670 return n->name ? strdup(n->name) : NULL;
2671}

◆ ncplane_new_internal()

ncplane * ncplane_new_internal ( notcurses nc,
ncplane n,
const ncplane_options nopts 
)

Definition at line 557 of file notcurses.c.

558 {
559 if(nopts->flags >= (NCPLANE_OPTION_FIXED << 1u)){
560 logwarn("provided unsupported flags %016" PRIx64, nopts->flags);
561 }
563 if(n == NULL){
564 logerror("alignment requires a parent plane");
565 return NULL;
566 }
567 }
569 if(nopts->rows != 0 || nopts->cols != 0){
570 logerror("geometry specified with margins (r=%u, c=%u)",
571 nopts->rows, nopts->cols);
572 return NULL;
573 }
574 }
575 ncplane* p = malloc(sizeof(*p));
576 if(p == NULL){
577 return NULL;
578 }
582 p->widget = NULL;
583 p->wdestruct = NULL;
585 p->margin_b = nopts->margin_b;
586 p->margin_r = nopts->margin_r;
587 if(n){ // use parent size
588 p->leny = ncplane_dim_y(n);
589 p->lenx = ncplane_dim_x(n);
590 }else{ // use pile size
591 notcurses_term_dim_yx(nc, &p->leny, &p->lenx);
592 }
593 if((p->leny -= p->margin_b) <= 0){
594 p->leny = 1;
595 }
596 if((p->lenx -= p->margin_r) <= 0){
597 p->lenx = 1;
598 }
599 }else{
600 p->leny = nopts->rows;
601 p->lenx = nopts->cols;
602 }
603
604 size_t fbsize = ncplane_sizeof_cellarray(p->leny, p->lenx);
605 if(!fbsize || (p->fb = calloc(fbsize, sizeof(struct nccell))) == NULL){
606 logerror("error allocating cellmatrix (r=%u, c=%u)",
607 p->leny, p->lenx);
608 free(p);
609 return NULL;
610 }
611 p->x = p->y = 0;
612 p->logrow = 0;
613 p->sprite = NULL;
614 p->blist = NULL;
615 p->name = strdup(nopts->name ? nopts->name : "");
618 p->tam = NULL;
619 if(!n){ // new root/standard plane
620 p->absy = nopts->y;
621 p->absx = nopts->x;
622 p->bnext = NULL;
623 p->bprev = NULL;
624 p->boundto = p;
625 }else{ // bound to preexisting pile
626 if(nopts->flags & NCPLANE_OPTION_HORALIGNED){
627 p->absx = ncplane_halign(n, nopts->x, nopts->cols);
628 p->halign = nopts->x;
629 }else{
630 p->absx = nopts->x;
631 }
632 p->absx += n->absx;
633 if(nopts->flags & NCPLANE_OPTION_VERALIGNED){
634 p->absy = ncplane_valign(n, nopts->y, nopts->rows);
635 p->valign = nopts->y;
636 }else{
637 p->absy = nopts->y;
638 }
639 p->absy += n->absy;
640 if( (p->bnext = n->blist) ){
641 n->blist->bprev = &p->bnext;
642 }
643 p->bprev = &n->blist;
644 *p->bprev = p;
645 p->boundto = n;
646 }
647 // FIXME handle top/left margins
648 p->resizecb = nopts->resizecb;
649 p->stylemask = 0;
650 p->channels = 0;
651 egcpool_init(&p->pool);
652 nccell_init(&p->basecell);
653 p->userptr = nopts->userptr;
654 if(nc == NULL){ // fake ncplane backing ncdirect object
655 p->above = NULL;
656 p->below = NULL;
657 p->pile = NULL;
658 }else{
659 pthread_mutex_lock(&nc->pilelock);
660 ncpile* pile = n ? ncplane_pile(n) : NULL;
661 if( (p->pile = pile) ){ // existing pile
662 p->above = NULL;
663 if( (p->below = pile->top) ){ // always happens save initial plane
664 pile->top->above = p;
665 }else{
666 pile->bottom = p;
667 }
668 pile->top = p;
669 }else{ // new pile
670 make_ncpile(nc, p);
671 }
672 pthread_mutex_lock(&nc->stats.lock);
673 nc->stats.s.fbbytes += fbsize;
674 ++nc->stats.s.planes;
675 pthread_mutex_unlock(&nc->stats.lock);
676 pthread_mutex_unlock(&nc->pilelock);
677 }
678 loginfo("created new %ux%u plane \"%s\" @ %dx%d",
679 p->leny, p->lenx, p->name ? p->name : "", p->absy, p->absx);
680 return p;
681}
#define NCPLANE_OPTION_HORALIGNED
Definition notcurses.h:1441
#define NCPLANE_OPTION_AUTOGROW
Definition notcurses.h:1458
#define NCPLANE_OPTION_MARGINALIZED
Definition notcurses.h:1450
#define NCPLANE_OPTION_VSCROLL
Definition notcurses.h:1462
@ NCALIGN_UNALIGNED
Definition notcurses.h:81
#define NCPLANE_OPTION_VERALIGNED
Definition notcurses.h:1443
#define NCPLANE_OPTION_FIXED
Definition notcurses.h:1454
const char * name
Definition notcurses.h:1470
int(* resizecb)(struct ncplane *)
Definition notcurses.h:1471
int logrow
Definition internal.h:78
ncalign_e valign
Definition internal.h:113
bool fixedbound
Definition internal.h:117
bool scrolling
Definition internal.h:116
bool autogrow
Definition internal.h:118
struct ncpile * pile
Definition internal.h:92
uint64_t channels
Definition internal.h:88
ncalign_e halign
Definition internal.h:112
unsigned x
Definition internal.h:79
int absy
Definition internal.h:83
uint16_t stylemask
Definition internal.h:114
void * userptr
Definition internal.h:108
tament * tam
Definition internal.h:106
int(* resizecb)(struct ncplane *)
Definition internal.h:109
unsigned y
Definition internal.h:79
int absx
Definition internal.h:83
int margin_b
Definition internal.h:115
int margin_r
Definition internal.h:115
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_notcurses()

notcurses * ncplane_notcurses ( const ncplane n)

Definition at line 2626 of file notcurses.c.

2626 {
2627 return ncplane_pile(n)->nc;
2628}
Here is the caller graph for this function:

◆ ncplane_notcurses_const()

const notcurses * ncplane_notcurses_const ( const ncplane n)

Definition at line 2630 of file notcurses.c.

2630 {
2631 return ncplane_pile_const(n)->nc;
2632}
Here is the caller graph for this function:

◆ ncplane_off_styles()

void ncplane_off_styles ( ncplane n,
unsigned  stylebits 
)

Definition at line 2081 of file notcurses.c.

2081 {
2082 n->stylemask &= ~(stylebits & NCSTYLE_MASK);
2083}
#define NCSTYLE_MASK
Definition notcurses.h:769
Here is the caller graph for this function:

◆ ncplane_on_styles()

void ncplane_on_styles ( ncplane n,
unsigned  stylebits 
)

Definition at line 2076 of file notcurses.c.

2076 {
2077 n->stylemask |= (stylebits & NCSTYLE_MASK);
2078}
Here is the caller graph for this function:

◆ ncplane_parent()

ncplane * ncplane_parent ( ncplane n)

Definition at line 2651 of file notcurses.c.

2651 {
2652 return n->boundto;
2653}
Here is the caller graph for this function:

◆ ncplane_parent_const()

const ncplane * ncplane_parent_const ( const ncplane n)

Definition at line 2655 of file notcurses.c.

2655 {
2656 return n->boundto;
2657}
Here is the caller graph for this function:

◆ ncplane_pixel_geom()

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 
)

Definition at line 3333 of file notcurses.c.

3336 {
3337 const notcurses* nc = ncplane_notcurses_const(n);
3338 const ncpile* p = ncplane_pile_const(n);
3339 if(celldimy){
3340 *celldimy = p->cellpxy;
3341 }
3342 if(celldimx){
3343 *celldimx = p->cellpxx;
3344 }
3345 if(pxy){
3346 *pxy = p->cellpxy * ncplane_dim_y(n);
3347 }
3348 if(pxx){
3349 *pxx = p->cellpxx * ncplane_dim_x(n);
3350 }
3352 if(maxbmapy){
3353 *maxbmapy = p->cellpxy * ncplane_dim_y(n);
3354 if(*maxbmapy > nc->tcache.sixel_maxy && nc->tcache.sixel_maxy){
3355 *maxbmapy = nc->tcache.sixel_maxy;
3356 }
3357 }
3358 if(maxbmapx){
3359 *maxbmapx = p->cellpxx * ncplane_dim_x(n);
3360 if(*maxbmapx > nc->tcache.sixel_maxx && nc->tcache.sixel_maxx){
3361 *maxbmapx = nc->tcache.sixel_maxx;
3362 }
3363 }
3364 }else{
3365 if(maxbmapy){
3366 *maxbmapy = 0;
3367 }
3368 if(maxbmapx){
3369 *maxbmapx = 0;
3370 }
3371 }
3372}
const notcurses * ncplane_notcurses_const(const ncplane *n)
Definition notcurses.c:2630
ncpixelimpl_e notcurses_check_pixel_support(const notcurses *nc)
Definition notcurses.c:1153
tinfo tcache
Definition internal.h:360
unsigned sixel_maxx
Definition termdesc.h:165
unsigned sixel_maxy
Definition termdesc.h:172
Here is the call graph for this function:

◆ ncplane_putc_yx()

int ncplane_putc_yx ( ncplane n,
int  y,
int  x,
const nccell c 
)

Definition at line 1980 of file notcurses.c.

1980 {
1981 const int cols = nccell_cols(c);
1982 // unfortunately, |c| comes from |n|. the act of writing |c| to |n| could
1983 // grow |n|'s egcpool, invalidating the reference represented by
1984 // nccell_extended_gcluster(). so we must copy and free it.
1985 char* egc = nccell_strdup(n, c);
1986 if(egc == NULL){
1987 logerror("couldn't duplicate cell");
1988 return -1;
1989 }
1990 int r = ncplane_put(n, y, x, egc, cols, c->stylemask, c->channels, strlen(egc));
1991 free(egc);
1992 return r;
1993}
uint64_t channels
Definition notcurses.h:723
uint16_t stylemask
Definition notcurses.h:703
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_putchar_stained()

int ncplane_putchar_stained ( ncplane n,
char  c 
)

Definition at line 2008 of file notcurses.c.

2008 {
2009 uint64_t channels = n->channels;
2010 uint16_t stylemask = n->stylemask;
2011 const nccell* targ = &n->fb[nfbcellidx(n, n->y, n->x)];
2012 n->channels = targ->channels;
2013 n->stylemask = targ->stylemask;
2014 int ret = ncplane_putchar(n, c);
2015 n->channels = channels;
2016 n->stylemask = stylemask;
2017 return ret;
2018}
Here is the caller graph for this function:

◆ ncplane_putegc_stained()

int ncplane_putegc_stained ( ncplane n,
const char *  gclust,
size_t *  sbytes 
)

Definition at line 2032 of file notcurses.c.

2032 {
2033 uint64_t channels = n->channels;
2034 uint16_t stylemask = n->stylemask;
2035 const nccell* targ = &n->fb[nfbcellidx(n, n->y, n->x)];
2036 n->channels = targ->channels;
2037 n->stylemask = targ->stylemask;
2038 int ret = ncplane_putegc(n, gclust, sbytes);
2039 n->channels = channels;
2040 n->stylemask = stylemask;
2041 return ret;
2042}
Here is the caller graph for this function:

◆ ncplane_putegc_yx()

int ncplane_putegc_yx ( ncplane n,
int  y,
int  x,
const char *  gclust,
size_t *  sbytes 
)

Definition at line 1995 of file notcurses.c.

1995 {
1996 int cols;
1997 int bytes = utf8_egc_len(gclust, &cols);
1998 if(bytes < 0){
1999 return -1;
2000 }
2001 if(sbytes){
2002 *sbytes = bytes;
2003 }
2004//fprintf(stderr, "glust: %s cols: %d wcs: %d\n", gclust, cols, bytes);
2005 return ncplane_put(n, y, x, gclust, cols, n->stylemask, n->channels, bytes);
2006}
Here is the caller graph for this function:

◆ ncplane_putnstr_aligned()

int ncplane_putnstr_aligned ( struct ncplane n,
int  y,
ncalign_e  align,
size_t  s,
const char *  str 
)

Definition at line 2146 of file notcurses.c.

2146 {
2147 char* chopped = strndup(str, s);
2148 int ret = ncplane_putstr_aligned(n, y, align, chopped);
2149 free(chopped);
2150 return ret;
2151}
Here is the call graph for this function:

◆ ncplane_putwegc_stained()

int ncplane_putwegc_stained ( ncplane n,
const wchar_t *  gclust,
size_t *  sbytes 
)

Definition at line 2020 of file notcurses.c.

2020 {
2021 uint64_t channels = n->channels;
2022 uint16_t stylemask = n->stylemask;
2023 const nccell* targ = &n->fb[nfbcellidx(n, n->y, n->x)];
2024 n->channels = targ->channels;
2025 n->stylemask = targ->stylemask;
2026 int ret = ncplane_putwegc(n, gclust, sbytes);
2027 n->channels = channels;
2028 n->stylemask = stylemask;
2029 return ret;
2030}
Here is the caller graph for this function:

◆ ncplane_putwstr_stained()

int ncplane_putwstr_stained ( ncplane n,
const wchar_t *  gclustarr 
)

Definition at line 3278 of file notcurses.c.

3278 {
3279 mbstate_t ps = {0};
3280 const wchar_t** wset = &gclustarr;
3281 size_t mbytes = wcsrtombs(NULL, wset, 0, &ps);
3282 if(mbytes == (size_t)-1){
3283 logerror("error converting wide string");
3284 return -1;
3285 }
3286 ++mbytes;
3287 char* mbstr = malloc(mbytes);
3288 if(mbstr == NULL){
3289 return -1;
3290 }
3291 size_t s = wcsrtombs(mbstr, wset, mbytes, &ps);
3292 if(s == (size_t)-1){
3293 free(mbstr);
3294 return -1;
3295 }
3296 int r = ncplane_putstr_stained(n, mbstr);
3297 free(mbstr);
3298 return r;
3299}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_reparent()

ncplane * ncplane_reparent ( ncplane n,
ncplane newparent 
)

Definition at line 2791 of file notcurses.c.

2791 {
2792 const notcurses* nc = ncplane_notcurses_const(n);
2793 if(n == nc->stdplane){
2794 logerror("won't reparent standard plane");
2795 return NULL; // can't reparent standard plane
2796 }
2797 if(n->boundto == newparent){
2798 loginfo("won't reparent plane to itself");
2799 return n; // don't return error, just a no-op
2800 }
2801//notcurses_debug(ncplane_notcurses(n), stderr);
2802 if(n->blist){
2803 if(n->boundto == n){ // children become new root planes
2804 ncplane* lastlink;
2805 ncplane* child = n->blist;
2806 do{
2807 child->boundto = child;
2808 lastlink = child;
2809 child = child->bnext;
2810 }while(child); // n->blist != NULL -> lastlink != NULL
2811 if( (lastlink->bnext = ncplane_pile(n)->roots) ){
2812 lastlink->bnext->bprev = &lastlink->bnext;
2813 }
2814 n->blist->bprev = &ncplane_pile(n)->roots;
2815 ncplane_pile(n)->roots = n->blist;
2816 }else{ // children are rebound to current parent
2817 ncplane* lastlink;
2818 ncplane* child = n->blist;
2819 do{
2820 child->boundto = n->boundto;
2821 lastlink = child;
2822 child = child->bnext;
2823 }while(child); // n->blist != NULL -> lastlink != NULL
2824 if( (lastlink->bnext = n->boundto->blist) ){
2825 lastlink->bnext->bprev = &lastlink->bnext;
2826 }
2827 n->blist->bprev = &n->boundto->blist;
2828 n->boundto->blist = n->blist;
2829 }
2830 n->blist = NULL;
2831 }
2832 // FIXME would be nice to skip ncplane_descendant_p() on this call...:/
2833 return ncplane_reparent_family(n, newparent);
2834}
ncplane * stdplane
Definition internal.h:333
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_reparent_family()

ncplane * ncplane_reparent_family ( ncplane n,
ncplane newparent 
)

Definition at line 2913 of file notcurses.c.

2913 {
2914 // ncplane_notcurses() goes through ncplane_pile(). since we're possibly
2915 // destroying piles below, get the notcurses reference early on.
2917 if(n == nc->stdplane){
2918 return NULL; // can't reparent standard plane
2919 }
2920 if(n->boundto == newparent){ // no-op
2921 return n;
2922 }
2923 if(ncplane_descendant_p(newparent, n)){
2924 return NULL;
2925 }
2926//notcurses_debug(ncplane_notcurses(n), stderr);
2927 if(n->bprev){ // extract from sibling list
2928 if( (*n->bprev = n->bnext) ){
2929 n->bnext->bprev = n->bprev;
2930 }
2931 }else if(n->bnext){
2932 n->bnext->bprev = NULL;
2933 }
2934 n->bprev = NULL;
2935 n->bnext = NULL;
2936 // if leaving a pile, extract n from the old zaxis, and also any sprixel
2937 sprixel* s = NULL;
2938 if(n == newparent || ncplane_pile(n) != ncplane_pile(newparent)){
2939 unsplice_zaxis_recursive(n);
2940 s = unsplice_sprixels_recursive(n, NULL);
2941 }
2942 const unsigned ocellpxy = ncplane_pile(n)->cellpxy;
2943 const unsigned ocellpxx = ncplane_pile(n)->cellpxx;
2944 n->boundto = newparent;
2945 if(n == n->boundto){ // we're a new root plane
2946 logdebug("reparenting new root plane %p", n);
2947 unsplice_zaxis_recursive(n);
2948 n->bnext = NULL;
2949 n->bprev = NULL;
2950 pthread_mutex_lock(&nc->pilelock);
2951 if(ncplane_pile(n)->top == NULL){ // did we just empty our pile?
2952 ncpile_destroy(ncplane_pile(n));
2953 }
2954 make_ncpile(nc, n);
2955 unsigned ncellpxy = ncplane_pile(n)->cellpxy;
2956 unsigned ncellpxx = ncplane_pile(n)->cellpxx;
2957 pthread_mutex_unlock(&nc->pilelock);
2958 if(ncplane_pile(n)){ // FIXME otherwise, we've got a problem...!
2959 splice_zaxis_recursive(n, ncplane_pile(n), ocellpxy, ocellpxx, ncellpxy, ncellpxx);
2960 }
2961 }else{ // establish ourselves as a sibling of new parent's children
2962 if( (n->bnext = newparent->blist) ){
2963 n->bnext->bprev = &n->bnext;
2964 }
2965 n->bprev = &newparent->blist;
2966 newparent->blist = n;
2967 // place it immediately above the new binding plane if crossing piles
2968 if(ncplane_pile(n) != ncplane_pile(n->boundto)){
2969 unsigned ncellpxy = ncplane_pile(n->boundto)->cellpxy;
2970 unsigned ncellpxx = ncplane_pile(n->boundto)->cellpxx;
2971 pthread_mutex_lock(&nc->pilelock);
2972 if(ncplane_pile(n)->top == NULL){ // did we just empty our pile?
2973 ncpile_destroy(ncplane_pile(n));
2974 }
2975 n->pile = ncplane_pile(n->boundto);
2976 pthread_mutex_unlock(&nc->pilelock);
2977 splice_zaxis_recursive(n, ncplane_pile(n), ocellpxy, ocellpxx, ncellpxy, ncellpxx);
2978 }
2979 }
2980 if(s){ // must be on new plane, with sprixels to donate
2981 sprixel* lame = s;
2982 while(lame->next){
2983 lame = lame->next;
2984 }
2985 if( (lame->next = n->pile->sprixelcache) ){
2986 n->pile->sprixelcache->prev = lame;
2987 }
2988 n->pile->sprixelcache = s;
2989 }
2990 return n;
2991}
struct sprixel * prev
Definition sprite.h:145
struct sprixel * next
Definition sprite.h:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_resize()

int ncplane_resize ( ncplane n,
int  keepy,
int  keepx,
unsigned  keepleny,
unsigned  keeplenx,
int  yoff,
int  xoff,
unsigned  ylen,
unsigned  xlen 
)

Definition at line 1006 of file notcurses.c.

1009 {
1010 if(n == ncplane_notcurses(n)->stdplane){
1011//fprintf(stderr, "Can't resize standard plane\n");
1012 return -1;
1013 }
1014 return ncplane_resize_internal(n, keepy, keepx, keepleny, keeplenx,
1015 yoff, xoff, ylen, xlen);
1016}
int ncplane_resize_internal(ncplane *n, int keepy, int keepx, unsigned keepleny, unsigned keeplenx, int yoff, int xoff, unsigned ylen, unsigned xlen)
Definition notcurses.c:854
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_resize_internal()

int ncplane_resize_internal ( ncplane n,
int  keepy,
int  keepx,
unsigned  keepleny,
unsigned  keeplenx,
int  yoff,
int  xoff,
unsigned  ylen,
unsigned  xlen 
)

Definition at line 854 of file notcurses.c.

857 {
858 unsigned rows, cols;
859 if(ncplane_resize_internal_check(n, keepy, keepx, keepleny, keeplenx,
860 yoff, xoff, ylen, xlen,
861 &rows, &cols)){
862 return -1;
863 }
864 if(n->absy == n->absy + keepy && n->absx == n->absx + keepx &&
865 rows == ylen && cols == xlen){
866 return 0;
867 }
869 if(n->sprite){
870 sprixel_hide(n->sprite);
871 }
872 // we're good to resize. we'll need alloc up a new framebuffer, and copy in
873 // those elements we're retaining, zeroing out the rest. alternatively, if
874 // we've shrunk, we will be filling the new structure.
875 int oldarea = rows * cols;
876 int keptarea = keepleny * keeplenx;
877 int newarea = ylen * xlen;
878 size_t fbsize = sizeof(nccell) * newarea;
879 nccell* fb;
880 // there are two cases worth optimizing:
881 //
882 // * nothing is kept. we malloc() a new cellmatrix, dump the EGCpool in
883 // toto, and zero out the matrix. no copies, one memset.
884 // * old and new x dimensions match, and we're keeping the full width.
885 // we release any cells we're about to lose, realloc() the cellmatrix,
886 // and zero out any new cells. so long as the realloc() doesn't move
887 // us, there are no copies, one memset, one iteration (since this is
888 // most often due to autogrowth by a single line, the likelihood that
889 // we remain where we are is pretty high).
890 // * otherwise, we malloc() a new cellmatrix, zero out any new cells,
891 // copy over any reused cells, and release any lost cells. one
892 // gigantic iteration.
893 // we might realloc instead of mallocing, in which case we NULL out
894 // |preserved|. it must otherwise be free()d at the end.
895 nccell* preserved = n->fb;
896 if(cols == xlen && cols == keeplenx && keepleny && !keepy){
897 // we need release the cells that we're losing, lest we leak EGCpool
898 // memory. unfortunately, this means we mutate the plane on the error case.
899 // any solution would involve copying them out first. we only do this if
900 // we're keeping some, as we otherwise drop the EGCpool in toto.
901 if(n->leny > keepleny){
902 for(unsigned y = keepleny ; y < n->leny ; ++y){
903 for(unsigned x = 0 ; x < n->lenx ; ++x){
904 nccell_release(n, ncplane_cell_ref_yx(n, y, x));
905 }
906 }
907 }
908 if((fb = realloc(n->fb, fbsize)) == NULL){
909 return -1;
910 }
911 preserved = NULL;
912 }else{
913 if((fb = malloc(fbsize)) == NULL){
914 return -1;
915 }
916 }
917 if(n->tam){
918 loginfo("tam realloc to %d entries", newarea);
919 // FIXME first, free any disposed auxiliary vectors!
920 tament* tmptam = realloc(n->tam, sizeof(*tmptam) * newarea);
921 if(tmptam == NULL){
922 if(preserved){
923 free(fb);
924 }
925 return -1;
926 }
927 n->tam = tmptam;
928 if(newarea > oldarea){
929 memset(n->tam + oldarea, 0, sizeof(*n->tam) * (newarea - oldarea));
930 }
931 }
932 // update the cursor, if it would otherwise be off-plane
933 if(n->y >= ylen){
934 n->y = ylen - 1;
935 }
936 if(n->x >= xlen){
937 n->x = xlen - 1;
938 }
939 pthread_mutex_lock(&nc->stats.lock);
940 ncplane_notcurses(n)->stats.s.fbbytes -= sizeof(*fb) * (rows * cols);
941 ncplane_notcurses(n)->stats.s.fbbytes += fbsize;
942 pthread_mutex_unlock(&nc->stats.lock);
943 const int oldabsy = n->absy;
944 // go ahead and move. we can no longer fail at this point. but don't yet
945 // resize, because n->len[xy] are used in fbcellidx() in the loop below. we
946 // don't use ncplane_move_yx(), because we want to planebinding-invariant.
947 n->absy += keepy + yoff;
948 n->absx += keepx + xoff;
949//fprintf(stderr, "absx: %d keepx: %d xoff: %d\n", n->absx, keepx, xoff);
950 if(keptarea == 0){ // keep nothing, resize/move only.
951 // if we're keeping nothing, dump the old egcspool. otherwise, we go ahead
952 // and keep it. perhaps we ought compact it?
953 memset(fb, 0, sizeof(*fb) * newarea);
954 egcpool_dump(&n->pool);
955 }else if(!preserved){
956 // the x dimensions are equal, and we're keeping across the width. only the
957 // y dimension changed. if we grew, we need zero out the new cells (if we
958 // shrunk, we already released the old cells prior to the realloc).
959 unsigned tozorch = (ylen - keepleny) * xlen * sizeof(*fb);
960 if(tozorch){
961 unsigned zorchoff = keepleny * xlen;
962 memset(fb + zorchoff, 0, tozorch);
963 }
964 }else{
965 // we currently have maxy rows of maxx cells each. we will be keeping rows
966 // keepy..keepy + keepleny - 1 and columns keepx..keepx + keeplenx - 1.
967 // anything else is zerod out. itery is the row we're writing *to*, and we
968 // must write to each (and every cell in each).
969 for(unsigned itery = 0 ; itery < ylen ; ++itery){
970 int truey = itery + n->absy;
971 int sourceoffy = truey - oldabsy;
972//fprintf(stderr, "sourceoffy: %d keepy: %d ylen: %d\n", sourceoffy, keepy, ylen);
973 // if we have nothing copied to this line, zero it out in one go
974 if(sourceoffy < keepy || sourceoffy >= keepy + (int)keepleny){
975//fprintf(stderr, "writing 0s to line %d of %d\n", itery, ylen);
976 memset(fb + (itery * xlen), 0, sizeof(*fb) * xlen);
977 }else{
978 int copyoff = itery * xlen; // our target at any given time
979 // we do have something to copy, and zero, one, or two regions to zero out
980 unsigned copied = 0;
981 if(xoff < 0){
982 memset(fb + copyoff, 0, sizeof(*fb) * -xoff);
983 copyoff += -xoff;
984 copied += -xoff;
985 }
986 const int sourceidx = nfbcellidx(n, sourceoffy, keepx);
987//fprintf(stderr, "copying line %d (%d) to %d (%d)\n", sourceoffy, sourceidx, copyoff / xlen, copyoff);
988 memcpy(fb + copyoff, preserved + sourceidx, sizeof(*fb) * keeplenx);
989 copyoff += keeplenx;
990 copied += keeplenx;
991 unsigned perline = xlen - copied;
992 for(unsigned x = copyoff ; x < n->lenx ; ++x){
993 nccell_release(n, ncplane_cell_ref_yx(n, sourceoffy, x));
994 }
995 memset(fb + copyoff, 0, sizeof(*fb) * perline);
996 }
997 }
998 }
999 n->fb = fb;
1000 n->lenx = xlen;
1001 n->leny = ylen;
1002 free(preserved);
1004}
int resize_callbacks_children(ncplane *n)
Definition notcurses.c:801
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_resize_marginalized()

int ncplane_resize_marginalized ( ncplane n)

Definition at line 2723 of file notcurses.c.

2723 {
2724 const ncplane* parent = ncplane_parent_const(n);
2725 // a marginalized plane cannot be larger than its oppressor plane =]
2726 unsigned maxy, maxx;
2727 if(parent == n){ // root plane, need to use pile size
2728 ncpile* p = ncplane_pile(n);
2729 maxy = p->dimy;
2730 maxx = p->dimx;
2731 }else{
2732 ncplane_dim_yx(parent, &maxy, &maxx);
2733 }
2734 if((maxy -= (n->margin_b + (n->absy - n->boundto->absy))) < 1){
2735 maxy = 1;
2736 }
2737 if((maxx -= (n->margin_r + (n->absx - n->boundto->absx))) < 1){
2738 maxx = 1;
2739 }
2740 unsigned oldy, oldx;
2741 ncplane_dim_yx(n, &oldy, &oldx); // current dimensions of 'n'
2742 unsigned keepleny = oldy > maxy ? maxy : oldy;
2743 unsigned keeplenx = oldx > maxx ? maxx : oldx;
2744 if(ncplane_resize_internal(n, 0, 0, keepleny, keeplenx, 0, 0, maxy, maxx)){
2745 return -1;
2746 }
2747 int targy = maxy - n->margin_b;
2748 int targx = maxx - n->margin_b;
2749 loginfo("marg %d/%d, pdim %d/%d, move %d/%d", n->margin_b, n->margin_r, maxy, maxx, targy, targx);
2750 return ncplane_move_yx(n, targy, targx);
2751}
int ncplane_move_yx(ncplane *n, int y, int x)
Definition notcurses.c:2411
const ncplane * ncplane_parent_const(const ncplane *n)
Definition notcurses.c:2655
Here is the call graph for this function:

◆ ncplane_resize_maximize()

int ncplane_resize_maximize ( ncplane n)

Definition at line 2753 of file notcurses.c.

2753 {
2754 const ncpile* pile = ncplane_pile(n); // FIXME should be taken against parent
2755 const unsigned rows = pile->dimy;
2756 const unsigned cols = pile->dimx;
2757 unsigned oldy, oldx;
2758 ncplane_dim_yx(n, &oldy, &oldx); // current dimensions of 'n'
2759 unsigned keepleny = oldy > rows ? rows : oldy;
2760 unsigned keeplenx = oldx > cols ? cols : oldx;
2761 return ncplane_resize_internal(n, 0, 0, keepleny, keeplenx, 0, 0, rows, cols);
2762}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_resize_placewithin()

int ncplane_resize_placewithin ( ncplane n)

Definition at line 2681 of file notcurses.c.

2681 {
2682 if(n->boundto == n){
2683 return 0;
2684 }
2685 int absy = ncplane_abs_y(n);
2686 int absx = ncplane_abs_x(n);
2687 int ret = 0;
2688 if(absy + ncplane_dim_y(n) > ncplane_dim_y(n->boundto)){
2689 const int dy = (absy + ncplane_dim_y(n)) - ncplane_dim_y(n->boundto);
2690 logdebug("moving up %d", dy);
2691 if(ncplane_move_rel(n, -dy, 0)){
2692 ret = -1;
2693 }
2694 absy = ncplane_abs_y(n);
2695 }
2696 if(absx + ncplane_dim_x(n) > ncplane_dim_x(n->boundto)){
2697 const int dx = ncplane_dim_x(n->boundto) - (absx + ncplane_dim_x(n));
2698 logdebug("moving left %d", dx);
2699 if(ncplane_move_rel(n, 0, dx)){
2700 ret = -1;
2701 }
2702 absx = ncplane_abs_x(n);
2703 }
2704 // this will prefer upper-left material if the child plane is larger than
2705 // the parent. we might want a smarter rule, one based on origin?
2706 if(absy < 0){
2707 logdebug("moving down %d", -absy);
2708 // we're at least partially above our parent
2709 if(ncplane_move_rel(n, -absy, 0)){
2710 ret = -1;
2711 }
2712 }
2713 if(absx < 0){
2714 logdebug("moving right %d", -absx);
2715 // we're at least partially to the left of our parent
2716 if(ncplane_move_rel(n, 0, -absx)){
2717 ret = -1;
2718 }
2719 }
2720 return ret;
2721}
Here is the call graph for this function:

◆ ncplane_resize_realign()

int ncplane_resize_realign ( ncplane n)

Definition at line 2764 of file notcurses.c.

2764 {
2765 const ncplane* parent = ncplane_parent_const(n);
2766 if(parent == n){
2767 logerror("can't realign a root plane");
2768 return 0;
2769 }
2770 if(n->halign == NCALIGN_UNALIGNED && n->valign == NCALIGN_UNALIGNED){
2771 logerror("passed a non-aligned plane");
2772 return -1;
2773 }
2774 int xpos = ncplane_x(n);
2775 if(n->halign != NCALIGN_UNALIGNED){
2776 xpos = ncplane_halign(parent, n->halign, ncplane_dim_x(n));
2777 }
2778 int ypos = ncplane_y(n);
2779 if(n->valign != NCALIGN_UNALIGNED){
2780 ypos = ncplane_valign(parent, n->valign, ncplane_dim_y(n));
2781 }
2782 return ncplane_move_yx(n, ypos, xpos);
2783}
int ncplane_x(const ncplane *n)
Definition notcurses.c:2441
int ncplane_y(const ncplane *n)
Definition notcurses.c:2434
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_scrolling_p()

bool ncplane_scrolling_p ( const ncplane n)

Definition at line 2999 of file notcurses.c.

2999 {
3000 return n->scrolling;
3001}
Here is the caller graph for this function:

◆ ncplane_scrollup()

int ncplane_scrollup ( ncplane n,
int  r 
)

Definition at line 1792 of file notcurses.c.

1792 {
1793 if(!ncplane_scrolling_p(n)){
1794 logerror("can't scroll %d on non-scrolling plane", r);
1795 return -1;
1796 }
1797 if(r < 0){
1798 logerror("can't scroll %d lines", r);
1799 return -1;
1800 }
1801 while(r-- > 0){
1802 scroll_down(n);
1803 }
1805 notcurses_render(ncplane_notcurses(n));
1806 }
1807 return 0;
1808}
ncplane * notcurses_stdplane(notcurses *nc)
Definition notcurses.c:699
bool ncplane_scrolling_p(const ncplane *n)
Definition notcurses.c:2999
void scroll_down(ncplane *n)
Definition notcurses.c:1758
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_scrollup_child()

int ncplane_scrollup_child ( ncplane n,
const ncplane child 
)

Definition at line 1813 of file notcurses.c.

1813 {
1814 if(!ncplane_descendant_p(child, n)){
1815 logerror("not a descendant of specified plane");
1816 return -1;
1817 }
1818 if(child->fixedbound){
1819 logerror("child plane is fixed");
1820 return -1;
1821 }
1822 int parend = ncplane_abs_y(n) + ncplane_dim_y(n) - 1; // where parent ends
1823 int chend = ncplane_abs_y(child) + ncplane_dim_y(child) - 1; // where child ends
1824 if(chend <= parend){
1825 return 0;
1826 }
1827 int r = chend - parend; // how many rows we need scroll parent
1828 ncplane_cursor_move_yx(n, ncplane_dim_y(n) - 1, 0);
1829 int ret = ncplane_scrollup(n, r);
1830 return ret;
1831}
int ncplane_scrollup(ncplane *n, int r)
Definition notcurses.c:1792
Here is the call graph for this function:

◆ ncplane_set_autogrow()

bool ncplane_set_autogrow ( ncplane n,
unsigned  growp 
)

Definition at line 3003 of file notcurses.c.

3003 {
3005 logerror("can't set the standard plane autogrow");
3006 return false;
3007 }
3008 bool old = n->autogrow;
3009 n->autogrow = growp;
3010 return old;
3011}
const ncplane * notcurses_stdplane_const(const notcurses *nc)
Definition notcurses.c:703
Here is the call graph for this function:

◆ ncplane_set_base()

int ncplane_set_base ( ncplane ncp,
const char *  egc,
uint16_t  stylemask,
uint64_t  channels 
)

Definition at line 1565 of file notcurses.c.

1565 {
1566 return nccell_prime(ncp, &ncp->basecell, egc, stylemask, channels);
1567}
Here is the caller graph for this function:

◆ ncplane_set_base_cell()

int ncplane_set_base_cell ( ncplane ncp,
const nccell c 
)

Definition at line 1558 of file notcurses.c.

1558 {
1559 if(nccell_wide_right_p(c)){
1560 return -1;
1561 }
1562 return nccell_duplicate(ncp, &ncp->basecell, c);
1563}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_set_bchannel()

uint64_t ncplane_set_bchannel ( ncplane n,
uint32_t  channel 
)

Definition at line 1530 of file notcurses.c.

1530 {
1531 return ncchannels_set_bchannel(&n->channels, channel);
1532}

◆ ncplane_set_bg_alpha()

int ncplane_set_bg_alpha ( ncplane n,
int  alpha 
)

Definition at line 1546 of file notcurses.c.

1546 {
1547 return ncchannels_set_bg_alpha(&n->channels, alpha);
1548}
Here is the caller graph for this function:

◆ ncplane_set_bg_default()

void ncplane_set_bg_default ( ncplane n)

Definition at line 1506 of file notcurses.c.

1506 {
1507 ncchannels_set_bg_default(&n->channels);
1508}
Here is the caller graph for this function:

◆ ncplane_set_bg_palindex()

int ncplane_set_bg_palindex ( ncplane n,
unsigned  idx 
)

Definition at line 1554 of file notcurses.c.

1554 {
1555 return ncchannels_set_bg_palindex(&n->channels, idx);
1556}
uint32_t idx
Definition egcpool.h:298

◆ ncplane_set_bg_rgb()

int ncplane_set_bg_rgb ( ncplane n,
unsigned  channel 
)

Definition at line 1538 of file notcurses.c.

1538 {
1539 return ncchannels_set_bg_rgb(&n->channels, channel);
1540}
Here is the caller graph for this function:

◆ ncplane_set_bg_rgb8()

int ncplane_set_bg_rgb8 ( ncplane n,
unsigned  r,
unsigned  g,
unsigned  b 
)

Definition at line 1514 of file notcurses.c.

1514 {
1515 return ncchannels_set_bg_rgb8(&n->channels, r, g, b);
1516}
Here is the caller graph for this function:

◆ ncplane_set_bg_rgb8_clipped()

void ncplane_set_bg_rgb8_clipped ( ncplane n,
int  r,
int  g,
int  b 
)

Definition at line 1510 of file notcurses.c.

1510 {
1511 ncchannels_set_bg_rgb8_clipped(&n->channels, r, g, b);
1512}
Here is the caller graph for this function:

◆ ncplane_set_channels()

void ncplane_set_channels ( ncplane n,
uint64_t  channels 
)

Definition at line 1494 of file notcurses.c.

1494 {
1495 ncchannels_set_channels(&n->channels, channels);
1496}
Here is the caller graph for this function:

◆ ncplane_set_fchannel()

uint64_t ncplane_set_fchannel ( ncplane n,
uint32_t  channel 
)

Definition at line 1534 of file notcurses.c.

1534 {
1535 return ncchannels_set_fchannel(&n->channels, channel);
1536}

◆ ncplane_set_fg_alpha()

int ncplane_set_fg_alpha ( ncplane n,
int  alpha 
)

Definition at line 1542 of file notcurses.c.

1542 {
1543 return ncchannels_set_fg_alpha(&n->channels, alpha);
1544}
Here is the caller graph for this function:

◆ ncplane_set_fg_default()

void ncplane_set_fg_default ( ncplane n)

Definition at line 1502 of file notcurses.c.

1502 {
1503 ncchannels_set_fg_default(&n->channels);
1504}
Here is the caller graph for this function:

◆ ncplane_set_fg_palindex()

int ncplane_set_fg_palindex ( ncplane n,
unsigned  idx 
)

Definition at line 1550 of file notcurses.c.

1550 {
1551 return ncchannels_set_fg_palindex(&n->channels, idx);
1552}
Here is the caller graph for this function:

◆ ncplane_set_fg_rgb()

int ncplane_set_fg_rgb ( ncplane n,
unsigned  channel 
)

Definition at line 1526 of file notcurses.c.

1526 {
1527 return ncchannels_set_fg_rgb(&n->channels, channel);
1528}
Here is the caller graph for this function:

◆ ncplane_set_fg_rgb8()

int ncplane_set_fg_rgb8 ( ncplane n,
unsigned  r,
unsigned  g,
unsigned  b 
)

Definition at line 1522 of file notcurses.c.

1522 {
1523 return ncchannels_set_fg_rgb8(&n->channels, r, g, b);
1524}
Here is the caller graph for this function:

◆ ncplane_set_fg_rgb8_clipped()

void ncplane_set_fg_rgb8_clipped ( ncplane n,
int  r,
int  g,
int  b 
)

Definition at line 1518 of file notcurses.c.

1518 {
1519 ncchannels_set_fg_rgb8_clipped(&n->channels, r, g, b);
1520}
Here is the caller graph for this function:

◆ ncplane_set_name()

int ncplane_set_name ( ncplane n,
const char *  name 
)

Definition at line 2659 of file notcurses.c.

2659 {
2660 char* copy = name ? strdup(name) : NULL;
2661 if(copy == NULL && name != NULL){
2662 return -1;
2663 }
2664 free(n->name);
2665 n->name = copy;
2666 return 0;
2667}
Here is the call graph for this function:

◆ ncplane_set_resizecb()

void ncplane_set_resizecb ( ncplane n,
int(*)(ncplane *)  resizecb 
)

Definition at line 2673 of file notcurses.c.

2673 {
2674 n->resizecb = resizecb;
2675}
Here is the caller graph for this function:

◆ ncplane_set_scrolling()

bool ncplane_set_scrolling ( ncplane n,
unsigned  scrollp 
)

Definition at line 2993 of file notcurses.c.

2993 {
2994 bool old = n->scrolling;
2995 n->scrolling = scrollp;
2996 return old;
2997}
Here is the caller graph for this function:

◆ ncplane_set_styles()

void ncplane_set_styles ( ncplane n,
unsigned  stylebits 
)

Definition at line 2071 of file notcurses.c.

2071 {
2072 n->stylemask = (stylebits & NCSTYLE_MASK);
2073}
Here is the caller graph for this function:

◆ ncplane_set_userptr()

void * ncplane_set_userptr ( ncplane n,
void *  opaque 
)

Definition at line 186 of file notcurses.c.

186 {
187 void* ret = n->userptr;
188 n->userptr = opaque;
189 return ret;
190}
Here is the caller graph for this function:

◆ ncplane_styles()

uint16_t ncplane_styles ( const ncplane n)

Definition at line 1498 of file notcurses.c.

1498 {
1499 return n->stylemask;
1500}
Here is the caller graph for this function:

◆ ncplane_translate()

void ncplane_translate ( const ncplane src,
const ncplane dst,
int *restrict  y,
int *restrict  x 
)

Definition at line 2613 of file notcurses.c.

2614 {
2615 if(dst == NULL){
2616 dst = ncplane_stdplane_const(src);
2617 }
2618 if(y){
2619 *y = src->absy - dst->absy + *y;
2620 }
2621 if(x){
2622 *x = src->absx - dst->absx + *x;
2623 }
2624}
Here is the caller graph for this function:

◆ ncplane_translate_abs()

bool ncplane_translate_abs ( const ncplane n,
int *restrict  y,
int *restrict  x 
)

Definition at line 2590 of file notcurses.c.

2590 {
2591 ncplane_translate(ncplane_stdplane_const(n), n, y, x);
2592 if(y){
2593 if(*y < 0){
2594 return false;
2595 }
2596 unsigned yval = *y;
2597 if(yval >= n->leny){
2598 return false;
2599 }
2600 }
2601 if(x){
2602 if(*x < 0){
2603 return false;
2604 }
2605 unsigned xval = *x;
2606 if(xval >= n->lenx){
2607 return false;
2608 }
2609 }
2610 return true;
2611}
void ncplane_translate(const ncplane *src, const ncplane *dst, int *restrict y, int *restrict x)
Definition notcurses.c:2613
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_userptr()

void * ncplane_userptr ( ncplane n)

Definition at line 192 of file notcurses.c.

192 {
193 return n->userptr;
194}
Here is the caller graph for this function:

◆ ncplane_userptr_const()

const void * ncplane_userptr_const ( const ncplane n)

Definition at line 196 of file notcurses.c.

196 {
197 return n->userptr;
198}

◆ ncplane_vline_interp()

int ncplane_vline_interp ( ncplane n,
const nccell c,
unsigned  len,
uint64_t  c1,
uint64_t  c2 
)

Definition at line 2209 of file notcurses.c.

2210 {
2211 if(len <= 0){
2212 logerror("passed invalid length %u", len);
2213 return -1;
2214 }
2215 unsigned ur, ug, ub;
2216 int r1, g1, b1, r2, g2, b2;
2217 int br1, bg1, bb1, br2, bg2, bb2;
2218 ncchannels_fg_rgb8(c1, &ur, &ug, &ub);
2219 r1 = ur; g1 = ug; b1 = ub;
2220 ncchannels_fg_rgb8(c2, &ur, &ug, &ub);
2221 r2 = ur; g2 = ug; b2 = ub;
2222 ncchannels_bg_rgb8(c1, &ur, &ug, &ub);
2223 br1 = ur; bg1 = ug; bb1 = ub;
2224 ncchannels_bg_rgb8(c2, &ur, &ug, &ub);
2225 br2 = ur; bg2 = ug; bb2 = ub;
2226 int deltr = (r2 - r1) / ((int)len + 1);
2227 int deltg = (g2 - g1) / ((int)len + 1);
2228 int deltb = (b2 - b1) / ((int)len + 1);
2229 int deltbr = (br2 - br1) / ((int)len + 1);
2230 int deltbg = (bg2 - bg1) / ((int)len + 1);
2231 int deltbb = (bb2 - bb1) / ((int)len + 1);
2232 unsigned ypos, xpos;
2233 unsigned ret;
2234 ncplane_cursor_yx(n, &ypos, &xpos);
2236 if(nccell_duplicate(n, &dupc, c) < 0){
2237 return -1;
2238 }
2239 bool fgdef = false, bgdef = false;
2240 if(ncchannels_fg_default_p(c1) && ncchannels_fg_default_p(c2)){
2241 fgdef = true;
2242 }
2243 if(ncchannels_bg_default_p(c1) && ncchannels_bg_default_p(c2)){
2244 bgdef = true;
2245 }
2246 for(ret = 0 ; ret < len ; ++ret){
2247 if(ncplane_cursor_move_yx(n, ypos + ret, xpos)){
2248 return -1;
2249 }
2250 r1 += deltr;
2251 g1 += deltg;
2252 b1 += deltb;
2253 br1 += deltbr;
2254 bg1 += deltbg;
2255 bb1 += deltbb;
2256 if(!fgdef){
2257 nccell_set_fg_rgb8(&dupc, r1, g1, b1);
2258 }
2259 if(!bgdef){
2260 nccell_set_bg_rgb8(&dupc, br1, bg1, bb1);
2261 }
2262 if(ncplane_putc(n, &dupc) <= 0){
2263 return -1;
2264 }
2265 }
2266 nccell_release(n, &dupc);
2267 return ret;
2268}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_vprintf_aligned()

int ncplane_vprintf_aligned ( ncplane n,
int  y,
ncalign_e  align,
const char *  format,
va_list  ap 
)

Definition at line 2125 of file notcurses.c.

2126 {
2127 char* r = ncplane_vprintf_prep(format, ap);
2128 if(r == NULL){
2129 return -1;
2130 }
2131 int ret = ncplane_putstr_aligned(n, y, align, r);
2132 free(r);
2133 return ret;
2134}
char * ncplane_vprintf_prep(const char *format, va_list ap)
Definition notcurses.c:2087
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_vprintf_prep()

char * ncplane_vprintf_prep ( const char *  format,
va_list  ap 
)

Definition at line 2087 of file notcurses.c.

2087 {
2088 const size_t size = BUFSIZ; // healthy estimate, can embiggen below
2089 char* buf = malloc(size);
2090 if(buf == NULL){
2091 return NULL;
2092 }
2093 va_list vacopy;
2094 va_copy(vacopy, ap);
2095 int ret = vsnprintf(buf, size, format, ap);
2096 if(ret < 0){
2097 free(buf);
2098 va_end(vacopy);
2099 return NULL;
2100 }
2101 if((size_t)ret >= size){
2102 char* tmp = realloc(buf, ret + 1);
2103 if(tmp == NULL){
2104 free(buf);
2105 va_end(vacopy);
2106 return NULL;
2107 }
2108 buf = tmp;
2109 vsprintf(buf, format, vacopy);
2110 }
2111 va_end(vacopy);
2112 return buf;
2113}
va_end(va)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_vprintf_stained()

int ncplane_vprintf_stained ( struct ncplane n,
const char *  format,
va_list  ap 
)

Definition at line 2136 of file notcurses.c.

2136 {
2137 char* r = ncplane_vprintf_prep(format, ap);
2138 if(r == NULL){
2139 return -1;
2140 }
2141 int ret = ncplane_putstr_stained(n, r);
2142 free(r);
2143 return ret;
2144}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_vprintf_yx()

int ncplane_vprintf_yx ( ncplane n,
int  y,
int  x,
const char *  format,
va_list  ap 
)

Definition at line 2115 of file notcurses.c.

2115 {
2116 char* r = ncplane_vprintf_prep(format, ap);
2117 if(r == NULL){
2118 return -1;
2119 }
2120 int ret = ncplane_putstr_yx(n, y, x, r);
2121 free(r);
2122 return ret;
2123}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncplane_x()

int ncplane_x ( const ncplane n)

Definition at line 2441 of file notcurses.c.

2441 {
2442 if(n->boundto == n){
2443 return n->absx;
2444 }
2445 return n->absx - n->boundto->absx;
2446}
Here is the caller graph for this function:

◆ ncplane_y()

int ncplane_y ( const ncplane n)

Definition at line 2434 of file notcurses.c.

2434 {
2435 if(n->boundto == n){
2436 return n->absy;
2437 }
2438 return n->absy - n->boundto->absy;
2439}
Here is the caller graph for this function:

◆ ncplane_yx()

void ncplane_yx ( const ncplane n,
int *  y,
int *  x 
)

Definition at line 2448 of file notcurses.c.

2448 {
2449 if(y){
2450 *y = ncplane_y(n);
2451 }
2452 if(x){
2453 *x = ncplane_x(n);
2454 }
2455}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ncstrwidth()

int ncstrwidth ( const char *  egcs,
int *  validbytes,
int *  validwidth 
)

Definition at line 3309 of file notcurses.c.

3309 {
3310 int cols;
3311 if(validwidth == NULL){
3312 validwidth = &cols;
3313 }
3314 *validwidth = 0;
3315 int bytes;
3316 if(validbytes == NULL){
3317 validbytes = &bytes;
3318 }
3319 *validbytes = 0;
3320 do{
3321 int thesecols, thesebytes;
3322 thesebytes = utf8_egc_len(egcs, &thesecols);
3323 if(thesebytes < 0){
3324 return -1;
3325 }
3326 egcs += thesebytes;
3327 *validbytes += thesebytes;
3328 *validwidth += thesecols;
3329 }while(*egcs);
3330 return *validwidth;
3331}
Here is the caller graph for this function:

◆ notcurses_capabilities()

const nccapabilities * notcurses_capabilities ( const notcurses n)

Definition at line 3374 of file notcurses.c.

3374 {
3375 return &n->tcache.caps;
3376}

◆ notcurses_check_pixel_support()

ncpixelimpl_e notcurses_check_pixel_support ( const notcurses nc)

Definition at line 1153 of file notcurses.c.

1153 {
1154 if(nc->tcache.cellpxy == 0 || nc->tcache.cellpxx == 0){
1155 return NCPIXEL_NONE;
1156 }
1157 return nc->tcache.pixel_implementation;
1158}
@ NCPIXEL_NONE
Definition notcurses.h:1673
ncpixelimpl_e pixel_implementation
Definition termdesc.h:134
unsigned cellpxx
Definition termdesc.h:117
unsigned cellpxy
Definition termdesc.h:116
Here is the caller graph for this function:

◆ notcurses_core_init()

notcurses * notcurses_core_init ( const notcurses_options opts,
FILE *  outfp 
)

Definition at line 1242 of file notcurses.c.

1242 {
1243 if(outfp == NULL){
1244 outfp = stdout;
1245 }
1246 unsigned utf8;
1247 // ret comes out entirely zero-initialized
1248 notcurses* ret = notcurses_early_init(opts, outfp, &utf8);
1249 if(ret == NULL){
1250 return NULL;
1251 }
1252 // the fbuf is needed by notcurses_stop_minimal, so this must be done
1253 // before registering fatal signal handlers.
1254 if(fbuf_init(&ret->rstate.f)){
1255 pthread_mutex_destroy(&ret->pilelock);
1256 pthread_mutex_destroy(&ret->stats.lock);
1257 free(ret);
1258 return NULL;
1259 }
1262 notcurses_stop_minimal)){
1263 fbuf_free(&ret->rstate.f);
1264 pthread_mutex_destroy(&ret->pilelock);
1265 pthread_mutex_destroy(&ret->stats.lock);
1266 free(ret);
1267 return NULL;
1268 }
1269 // don't set loglevel until we've acquired the signal handler, lest we
1270 // change the loglevel out from under a running instance
1271 loglevel = ret->loglevel;
1272 ret->rstate.logendy = -1;
1273 ret->rstate.logendx = -1;
1274 ret->rstate.x = ret->rstate.y = -1;
1275 int fakecursory = ret->rstate.logendy;
1276 int fakecursorx = ret->rstate.logendx;
1277 int* cursory = ret->flags & NCOPTION_PRESERVE_CURSOR ?
1278 &ret->rstate.logendy : &fakecursory;
1279 int* cursorx = ret->flags & NCOPTION_PRESERVE_CURSOR ?
1280 &ret->rstate.logendx : &fakecursorx;
1281 if(interrogate_terminfo(&ret->tcache, ret->ttyfp, utf8,
1284 cursory, cursorx, &ret->stats,
1285 ret->margin_l, ret->margin_t,
1286 ret->margin_r, ret->margin_b,
1287 ret->flags & NCOPTION_DRAIN_INPUT)){
1288 void* altstack;
1289 fbuf_free(&ret->rstate.f);
1290 pthread_mutex_destroy(&ret->pilelock);
1291 pthread_mutex_destroy(&ret->stats.lock);
1292 drop_signals(ret, &altstack);
1293 free(ret);
1294 free(altstack);
1295 return NULL;
1296 }
1297 if(ret->tcache.maxpaletteread > -1){
1298 memcpy(ret->palette.chans, ret->tcache.originalpalette.chans,
1299 sizeof(*ret->palette.chans) * (ret->tcache.maxpaletteread + 1));
1300 }
1301 if((ret->flags & NCOPTION_PRESERVE_CURSOR) ||
1302 (!(ret->flags & NCOPTION_SUPPRESS_BANNERS))){
1303 // the u7 led the queries so that we would get a cursor position
1304 // unaffected by any query spill (unconsumed control sequences). move
1305 // us back to that location, in case there was any such spillage.
1306 if(*cursory < 0 || *cursorx < 0){
1307 unsigned cy, cx;
1308 if(locate_cursor(&ret->tcache, &cy, &cx)){
1309 logwarn("couldn't preserve cursor");
1310 }else{
1311 *cursory = cy;
1312 *cursorx = cx;
1313 }
1314 }
1315 if(*cursory >= 0 && *cursorx >= 0){
1316 if(goto_location(ret, &ret->rstate.f, *cursory, *cursorx, NULL)){
1317 goto err;
1318 }
1319 }
1320 }
1321 unsigned dimy, dimx, cgeo, pgeo; // latter two are don't-cares
1322 if(update_term_dimensions(&dimy, &dimx, &ret->tcache, ret->margin_b, &cgeo, &pgeo)){
1323 goto err;
1324 }
1325 if(ncvisual_init(ret->loglevel)){
1326 goto err;
1327 }
1328 ret->stdplane = NULL;
1329 if((ret->stdplane = create_initial_ncplane(ret, dimy, dimx)) == NULL){
1330 logpanic("couldn't create the initial plane (bad margins?)");
1331 goto err;
1332 }
1333 if(ret->flags & NCOPTION_SCROLLING){
1334 ncplane_set_scrolling(ret->stdplane, true);
1335 }
1336 reset_term_attributes(&ret->tcache, &ret->rstate.f);
1337 const char* cinvis = get_escape(&ret->tcache, ESCAPE_CIVIS);
1338 if(cinvis && fbuf_emit(&ret->rstate.f, cinvis) < 0){
1339 free_plane(ret->stdplane);
1340 goto err;
1341 }
1342 const char* pushcolors = get_escape(&ret->tcache, ESCAPE_SAVECOLORS);
1343 if(pushcolors && fbuf_emit(&ret->rstate.f, pushcolors)){
1344 free_plane(ret->stdplane);
1345 goto err;
1346 }
1347 init_banner(ret, &ret->rstate.f);
1348 if(fbuf_flush(&ret->rstate.f, ret->ttyfp) < 0){
1349 free_plane(ret->stdplane);
1350 goto err;
1351 }
1352 if(ret->rstate.logendy >= 0){ // if either is set, both are
1353 if(!(ret->flags & NCOPTION_SUPPRESS_BANNERS) && ret->tcache.ttyfd >= 0){
1354 unsigned uendy, uendx;
1355 if(locate_cursor(&ret->tcache, &uendy, &uendx)){
1356 free_plane(ret->stdplane);
1357 goto err;
1358 }
1359 ret->rstate.logendy = uendy;
1360 ret->rstate.logendx = uendx;
1361 }
1364 }
1365 }
1366 if(!(ret->flags & NCOPTION_NO_ALTERNATE_SCREEN)){
1367 // perform an explicit clear since the alternate screen was requested
1368 // (smcup *might* clear, but who knows? and it might not have been
1369 // available in any case).
1370 if(clear_and_home(ret, &ret->tcache, &ret->rstate.f)){
1371 goto err;
1372 }
1373 // no need to reestablish a preserved cursor -- that only affects the
1374 // standard plane, not the physical cursor that was just disrupted.
1375 }
1376 // the sprite clear ought take place within the alternate screen, if it's
1377 // being used.
1378 if(!(ret->flags & NCOPTION_NO_CLEAR_BITMAPS)){
1379 if(sprite_clear_all(&ret->tcache, &ret->rstate.f)){
1380 goto err;
1381 }
1382 }
1383 if(ret->rstate.f.used){
1384 if(fbuf_flush(&ret->rstate.f, ret->ttyfp) < 0){
1385 goto err;
1386 }
1387 }
1388 return ret;
1389
1390err:{
1391 void* altstack;
1392 logpanic("alas, you will not be going to space today.");
1393 notcurses_stop_minimal(ret, &altstack);
1394 fbuf_free(&ret->rstate.f);
1395 if(ret->tcache.ttyfd >= 0 && ret->tcache.tpreserved){
1396 (void)tcsetattr(ret->tcache.ttyfd, TCSAFLUSH, ret->tcache.tpreserved);
1397 free(ret->tcache.tpreserved);
1398 }
1399 del_curterm(cur_term);
1400 pthread_mutex_destroy(&ret->stats.lock);
1401 pthread_mutex_destroy(&ret->pilelock);
1402 free(ret);
1403 free(altstack);
1404 return NULL;
1405 }
1406}
int init_banner(const notcurses *nc, fbuf *f)
Definition banner.c:27
ncloglevel_e loglevel
Definition debug.c:3
int ncvisual_init(int loglevel)
Definition visual.c:23
int sprite_clear_all(const tinfo *t, fbuf *f)
Definition sprite.c:204
int clear_and_home(notcurses *nc, tinfo *ti, fbuf *f)
Definition render.c:1399
#define logpanic(fmt,...)
Definition logging.h:22
int update_term_dimensions(unsigned *rows, unsigned *cols, tinfo *tcache, int margin_b, unsigned *cgeo_changed, unsigned *pgeo_changed)
Definition notcurses.c:316
bool ncplane_set_scrolling(ncplane *n, unsigned scrollp)
Definition notcurses.c:2993
int reset_term_attributes(const tinfo *ti, fbuf *f)
Definition notcurses.c:60
#define NCOPTION_SUPPRESS_BANNERS
Definition notcurses.h:1015
#define NCOPTION_NO_CLEAR_BITMAPS
Definition notcurses.h:996
#define NCOPTION_DRAIN_INPUT
Definition notcurses.h:1030
#define NCOPTION_PRESERVE_CURSOR
Definition notcurses.h:1011
#define NCOPTION_NO_QUIT_SIGHANDLERS
Definition notcurses.h:1005
#define NCOPTION_NO_WINCH_SIGHANDLER
Definition notcurses.h:1000
#define NCOPTION_NO_ALTERNATE_SCREEN
Definition notcurses.h:1019
#define NCOPTION_NO_FONT_CHANGES
Definition notcurses.h:1025
uint64_t used
Definition fbuf.h:27
rasterstate rstate
Definition internal.h:336
int maxpaletteread
Definition termdesc.h:193
ncpalette originalpalette
Definition termdesc.h:192
struct termios * tpreserved
Definition termdesc.h:180
int ttyfd
Definition termdesc.h:109
int locate_cursor(tinfo *ti, unsigned *cursor_y, unsigned *cursor_x)
Definition termdesc.c:1558
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)
Definition termdesc.c:1294
@ ESCAPE_CIVIS
Definition termdesc.h:54
@ ESCAPE_SAVECOLORS
Definition termdesc.h:87
int setup_signals(void *vnc, bool no_quit_sigs, bool no_winch_sigs, int(*handler)(void *, void **))
Definition unixsig.c:188
int drop_signals(void *nc, void **altstack)
Definition unixsig.c:100
Here is the call graph for this function:

◆ notcurses_detected_terminal()

char * notcurses_detected_terminal ( const notcurses nc)

Definition at line 2066 of file notcurses.c.

2066 {
2067 return termdesc_longterm(&nc->tcache);
2068}
char * termdesc_longterm(const tinfo *ti)
Definition termdesc.c:1535
Here is the call graph for this function:

◆ notcurses_drop_planes()

void notcurses_drop_planes ( notcurses nc)

Definition at line 1434 of file notcurses.c.

1434 {
1435 logdebug("we have some planes");
1436 pthread_mutex_lock(&nc->pilelock);
1437 ncpile* p = ncplane_pile(nc->stdplane);
1438 ncpile* p0 = p;
1439 do{
1440 ncpile_drop(nc, &p);
1441 }while(p0 != p);
1442 pthread_mutex_unlock(&nc->pilelock);
1443 logdebug("all planes dropped");
1444}
Here is the caller graph for this function:

◆ notcurses_enter_alternate_screen()

int notcurses_enter_alternate_screen ( notcurses nc)

Definition at line 31 of file notcurses.c.

31 {
32 if(nc->tcache.ttyfd < 0){
33 return -1;
34 }
36 return -1;
37 }
39 return 0;
40}
int enter_alternate_screen(int fd, FILE *ttyfp, tinfo *ti, unsigned drain)
Definition termdesc.c:559
Here is the call graph for this function:

◆ notcurses_inputready_fd()

int notcurses_inputready_fd ( notcurses n)

Definition at line 3091 of file notcurses.c.

3091 {
3092 return inputready_fd(n->tcache.ictx);
3093}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ notcurses_leave_alternate_screen()

int notcurses_leave_alternate_screen ( notcurses nc)

Definition at line 42 of file notcurses.c.

42 {
43 if(nc->tcache.ttyfd < 0){
44 return -1;
45 }
47 &nc->tcache, nc->flags & NCOPTION_DRAIN_INPUT)){
48 return -1;
49 }
50 // move to the end of our output
51 if(nc->rstate.logendy < 0){
52 return 0;
53 }
55 return 0;
56}
int leave_alternate_screen(int fd, FILE *fp, tinfo *ti, unsigned drain)
Definition termdesc.c:611
Here is the call graph for this function:

◆ notcurses_lex_margins()

int notcurses_lex_margins ( const char *  op,
notcurses_options opts 
)

Definition at line 3067 of file notcurses.c.

3067 {
3068 char* eptr;
3069 if(lex_ulong(op, &opts->margin_t, &eptr)){
3070 return -1;
3071 }
3072 if(!*eptr){ // allow a single value to be specified for all four margins
3073 opts->margin_r = opts->margin_l = opts->margin_b = opts->margin_t;
3074 return 0;
3075 }
3076 op = ++eptr; // once here, we require four values
3077 if(lex_ulong(op, &opts->margin_r, &eptr) || !*eptr){
3078 return -1;
3079 }
3080 op = ++eptr;
3081 if(lex_ulong(op, &opts->margin_b, &eptr) || !*eptr){
3082 return -1;
3083 }
3084 op = ++eptr;
3085 if(lex_ulong(op, &opts->margin_l, &eptr) || *eptr){ // must end in NUL
3086 return -1;
3087 }
3088 return 0;
3089}
Here is the caller graph for this function:

◆ notcurses_lex_scalemode()

int notcurses_lex_scalemode ( const char *  op,
ncscale_e scalemode 
)

Definition at line 3035 of file notcurses.c.

3035 {
3036 if(strcasecmp(op, "stretch") == 0){
3037 *scalemode = NCSCALE_STRETCH;
3038 }else if(strcasecmp(op, "scalehi") == 0){
3039 *scalemode = NCSCALE_SCALE_HIRES;
3040 }else if(strcasecmp(op, "hires") == 0){
3041 *scalemode = NCSCALE_NONE_HIRES;
3042 }else if(strcasecmp(op, "scale") == 0){
3043 *scalemode = NCSCALE_SCALE;
3044 }else if(strcasecmp(op, "none") == 0){
3045 *scalemode = NCSCALE_NONE;
3046 }else{
3047 return -1;
3048 }
3049 return 0;
3050}
@ NCSCALE_SCALE_HIRES
Definition notcurses.h:101
@ NCSCALE_STRETCH
Definition notcurses.h:99
@ NCSCALE_SCALE
Definition notcurses.h:98
@ NCSCALE_NONE
Definition notcurses.h:97
@ NCSCALE_NONE_HIRES
Definition notcurses.h:100
Here is the caller graph for this function:

◆ notcurses_mice_enable()

int notcurses_mice_enable ( notcurses n,
unsigned  eventmask 
)

Definition at line 2556 of file notcurses.c.

2556 {
2557 if(mouse_setup(&n->tcache, eventmask)){
2558 return -1;
2559 }
2560 return 0;
2561}
int mouse_setup(tinfo *ti, unsigned eventmask)
Definition mice.c:3
Here is the call graph for this function:
Here is the caller graph for this function:

◆ notcurses_palette_size()

unsigned notcurses_palette_size ( const notcurses nc)

Definition at line 2062 of file notcurses.c.

2062 {
2063 return nc->tcache.caps.colors;
2064}
unsigned colors
Definition notcurses.h:1637
nccapabilities caps
Definition termdesc.h:111
Here is the caller graph for this function:

◆ notcurses_stdplane()

ncplane * notcurses_stdplane ( notcurses nc)

Definition at line 699 of file notcurses.c.

699 {
700 return nc->stdplane;
701}
Here is the caller graph for this function:

◆ notcurses_stdplane_const()

const ncplane * notcurses_stdplane_const ( const notcurses nc)

Definition at line 703 of file notcurses.c.

703 {
704 return nc->stdplane;
705}
Here is the caller graph for this function:

◆ notcurses_stop()

int notcurses_stop ( notcurses nc)

Definition at line 1446 of file notcurses.c.

1446 {
1447 logdebug("stopping notcurses");
1448//notcurses_debug(nc, stderr);
1449 int ret = 0;
1450 if(nc){
1451 void* altstack;
1452 ret |= notcurses_stop_minimal(nc, &altstack);
1453 // if we were not using the alternate screen, our cursor's wherever we last
1454 // wrote. move it to the furthest place to which it advanced.
1455 if(!get_escape(&nc->tcache, ESCAPE_SMCUP)){
1456 fbuf_reset(&nc->rstate.f);
1457//fprintf(stderr, "CLOSING TO %d/%d\n", nc->rstate.logendy, nc->rstate.logendx);
1458 goto_location(nc, &nc->rstate.f, nc->rstate.logendy, nc->rstate.logendx, NULL);
1459//fprintf(stderr, "***"); fflush(stderr);
1460 fbuf_finalize(&nc->rstate.f, stdout);
1461 }
1462 if(nc->stdplane){
1464 free_plane(nc->stdplane);
1465 }
1466 if(nc->tcache.ttyfd >= 0){
1467 ret |= close(nc->tcache.ttyfd);
1468 }
1469 egcpool_dump(&nc->pool);
1470 free(nc->lastframe);
1471 // perhaps surprisingly, this stops the input thread
1473 // get any current stats loaded into stash_stats
1475 if(!(nc->flags & NCOPTION_SUPPRESS_BANNERS)){
1476 summarize_stats(nc);
1477 }
1478#ifndef __MINGW32__
1479 del_curterm(cur_term);
1480#endif
1481 ret |= pthread_mutex_destroy(&nc->stats.lock);
1482 ret |= pthread_mutex_destroy(&nc->pilelock);
1483 fbuf_free(&nc->rstate.f);
1484 free(nc);
1485 free(altstack);
1486 }
1487 return ret;
1488}
void summarize_stats(notcurses *nc)
Definition stats.c:166
void notcurses_drop_planes(notcurses *nc)
Definition notcurses.c:1434
void notcurses_stats_reset(notcurses *nc, ncstats *stats)
Definition stats.c:100
nccell * lastframe
Definition internal.h:341
void free_terminfo_cache(tinfo *ti)
Definition termdesc.c:197
@ ESCAPE_SMCUP
Definition termdesc.h:68
Here is the call graph for this function:

◆ notcurses_str_scalemode()

const char * notcurses_str_scalemode ( ncscale_e  scalemode)

Definition at line 3052 of file notcurses.c.

3052 {
3053 if(scalemode == NCSCALE_STRETCH){
3054 return "stretch";
3055 }else if(scalemode == NCSCALE_SCALE){
3056 return "scale";
3057 }else if(scalemode == NCSCALE_NONE){
3058 return "none";
3059 }else if(scalemode == NCSCALE_NONE_HIRES){
3060 return "hires";
3061 }else if(scalemode == NCSCALE_SCALE_HIRES){
3062 return "scalehi";
3063 }
3064 return NULL;
3065}
Here is the caller graph for this function:

◆ notcurses_supported_styles()

uint16_t notcurses_supported_styles ( const notcurses nc)

Definition at line 2058 of file notcurses.c.

2058 {
2059 return term_supported_styles(&nc->tcache);
2060}
Here is the caller graph for this function:

◆ notcurses_ucs32_to_utf8()

int notcurses_ucs32_to_utf8 ( const uint32_t *  ucs32,
unsigned  ucs32count,
unsigned char *  resultbuf,
size_t  buflen 
)

Definition at line 3301 of file notcurses.c.

3302 {
3303 if(u32_to_u8(ucs32, ucs32count, resultbuf, &buflen) == NULL){
3304 return -1;
3305 }
3306 return buflen;
3307}
Here is the caller graph for this function:

◆ notcurses_version()

const char * notcurses_version ( void  )

Definition at line 182 of file notcurses.c.

182 {
183 return NOTCURSES_VERSION;
184}
Here is the caller graph for this function:

◆ notcurses_version_components()

void notcurses_version_components ( int *  major,
int *  minor,
int *  patch,
int *  tweak 
)

Definition at line 24 of file notcurses.c.

24 {
25 *major = NOTCURSES_VERNUM_MAJOR;
26 *minor = NOTCURSES_VERNUM_MINOR;
27 *patch = NOTCURSES_VERNUM_PATCH;
28 *tweak = atoi(NOTCURSES_VERSION_TWEAK);
29}
Here is the caller graph for this function:

◆ reset_term_attributes()

int reset_term_attributes ( const tinfo ti,
fbuf f 
)

Definition at line 60 of file notcurses.c.

60 {
61 int ret = 0;
62 const char* esc;
63 if((esc = get_escape(ti, ESCAPE_OP)) && fbuf_emit(f, esc)){
64 ret = -1;
65 }
66 if((esc = get_escape(ti, ESCAPE_SGR0)) && fbuf_emit(f, esc)){
67 ret = -1;
68 }
69 return ret;
70}
@ ESCAPE_OP
Definition termdesc.h:50
@ ESCAPE_SGR0
Definition termdesc.h:53
Here is the caller graph for this function:

◆ reset_term_palette()

int reset_term_palette ( const tinfo ti,
fbuf f,
unsigned  touchedpalette 
)

Definition at line 78 of file notcurses.c.

78 {
79 int ret = 0;
80 const char* esc;
81 if((esc = get_escape(ti, ESCAPE_RESTORECOLORS))){
82 loginfo("restoring palette via xtpopcolors");
83 if(fbuf_emit(f, esc)){
84 ret = -1;
85 }
86 return ret;
87 }
88 if(!touchedpalette){
89 return 0;
90 }
91 if(ti->caps.can_change_colors && ti->maxpaletteread > -1){
92 loginfo("restoring saved palette (%d)", ti->maxpaletteread + 1);
93 esc = get_escape(ti, ESCAPE_INITC);
94 for(int z = 0 ; z < ti->maxpaletteread ; ++z){
95 unsigned r, g, b;
96 ncchannel_rgb8(ti->originalpalette.chans[z], &r, &g, &b);
97 // Need convert RGB values [0..256) to [0..1000], ugh
98 r = r * 1000 / 255;
99 g = g * 1000 / 255;
100 b = b * 1000 / 255;
101 if(fbuf_emit(f, tiparm(esc, z, r, g, b)) < 0){
102 return -1;
103 }
104 }
105 }else if((esc = get_escape(ti, ESCAPE_OC))){
106 loginfo("resetting palette");
107 if(fbuf_emit(f, esc)){
108 ret = -1;
109 }
110 }else{
111 logwarn("no method known to restore palette");
112 }
113 return ret;
114}
bool can_change_colors
Definition notcurses.h:1640
@ ESCAPE_RESTORECOLORS
Definition termdesc.h:88
@ ESCAPE_OC
Definition termdesc.h:56
@ ESCAPE_INITC
Definition termdesc.h:81

◆ resize_callbacks_children()

int resize_callbacks_children ( ncplane n)

Definition at line 801 of file notcurses.c.

801 {
802 int ret = 0;
803 for(struct ncplane* child = n->blist ; child ; child = child->bnext){
804 if(child->resizecb){
805 ret |= child->resizecb(child);
806 }
807 }
808 return ret;
809}
Here is the caller graph for this function:

◆ scroll_down()

void scroll_down ( ncplane n)

Definition at line 1758 of file notcurses.c.

1758 {
1759//fprintf(stderr, "pre-scroll: %d/%d %d/%d log: %d scrolling: %u\n", n->y, n->x, n->leny, n->lenx, n->logrow, n->scrolling);
1760 n->x = 0;
1761 if(n->y == n->leny - 1){
1762 // we're on the last line of the plane
1763 if(n->autogrow){
1764 ncplane_resize_simple(n, n->leny + 1, n->lenx);
1765 ncplane_cursor_move_yx(n, n->leny - 1, 0);
1766 return;
1767 }
1768 // we'll actually be scrolling material up and out, and making a new line.
1769 // if this is the standard plane, that means a "physical" scroll event is
1770 // called for.
1772 ncplane_pile(n)->scrolls++;
1773 }
1774 n->logrow = (n->logrow + 1) % n->leny;
1775 nccell* row = n->fb + nfbcellidx(n, n->y, 0);
1776 for(unsigned clearx = 0 ; clearx < n->lenx ; ++clearx){
1777 nccell_release(n, &row[clearx]);
1778 }
1779 memset(row, 0, sizeof(*row) * n->lenx);
1780 for(struct ncplane* c = n->blist ; c ; c = c->bnext){
1781 if(!c->fixedbound){
1782 if(ncplanes_intersect_p(n, c)){
1783 ncplane_move_rel(c, -1, 0);
1784 }
1785 }
1786 }
1787 }else{
1788 ++n->y;
1789 }
1790}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_term_dimensions()

int update_term_dimensions ( unsigned *  rows,
unsigned *  cols,
tinfo tcache,
int  margin_b,
unsigned *  cgeo_changed,
unsigned *  pgeo_changed 
)

Definition at line 316 of file notcurses.c.

317 {
318 *pgeo_changed = 0;
319 *cgeo_changed = 0;
320 // if we're not a real tty, we presumably haven't changed geometry, return
321 if(tcache->ttyfd < 0){
322 if(rows){
323 *rows = tcache->default_rows;
324 }
325 if(cols){
326 *cols = tcache->default_cols;
327 }
328 tcache->cellpxy = 0;
329 tcache->cellpxx = 0;
330 return 0;
331 }
332 unsigned rowsafe, colsafe;
333 if(rows == NULL){
334 rows = &rowsafe;
335 rowsafe = tcache->dimy;
336 }
337 if(cols == NULL){
338 cols = &colsafe;
339 colsafe = tcache->dimx;
340 }
341#ifndef __MINGW32__
342 struct winsize ws;
343 if(tiocgwinsz(tcache->ttyfd, &ws)){
344 return -1;
345 }
346 *rows = ws.ws_row;
347 *cols = ws.ws_col;
348 unsigned cpixy;
349 unsigned cpixx;
350#ifdef __linux__
351 if(tcache->linux_fb_fd >= 0){
352 get_linux_fb_pixelgeom(tcache, &tcache->pixy, &tcache->pixx);
353 cpixy = tcache->pixy / *rows;
354 cpixx = tcache->pixx / *cols;
355 }else{
356#else
357 {
358#endif
359 // we might have the pixel geometry from CSI14t, so don't override a valid
360 // earlier response with 0s from the ioctl. we do want to fire off a fresh
361 // CSI14t in this case, though FIXME.
362 if(ws.ws_ypixel){
363 tcache->pixy = ws.ws_ypixel;
364 tcache->pixx = ws.ws_xpixel;
365 }
366 // update even if we didn't get values just now, because we need set
367 // cellpx{y,x} up from an initial CSI14n, which set only pix{y,x}.
368 cpixy = ws.ws_row ? tcache->pixy / ws.ws_row : 0;
369 cpixx = ws.ws_col ? tcache->pixx / ws.ws_col : 0;
370 }
371 if(tcache->cellpxy != cpixy){
372 tcache->cellpxy = cpixy;
373 *pgeo_changed = 1;
374 }
375 if(tcache->cellpxx != cpixx){
376 tcache->cellpxx = cpixx;
377 *pgeo_changed = 1;
378 }
379 if(tcache->cellpxy == 0 || tcache->cellpxx == 0){
380 tcache->pixel_draw = NULL; // disable support
381 }
382#else
383 CONSOLE_SCREEN_BUFFER_INFO csbi;
384 // There is the buffer itself, which is similar in function to the scrollback
385 // buffer in a Linux terminal, and there is the display window, which is the
386 // visible view of that buffer. The addressable area (from a VT point of
387 // view) spans the width of the buffer, but the height of the display window.
388 //
389 // +--------------------------+ ^
390 // | | |
391 // | | |
392 // +-----+--------------+-----+ ^ w | b
393 // |XXXXX|XXXXXXXXXXXXXX|XXXXX| | i | u
394 // |XXXXX|XXXXXXXXXXXXXX|XXXXX| | n | f
395 // |XXXXX|XXXXXXXXXXXXXX|XXXXX| | d | f
396 // |XXXXX|XXXXXXXXXXXXXX|XXXXX| | o | e
397 // +-----+--------------+-----+ v w | r
398 // | | |
399 // | | |
400 // +--------------------------+ v
401 //
402 // <--- window --->
403 //
404 //<--------- buffer --------->
405 //
406 // Because the buffer extends past the bottom of the display window, a user
407 // can potentially scroll down beyond what would normally be thought of as the
408 // end of the buffer. Because the buffer can be wider than the display
409 // window, the user can scroll horizontally to view parts of the addressable
410 // area that aren't currently visible.
411 if(GetConsoleScreenBufferInfo(tcache->outhandle, &csbi)){
412 *cols = csbi.dwSize.X;
413 *rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
414 }else{
415 *rows = tcache->default_rows;
416 *cols = tcache->default_cols;
417 }
418#endif
419 if(tcache->dimy != *rows){
420 tcache->dimy = *rows;
421 *cgeo_changed = 1;
422 }
423 if(tcache->dimx != *cols){
424 tcache->dimx = *cols;
425 *cgeo_changed = 1;
426 }
427 if(tcache->sixel_maxy_pristine){
428 int sixelrows = *rows - 1;
429 // if the bottom margin is at least one row, we can draw into the last
430 // row of our visible area. we must leave the true bottom row alone.
431 if(margin_b){
432 ++sixelrows;
433 }
434 tcache->sixel_maxy = sixelrows * tcache->cellpxy;
435 if(tcache->sixel_maxy > tcache->sixel_maxy_pristine){
436 tcache->sixel_maxy = tcache->sixel_maxy_pristine;
437 }
438 }
439 return 0;
440}
int get_linux_fb_pixelgeom(tinfo *ti, unsigned *ypix, unsigned *xpix)
Definition linux.c:813
unsigned pixx
Definition termdesc.h:113
unsigned pixy
Definition termdesc.h:112
unsigned dimx
Definition termdesc.h:118
int default_rows
Definition termdesc.h:189
int(* pixel_draw)(const struct tinfo *, const struct ncpile *p, struct sprixel *s, fbuf *f, int y, int x)
Definition termdesc.h:147
unsigned dimy
Definition termdesc.h:118
unsigned sixel_maxy_pristine
Definition termdesc.h:173
int default_cols
Definition termdesc.h:190
int tiocgwinsz(int fd, struct winsize *ws)
Definition termdesc.c:1576
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ ncplane_resizecb

int(*)(ncplane *) ncplane_resizecb(const ncplane *n) ( const ncplane n)

Definition at line 2677 of file notcurses.c.

2677 {
2678 return n->resizecb;
2679}