@ -24,11 +24,7 @@ extern "C" {
# define RESTRICT restrict
# endif
# ifdef NOTCURSES_FFI
# define static API
# endif
# ifndef __MINGW32__
# ifndef __MINGW64__
# define API __attribute__((visibility("default")))
# else
# define API __declspec(dllexport)
@ -125,20 +121,20 @@ typedef enum {
// initialize a 32-bit channel pair with specified RGB
# define NCCHANNEL_INITIALIZER(r, g, b) \
( ( ( uint32_t ) ( r ) < < 16u ) + ( ( uint32_t ) ( g ) < < 8u ) + ( b ) + NC_BGDEFAULT_MASK )
( ( ( uint32_t ) r < < 16u ) + ( ( uint32_t ) g < < 8u ) + ( b ) + NC_BGDEFAULT_MASK )
// initialize a 64-bit channel pair with specified RGB fg/bg
# define NCCHANNELS_INITIALIZER(fr, fg, fb, br, bg, bb) \
( ( NCCHANNEL_INITIALIZER ( ( fr ) , ( fg ) , ( fb ) ) < < 32ull ) + \
( NCCHANNEL_INITIALIZER ( ( br ) , ( bg ) , ( bb ) ) ) )
( ( NCCHANNEL_INITIALIZER ( fr , fg , fb ) < < 32ull ) + \
( NCCHANNEL_INITIALIZER ( br , bg , bb ) ) )
// These lowest-level functions directly manipulate a channel. Users will
// typically manipulate ncplanes' and nccells' channels through their APIs,
// rather than calling these explicitly.
// These lowest-level functions manipulate a channel encodings directly . Users
// will typically manipulate ncplanes' and nccells' channels through their
// APIs, rather than calling these explicitly.
// Extract the 2-bit alpha component from a 32-bit channel. It is not
// shifted down, and can be directly compared to NCALPHA_* values.
static inline u int32_t
static inline u nsigned
ncchannel_alpha ( uint32_t channel ) {
return channel & NC_BG_ALPHA_MASK ;
}
@ -151,7 +147,7 @@ ncchannel_set_alpha(uint32_t* channel, unsigned alpha){
if ( alpha & ~ NC_BG_ALPHA_MASK ) {
return - 1 ;
}
* channel = ( uint32_t ) alpha | ( * channel & ( uint32_t ) ~ NC_BG_ALPHA_MASK ) ;
* channel = alpha | ( * channel & ~ NC_BG_ALPHA_MASK ) ;
if ( alpha ! = NCALPHA_OPAQUE ) {
* channel | = NC_BGDEFAULT_MASK ;
}
@ -167,7 +163,7 @@ ncchannel_default_p(uint32_t channel){
// Mark the channel as using its default color. Alpha is set opaque.
static inline uint32_t
ncchannel_set_default ( uint32_t * channel ) {
* channel & = ( uint32_t ) ~ NC_BGDEFAULT_MASK ; // turn off not-default bit
* channel & = ~ NC_BGDEFAULT_MASK ; // turn off not-default bit
ncchannel_set_alpha ( channel , NCALPHA_OPAQUE ) ;
return * channel ;
}
@ -186,10 +182,10 @@ ncchannel_palindex(uint32_t channel){
}
// Mark the channel as using the specified palette color. It is an error if
// the index is greater than NCPALETTESIZE. Alpha is set opaque.
// the index is negative, or greater than NCPALETTESIZE. Alpha is set opaque.
static inline int
ncchannel_set_palindex ( uint32_t * channel , unsigned idx ) {
if ( idx >= NCPALETTESIZE ) {
ncchannel_set_palindex ( uint32_t * channel , int idx ) {
if ( idx < 0 | | idx >= NCPALETTESIZE ) {
return - 1 ;
}
ncchannel_set_alpha ( channel , NCALPHA_OPAQUE ) ;
@ -201,7 +197,8 @@ ncchannel_set_palindex(uint32_t* channel, unsigned idx){
// Is this channel using RGB color?
static inline bool
ncchannel_rgb_p ( uint32_t channel ) {
return ! ( ncchannel_default_p ( channel ) | | ncchannel_palindex_p ( channel ) ) ;
// bitwise or is intentional (allows compiler more freedom)
return ! ( ncchannel_default_p ( channel ) | ncchannel_palindex_p ( channel ) ) ;
}
// Extract the 8-bit red component from a 32-bit channel. Only valid if
@ -225,16 +222,9 @@ ncchannel_b(uint32_t channel){
return ( channel & 0x0000ffu ) ;
}
// Extract the 24-bit RGB value from a 32-bit channel.
// Only valid if ncchannel_rgb_p() would return true for the channel.
static inline uint32_t
ncchannel_rgb ( uint32_t channel ) {
return channel & NC_BG_RGB_MASK ;
}
// Extract the three 8-bit R/G/B components from a 32-bit channel.
// Only valid if ncchannel_rgb_p() would return true for the channel.
static inline u int32_t
static inline unsigned
ncchannel_rgb8 ( uint32_t channel , unsigned * RESTRICT r , unsigned * RESTRICT g ,
unsigned * RESTRICT b ) {
* r = ncchannel_r ( channel ) ;
@ -254,7 +244,7 @@ ncchannel_set_rgb8(uint32_t* channel, unsigned r, unsigned g, unsigned b){
uint32_t c = ( r < < 16u ) | ( g < < 8u ) | b ;
// clear the existing rgb bits, clear the palette index indicator, set
// the not-default bit, and or in the new rgb.
* channel = ( uint32_t ) ( ( * channel & ~ ( NC_BG_RGB_MASK | NC_BG_PALETTE ) ) | NC_BGDEFAULT_MASK | c ) ;
* channel = ( * channel & ~ ( NC_BG_RGB_MASK | NC_BG_PALETTE ) ) | NC_BGDEFAULT_MASK | c ;
return 0 ;
}
@ -264,7 +254,7 @@ ncchannel_set(uint32_t* channel, uint32_t rgb){
if ( rgb > 0xffffffu ) {
return - 1 ;
}
* channel = ( uint32_t ) ( ( * channel & ~ ( NC_BG_RGB_MASK | NC_BG_PALETTE ) ) | NC_BGDEFAULT_MASK | rgb ) ;
* channel = ( * channel & ~ ( NC_BG_RGB_MASK | NC_BG_PALETTE ) ) | NC_BGDEFAULT_MASK | rgb ;
return 0 ;
}
@ -291,32 +281,22 @@ ncchannel_set_rgb8_clipped(uint32_t* channel, int r, int g, int b){
if ( b < = - 1 ) {
b = 0 ;
}
uint32_t c = ( uint32_t ) ( ( r < < 16u ) | ( g < < 8u ) | b ) ;
* channel = ( uint32_t ) ( ( * channel & ~ ( NC_BG_RGB_MASK | NC_BG_PALETTE ) ) | NC_BGDEFAULT_MASK | c ) ;
uint32_t c = ( r < < 16u ) | ( g < < 8u ) | b ;
* channel = ( * channel & ~ ( NC_BG_RGB_MASK | NC_BG_PALETTE ) ) | NC_BGDEFAULT_MASK | c ;
}
// Extract the background alpha and coloring bits from a 64-bit channel
// pair as a single 32-bit value.
// Extract the 32-bit background channel from a channel pair.
static inline uint32_t
ncchannels_bchannel ( uint64_t channels ) {
return channels & ( NC_BG_RGB_MASK | NC_BG_PALETTE |
NC_BGDEFAULT_MASK | NC_BG_ALPHA_MASK ) ;
return channels & 0xfffffffflu ;
}
// Extract the foreground alpha and coloring bits from a 64-bit channel
// pair as a single 32-bit value.
// Extract the 32-bit foreground channel from a channel pair.
static inline uint32_t
ncchannels_fchannel ( uint64_t channels ) {
return ncchannels_bchannel ( channels > > 32u ) ;
}
// Extract the background alpha and coloring bits from a 64-bit channel pair.
static inline uint64_t
ncchannels_channels ( uint64_t channels ) {
return ncchannels_bchannel ( channels ) |
( ( uint64_t ) ncchannels_fchannel ( channels ) < < 32u ) ;
}
static inline bool
ncchannels_bg_rgb_p ( uint64_t channels ) {
return ncchannel_rgb_p ( ncchannels_bchannel ( channels ) ) ;
@ -333,32 +313,16 @@ ncchannels_bg_alpha(uint64_t channels){
return ncchannel_alpha ( ncchannels_bchannel ( channels ) ) ;
}
// Set the background alpha and coloring bits of the 64-bit channel pair
// from a single 32-bit value.
// Set the 32-bit background channel of a channel pair.
static inline uint64_t
ncchannels_set_bchannel ( uint64_t * channels , uint32_t channel ) {
// drop the background color and alpha bit
* channels & = ( ( 0xffffffffllu < < 32u ) | NC_NOBACKGROUND_MASK ) ;
* channels | = ( uint32_t ) ( channel & ~ NC_NOBACKGROUND_MASK ) ;
return * channels ;
return * channels = ( * channels & 0xffffffff00000000llu ) | channel ;
}
// Set the foreground alpha and coloring bits of the 64-bit channel pair
// from a single 32-bit value.
// Set the 32-bit foreground channel of a channel pair.
static inline uint64_t
ncchannels_set_fchannel ( uint64_t * channels , uint32_t channel ) {
// drop the foreground color and alpha bit
* channels & = ( 0xffffffffllu | ( ( uint64_t ) NC_NOBACKGROUND_MASK < < 32u ) ) ;
* channels | = ( uint64_t ) ( channel & ~ NC_NOBACKGROUND_MASK ) < < 32u ;
return * channels ;
}
// Set the alpha and coloring bits of a channel pair from another channel pair.
static inline uint64_t
ncchannels_set_channels ( uint64_t * dst , uint64_t channels ) {
ncchannels_set_bchannel ( dst , channels & 0xffffffffull ) ;
ncchannels_set_fchannel ( dst , ( uint32_t ) ( ( channels > > 32u ) & 0xffffffffull ) ) ;
return * dst ;
return * channels = ( * channels & 0xfffffffflu ) | ( ( uint64_t ) channel < < 32u ) ;
}
// Set the 2-bit alpha component of the background channel.
@ -440,13 +404,13 @@ ncchannels_bg_palindex(uint64_t channels){
// Extract 24 bits of foreground RGB from 'channels', shifted to LSBs.
static inline uint32_t
ncchannels_fg_rgb ( uint64_t channels ) {
return ncchannel _rgb( ncchannels_fchannel ( channels ) ) ;
return ncchannel s_fchannel( channels ) & NC_BG_RGB_MASK ;
}
// Extract 24 bits of background RGB from 'channels', shifted to LSBs.
static inline uint32_t
ncchannels_bg_rgb ( uint64_t channels ) {
return ncchannel _rgb( ncchannels_bchannel ( channels ) ) ;
return ncchannel s_bchannel( channels ) & NC_BG_RGB_MASK ;
}
// Extract 24 bits of foreground RGB from 'channels', split into subchannels.
@ -482,7 +446,7 @@ ncchannels_set_fg_rgb8_clipped(uint64_t* channels, int r, int g, int b){
}
static inline int
ncchannels_set_fg_palindex ( uint64_t * channels , unsigned idx ) {
ncchannels_set_fg_palindex ( uint64_t * channels , int idx ) {
uint32_t channel = ncchannels_fchannel ( * channels ) ;
if ( ncchannel_set_palindex ( & channel , idx ) < 0 ) {
return - 1 ;
@ -525,7 +489,7 @@ ncchannels_set_bg_rgb8_clipped(uint64_t* channels, int r, int g, int b){
// Set the cell's background palette index, set the background palette index
// bit, set it background-opaque, and clear the background default color bit.
static inline int
ncchannels_set_bg_palindex ( uint64_t * channels , unsigned idx ) {
ncchannels_set_bg_palindex ( uint64_t * channels , int idx ) {
uint32_t channel = ncchannels_bchannel ( * channels ) ;
if ( ncchannel_set_palindex ( & channel , idx ) < 0 ) {
return - 1 ;
@ -597,8 +561,7 @@ ncchannels_set_bg_default(uint64_t* channels){
// returned, and the number of valid bytes and columns will be written into
// *|validbytes| and *|validwidth| (assuming them non-NULL). If the entire
// string is valid, *|validbytes| and *|validwidth| reflect the entire string.
API int ncstrwidth ( const char * egcs , int * validbytes , int * validwidth )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API int ncstrwidth ( const char * egcs , int * validbytes , int * validwidth ) ;
// input functions like notcurses_get() return ucs32-encoded uint32_t. convert
// a series of uint32_t to utf8. result must be at least 4 bytes per input
@ -606,8 +569,7 @@ API int ncstrwidth(const char* egcs, int* validbytes, int* validwidth)
// the number of bytes used is returned, or -1 if passed illegal ucs32, or too
// small of a buffer.
API int notcurses_ucs32_to_utf8 ( const uint32_t * ucs32 , unsigned ucs32count ,
unsigned char * resultbuf , size_t buflen )
__attribute__ ( ( nonnull ( 1 , 3 ) ) ) ;
unsigned char * resultbuf , size_t buflen ) ;
// An nccell corresponds to a single character cell on some plane, which can be
// occupied by a single grapheme cluster (some root spacing glyph, along with
@ -726,7 +688,6 @@ typedef struct nccell {
// protect against such misuse here. problems *will* ensue. similarly, do not
// set channel flags other than colors/alpha. we assign non-printing glyphs
// a width of 1 to match utf8_egc_len()'s behavior for whitespace/NUL.
// FIXME can we enforce this with static_assert?
# define NCCELL_INITIALIZER(c, s, chan) { .gcluster = (htole(c)), .gcluster_backstop = 0,\
. width = ( uint8_t ) ( ( wcwidth ( c ) < 0 | | ! c ) ? 1 : wcwidth ( c ) ) , . stylemask = ( s ) , . channels = ( chan ) , }
// python fails on #define CELL_CHAR_INITIALIZER(c) CELL_INITIALIZER(c, 0, 0)
@ -790,13 +751,13 @@ nccell_styles(const nccell* c){
// whether they're actively supported or not.
static inline void
nccell_on_styles ( nccell * c , unsigned stylebits ) {
c - > stylemask | = ( uint16_t ) ( stylebits & NCSTYLE_MASK ) ;
c - > stylemask | = ( stylebits & NCSTYLE_MASK ) ;
}
// Remove the specified styles (in the LSBs) from the nccell's existing spec.
static inline void
nccell_off_styles ( nccell * c , unsigned stylebits ) {
c - > stylemask & = ( uint16_t ) ~ ( stylebits & NCSTYLE_MASK ) ;
c - > stylemask & = ~ ( stylebits & NCSTYLE_MASK ) ;
}
// Use the default color for the foreground.
@ -812,30 +773,15 @@ nccell_set_bg_default(nccell* c){
}
static inline int
nccell_set_fg_alpha ( nccell * c , unsigned alpha ) {
nccell_set_fg_alpha ( nccell * c , int alpha ) {
return ncchannels_set_fg_alpha ( & c - > channels , alpha ) ;
}
static inline int
nccell_set_bg_alpha ( nccell * c , unsigned alpha ) {
nccell_set_bg_alpha ( nccell * c , int alpha ) {
return ncchannels_set_bg_alpha ( & c - > channels , alpha ) ;
}
static inline uint64_t
nccell_set_bchannel ( nccell * c , uint32_t channel ) {
return ncchannels_set_bchannel ( & c - > channels , channel ) ;
}
static inline uint64_t
nccell_set_fchannel ( nccell * c , uint32_t channel ) {
return ncchannels_set_fchannel ( & c - > channels , channel ) ;
}
static inline uint64_t
nccell_set_channels ( nccell * c , uint64_t channels ) {
return ncchannels_set_channels ( & c - > channels , channels ) ;
}
// Is the cell part of a multicolumn element?
static inline bool
nccell_double_wide_p ( const nccell * c ) {
@ -859,25 +805,6 @@ nccell_wide_left_p(const nccell* c){
API __attribute__ ( ( returns_nonnull ) ) const char *
nccell_extended_gcluster ( const struct ncplane * n , const nccell * c ) ;
static inline uint64_t
nccell_channels ( const nccell * c ) {
return ncchannels_channels ( c - > channels ) ;
}
// Extract the background alpha and coloring bits from a cell's channels
// as a single 32-bit value.
static inline uint32_t
nccell_bchannel ( const nccell * cl ) {
return ncchannels_bchannel ( cl - > channels ) ;
}
// Extract the foreground alpha and coloring bits from a cell's channels
// as a single 32-bit value.
static inline uint32_t
nccell_fchannel ( const nccell * cl ) {
return ncchannels_fchannel ( cl - > channels ) ;
}
// return the number of columns occupied by 'c'. see ncstrwidth() for an
// equivalent for multiple EGCs.
static inline unsigned
@ -1028,15 +955,8 @@ typedef enum {
// eventually preventing Notcurses from processing terminal messages.
# define NCOPTION_DRAIN_INPUT 0x0100ull
// Prepare the standard plane in scrolling mode, useful for CLIs. This is
// equivalent to calling ncplane_set_scrolling(notcurses_stdplane(nc), true).
# define NCOPTION_SCROLLING 0x0200ull
// "CLI mode" is just setting these four options.
# define NCOPTION_CLI_MODE (NCOPTION_NO_ALTERNATE_SCREEN \
| NCOPTION_NO_CLEAR_BITMAPS \
| NCOPTION_PRESERVE_CURSOR \
| NCOPTION_SCROLLING )
// "CLI mode" is just NCOPTION_NO_CLEAR_BITMAPS | NCOPTION_NO_ALTERNATE_SCREEN |
// NCOPTION_PRESERVE_CURSOR, plus enabling scrolling on the standard plane.
// Configuration for notcurses_init().
typedef struct notcurses_options {
@ -1190,103 +1110,39 @@ nckey_mouse_p(uint32_t r){
return r > = NCKEY_MOTION & & r < = NCKEY_BUTTON11 ;
}
typedef enum {
NCTYPE_UNKNOWN ,
NCTYPE_PRESS ,
NCTYPE_REPEAT ,
NCTYPE_RELEASE ,
} ncintype_e ;
// Note: changing this also means adding kitty_cb_atxt functions in
// in.c otherwise extra codepoints won't be picked up.
# define NCINPUT_MAX_EFF_TEXT_CODEPOINTS 4
// An input event. Cell coordinates are currently defined only for mouse
// events. It is not guaranteed that we can set the modifiers for a given
// ncinput. We encompass single Unicode codepoints, not complete EGCs.
// FIXME for abi4, combine the bools into |modifiers|
typedef struct ncinput {
uint32_t id ; // Unicode codepoint or synthesized NCKEY event
int y , x ; // y/x cell coordinate of event, -1 for undefined
char utf8 [ 5 ] ; // utf8 representation, if one exists
// DEPRECATED do not use! going away in 4.0
bool alt ; // was alt held?
bool shift ; // was shift held?
bool ctrl ; // was ctrl held?
// END DEPRECATION
ncintype_e evtype ;
unsigned modifiers ; // bitmask over NCKEY_MOD_*
// FIXME kitty protocol also exposes hyper, meta, caps_lock, num_lock
enum {
NCTYPE_UNKNOWN ,
NCTYPE_PRESS ,
NCTYPE_REPEAT ,
NCTYPE_RELEASE ,
} evtype ;
int ypx , xpx ; // pixel offsets within cell, -1 for undefined
uint32_t eff_text [ NCINPUT_MAX_EFF_TEXT_CODEPOINTS ] ; // Effective
// utf32 representation, taking modifier
// keys into account. This can be multiple
// codepoints. Array is zero-terminated.
} ncinput ;
static inline bool
ncinput_shift_p ( const ncinput * n ) {
return ( n - > modifiers & NCKEY_MOD_SHIFT ) ;
}
static inline bool
ncinput_ctrl_p ( const ncinput * n ) {
return ( n - > modifiers & NCKEY_MOD_CTRL ) ;
}
static inline bool
ncinput_alt_p ( const ncinput * n ) {
return ( n - > modifiers & NCKEY_MOD_ALT ) ;
}
static inline bool
ncinput_meta_p ( const ncinput * n ) {
return ( n - > modifiers & NCKEY_MOD_META ) ;
}
static inline bool
ncinput_super_p ( const ncinput * n ) {
return ( n - > modifiers & NCKEY_MOD_SUPER ) ;
}
static inline bool
ncinput_hyper_p ( const ncinput * n ) {
return ( n - > modifiers & NCKEY_MOD_HYPER ) ;
}
static inline bool
ncinput_capslock_p ( const ncinput * n ) {
return ( n - > modifiers & NCKEY_MOD_CAPSLOCK ) ;
}
static inline bool
ncinput_numlock_p ( const ncinput * n ) {
return ( n - > modifiers & NCKEY_MOD_NUMLOCK ) ;
}
// compare two ncinput structs for data equality. NCTYPE_PRESS and
// NCTYPE_UNKNOWN are considered to be equivalent. NCKEY_MOD_CAPSLOCK
// and NCKEY_MOD_NUMLOCK are not considered relevant.
// compare two ncinput structs for data equality.
static inline bool
ncinput_equal_p ( const ncinput * n1 , const ncinput * n2 ) {
// don't need to check ->utf8; it's derived from id
if ( n1 - > id ! = n2 - > id ) {
return false ;
}
if ( n1 - > y ! = n2 - > y | | n1 - > x ! = n2 - > x ) {
return false ;
}
// don't need to check deprecated alt, ctrl, shift
if ( ( n1 - > modifiers & ~ ( unsigned ) ( NCKEY_MOD_CAPSLOCK | NCKEY_MOD_NUMLOCK ) )
! = ( n2 - > modifiers & ~ ( unsigned ) ( NCKEY_MOD_CAPSLOCK | NCKEY_MOD_NUMLOCK ) ) ) {
if ( n1 - > alt ! = n2 - > alt | | n1 - > shift ! = n2 - > shift | | n1 - > ctrl ! = n2 - > ctrl ) {
return false ;
}
if ( n1 - > evtype ! = n2 - > evtype ) {
if ( ( n1 - > evtype ! = NCTYPE_UNKNOWN & & n1 - > evtype ! = NCTYPE_PRESS ) | |
( n2 - > evtype ! = NCTYPE_UNKNOWN & & n2 - > evtype ! = NCTYPE_PRESS ) ) {
return false ;
}
}
if ( n1 - > ypx ! = n2 - > ypx | | n1 - > xpx ! = n2 - > xpx ) {
return false ;
}
return true ;
@ -1333,7 +1189,7 @@ notcurses_get_blocking(struct notcurses* n, ncinput* ni){
// Was 'ni' free of modifiers?
static inline bool
ncinput_nomod_p ( const ncinput * ni ) {
return ! ( ni - > modifiers ) ;
return ! ( ni - > alt | ni - > ctrl | ni - > shift ) ;
}
# define NCMICE_NO_EVENTS 0
@ -1383,6 +1239,12 @@ API const struct notcurses* ncplane_notcurses_const(const struct ncplane* n)
API void ncplane_dim_yx ( const struct ncplane * n , unsigned * RESTRICT y , unsigned * RESTRICT x )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
// Get a reference to the standard plane (one matching our current idea of the
// terminal size) for this terminal. The standard plane always exists, and its
// origin is always at the uppermost, leftmost cell of the terminal.
API struct ncplane * notcurses_stdplane ( struct notcurses * nc ) ;
API const struct ncplane * notcurses_stdplane_const ( const struct notcurses * nc ) ;
// notcurses_stdplane(), plus free bonus dimensions written to non-NULL y/x!
static inline struct ncplane *
notcurses_stddim_yx ( struct notcurses * nc , unsigned * RESTRICT y , unsigned * RESTRICT x ) {
@ -1585,7 +1447,8 @@ typedef struct ncpalette {
} ncpalette ;
// Create a new palette store. It will be initialized with notcurses' best
// knowledge of the currently configured palette.
// knowledge of the currently configured palette. The palette upon startup
// cannot be reliably detected, sadly.
API ALLOC ncpalette * ncpalette_new ( struct notcurses * nc )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
@ -1611,21 +1474,12 @@ ncpalette_set(ncpalette* p, int idx, unsigned rgb){
return ncchannel_set ( & p - > chans [ idx ] , rgb ) ;
}
static inline int
ncpalette_get ( const ncpalette * p , int idx , uint32_t * palent ) {
if ( idx < 0 | | ( size_t ) idx > sizeof ( p - > chans ) / sizeof ( * p - > chans ) ) {
return - 1 ;
}
* palent = ncchannel_rgb ( p - > chans [ idx ] ) ;
return 0 ;
}
static inline int
ncpalette_get_rgb8 ( const ncpalette * p , int idx , unsigned * RESTRICT r , unsigned * RESTRICT g , unsigned * RESTRICT b ) {
if ( idx < 0 | | ( size_t ) idx > sizeof ( p - > chans ) / sizeof ( * p - > chans ) ) {
return - 1 ;
}
return ( int ) ncchannel_rgb8 ( p - > chans [ idx ] , r , g , b ) ;
return ncchannel_rgb8 ( p - > chans [ idx ] , r , g , b ) ;
}
// Free the palette store 'p'.
@ -2002,22 +1856,18 @@ API int ncplane_scrollup_child(struct ncplane* n, const struct ncplane* child)
// characters, spaces, half blocks, and full blocks. The plane must have
// an even number of columns. Use the ncvisual rotation for a more
// flexible approach.
API int ncplane_rotate_cw ( struct ncplane * n )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API int ncplane_rotate_ccw ( struct ncplane * n )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API int ncplane_rotate_cw ( struct ncplane * n ) ;
API int ncplane_rotate_ccw ( struct ncplane * n ) ;
// Retrieve the current contents of the cell under the cursor. The EGC is
// returned, or NULL on error. This EGC must be free()d by the caller. The
// stylemask and channels are written to 'stylemask' and 'channels', respectively.
API char * ncplane_at_cursor ( const struct ncplane * n , uint16_t * stylemask , uint64_t * channels )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API char * ncplane_at_cursor ( struct ncplane * n , uint16_t * stylemask , uint64_t * channels ) ;
// Retrieve the current contents of the cell under the cursor into 'c'. This
// cell is invalidated if the associated plane is destroyed. Returns the number
// of bytes in the EGC, or -1 on error.
API int ncplane_at_cursor_cell ( struct ncplane * n , nccell * c )
__attribute__ ( ( nonnull ( 1 , 2 ) ) ) ;
API int ncplane_at_cursor_cell ( struct ncplane * n , nccell * c ) ;
// Retrieve the current contents of the specified cell. The EGC is returned, or
// NULL on error. This EGC must be free()d by the caller. The stylemask and
@ -2025,20 +1875,16 @@ API int ncplane_at_cursor_cell(struct ncplane* n, nccell* c)
// represents how the cell will be used during rendering, and thus integrates
// any base cell where appropriate. If called upon the secondary columns of a
// wide glyph, the EGC will be returned (i.e. this function does not distinguish
// between the primary and secondary columns of a wide glyph). If called on a
// sprixel plane, its control sequence is returned for all valid locations.
// between the primary and secondary columns of a wide glyph).
API char * ncplane_at_yx ( const struct ncplane * n , int y , int x ,
uint16_t * stylemask , uint64_t * channels )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
uint16_t * stylemask , uint64_t * channels ) ;
// Retrieve the current contents of the specified cell into 'c'. This cell is
// invalidated if the associated plane is destroyed. Returns the number of
// bytes in the EGC, or -1 on error. Unlike ncplane_at_yx(), when called upon
// the secondary columns of a wide glyph, the return can be distinguished from
// the primary column (nccell_wide_right_p(c) will return true). It is an
// error to call this on a sprixel plane (unlike ncplane_at_yx()).
API int ncplane_at_yx_cell ( struct ncplane * n , int y , int x , nccell * c )
__attribute__ ( ( nonnull ( 1 , 4 ) ) ) ;
// the primary column (nccell_wide_right_p(c) will return true).
API int ncplane_at_yx_cell ( struct ncplane * n , int y , int x , nccell * c ) ;
// Create a flat string from the EGCs of the selected region of the ncplane
// 'n'. Start at the plane's 'begy'x'begx' coordinate (which must lie on the
@ -2046,24 +1892,20 @@ API int ncplane_at_yx_cell(struct ncplane* n, int y, int x, nccell* c)
// 'lenx' can be specified as 0 to go through the boundary of the plane.
// -1 can be specified for 'begx'/'begy' to use the current cursor location.
API char * ncplane_contents ( struct ncplane * n , int begy , int begx ,
unsigned leny , unsigned lenx )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
unsigned leny , unsigned lenx ) ;
// Manipulate the opaque user pointer associated with this plane.
// ncplane_set_userptr() returns the previous userptr after replacing
// it with 'opaque'. the others simply return the userptr.
API void * ncplane_set_userptr ( struct ncplane * n , void * opaque )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API void * ncplane_userptr ( struct ncplane * n )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API void * ncplane_set_userptr ( struct ncplane * n , void * opaque ) ;
API void * ncplane_userptr ( struct ncplane * n ) ;
// Find the center coordinate of a plane, preferring the top/left in the
// case of an even number of rows/columns (in such a case, there will be one
// more cell to the bottom/right of the center than the top/left). The
// center is then modified relative to the plane's origin.
API void ncplane_center_abs ( const struct ncplane * n , int * RESTRICT y ,
int * RESTRICT x )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
int * RESTRICT x ) ;
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
@ -2099,7 +1941,7 @@ notcurses_align(int availu, ncalign_e align, int u){
// 'align'. Undefined behavior on negative 'c'.
static inline int
ncplane_halign ( const struct ncplane * n , ncalign_e align , int c ) {
return notcurses_align ( ( int ) ncplane_dim_x ( n ) , align , c ) ;
return notcurses_align ( ncplane_dim_x ( n ) , align , c ) ;
}
// Return the row at which 'r' rows ought start in order to be aligned
@ -2107,7 +1949,7 @@ ncplane_halign(const struct ncplane* n, ncalign_e align, int c){
// 'align'. Undefined behavior on negative 'r'.
static inline int
ncplane_valign ( const struct ncplane * n , ncalign_e align , int r ) {
return notcurses_align ( ( int ) ncplane_dim_y ( n ) , align , r ) ;
return notcurses_align ( ncplane_dim_y ( n ) , align , r ) ;
}
// Move the cursor to the specified position (the cursor needn't be visible).
@ -2130,25 +1972,11 @@ API void ncplane_home(struct ncplane* n)
API void ncplane_cursor_yx ( const struct ncplane * n , unsigned * RESTRICT y , unsigned * RESTRICT x )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
static inline unsigned
ncplane_cursor_y ( const struct ncplane * n ) {
unsigned y ;
ncplane_cursor_yx ( n , & y , NULL ) ;
return y ;
}
static inline unsigned
ncplane_cursor_x ( const struct ncplane * n ) {
unsigned x ;
ncplane_cursor_yx ( n , NULL , & x ) ;
return x ;
}
// Get the current colors and alpha values for ncplane 'n'.
// Get the current channels or attribute word for ncplane 'n'.
API uint64_t ncplane_channels ( const struct ncplane * n )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
// Get the current styling for the ncplane 'n' .
// Return the current styling for this ncplane.
API uint16_t ncplane_styles ( const struct ncplane * n )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
@ -2166,9 +1994,8 @@ ncplane_putc(struct ncplane* n, const nccell* c){
}
// Replace the cell at the specified coordinates with the provided 7-bit char
// 'c'. Advance the cursor by 1. On success, returns the number of columns the
// cursor was advanced. On failure, returns -1. This works whether the
// underlying char is signed or unsigned.
// 'c'. Advance the cursor by 1. On success, returns 1. On failure, returns -1.
// This works whether the underlying char is signed or unsigned.
static inline int
ncplane_putchar_yx ( struct ncplane * n , int y , int x , char c ) {
nccell ce = NCCELL_INITIALIZER ( ( uint32_t ) c , ncplane_styles ( n ) , ncplane_channels ( n ) ) ;
@ -2192,8 +2019,7 @@ API int ncplane_putchar_stained(struct ncplane* n, char c)
// On failure, -1 is returned. The number of bytes converted from gclust is
// written to 'sbytes' if non-NULL.
API int ncplane_putegc_yx ( struct ncplane * n , int y , int x , const char * gclust ,
size_t * sbytes )
__attribute__ ( ( nonnull ( 1 , 4 ) ) ) ;
size_t * sbytes ) ;
// Call ncplane_putegc_yx() at the current cursor location.
static inline int
@ -2296,7 +2122,7 @@ ncplane_putstr_aligned(struct ncplane* n, int y, ncalign_e align, const char* s)
ncstrwidth ( s , & validbytes , & validwidth ) ;
int xpos = ncplane_halign ( n , align , validwidth ) ;
if ( xpos < 0 ) {
xpos = 0 ;
return - 1 ;
}
return ncplane_putstr_yx ( n , y , xpos , s ) ;
}
@ -2333,9 +2159,9 @@ API int ncplane_putnstr_aligned(struct ncplane* n, int y, ncalign_e align, size_
static inline int
ncplane_putnstr_yx ( struct ncplane * n , int y , int x , size_t s , const char * gclusters ) {
int ret = 0 ;
size_ t offset = 0 ;
in t offset = 0 ;
//fprintf(stderr, "PUT %zu at %d/%d [%.*s]\n", s, y, x, (int)s, gclusters);
while ( offset < s & & gclusters [ offset ] ) {
while ( ( size_t ) offset < s & & gclusters [ offset ] ) {
size_t wcs ;
int cols = ncplane_putegc_yx ( n , y , x , gclusters + offset , & wcs ) ;
if ( cols < 0 ) {
@ -2388,7 +2214,7 @@ ncplane_putwstr_aligned(struct ncplane* n, int y, ncalign_e align,
int width = wcswidth ( gclustarr , INT_MAX ) ;
int xpos = ncplane_halign ( n , align , width ) ;
if ( xpos < 0 ) {
xpos = 0 ;
return - 1 ;
}
return ncplane_putwstr_yx ( n , y , xpos , gclustarr ) ;
}
@ -2416,7 +2242,7 @@ ncplane_pututf32_yx(struct ncplane* n, int y, int x, uint32_t u){
memset ( & ps , 0 , sizeof ( ps ) ) ;
// this isn't going to be valid for reconstructued surrogate pairs...
// we need our own, or to use unistring or something.
size_t s = wcrtomb ( utf8c , ( wchar_t ) u , & ps ) ;
size_t s = wcrtomb ( utf8c , u , & ps ) ;
if ( s = = ( size_t ) - 1 ) {
return - 1 ;
}
@ -2426,7 +2252,7 @@ ncplane_pututf32_yx(struct ncplane* n, int y, int x, uint32_t u){
static inline int
ncplane_putwc_yx ( struct ncplane * n , int y , int x , wchar_t w ) {
return ncplane_pututf32_yx ( n , y , x , ( uint32_t ) w ) ;
return ncplane_pututf32_yx ( n , y , x , w ) ;
}
// Write 'w' at the current cursor position, using the plane's current styling.
@ -2456,7 +2282,7 @@ ncplane_putwc_utf32(struct ncplane* n, const wchar_t* w, unsigned* wchars){
utf32 + = ( w [ 1 ] & 0x3fflu ) ;
} else {
* wchars = 1 ;
utf32 = ( uint32_t ) * w ;
utf32 = * w ;
}
return ncplane_pututf32_yx ( n , - 1 , - 1 , utf32 ) ;
}
@ -2829,7 +2655,7 @@ nccell_set_fg_rgb(nccell* c, uint32_t channel){
// Set the cell's foreground palette index, set the foreground palette index
// bit, set it foreground-opaque, and clear the foreground default color bit.
static inline int
nccell_set_fg_palindex ( nccell * cl , unsigned idx ) {
nccell_set_fg_palindex ( nccell * cl , int idx ) {
return ncchannels_set_fg_palindex ( & cl - > channels , idx ) ;
}
@ -2861,7 +2687,7 @@ nccell_set_bg_rgb(nccell* c, uint32_t channel){
// Set the cell's background palette index, set the background palette index
// bit, set it background-opaque, and clear the background default color bit.
static inline int
nccell_set_bg_palindex ( nccell * cl , unsigned idx ) {
nccell_set_bg_palindex ( nccell * cl , int idx ) {
return ncchannels_set_bg_palindex ( & cl - > channels , idx ) ;
}
@ -2894,47 +2720,29 @@ nccell_bg_palindex_p(const nccell* cl){
return ncchannels_bg_palindex_p ( cl - > channels ) ;
}
// Extract the background alpha and coloring bits from a 64-bit channel
// pair as a single 32-bit value.
// Extract the 32-bit working background channel from an ncplane.
static inline uint32_t
ncplane_bchannel ( const struct ncplane * n ) {
return ncchannels_bchannel ( ncplane_channels ( n ) ) ;
}
// Extract the foreground alpha and coloring bits from a 64-bit channel
// pair as a single 32-bit value.
// Extract the 32-bit working foreground channel from an ncplane.
static inline uint32_t
ncplane_fchannel ( const struct ncplane * n ) {
return ncchannels_fchannel ( ncplane_channels ( n ) ) ;
}
// Set the alpha and coloring bits of the plane's current channels from a
// 64-bit pair of channels.
API void ncplane_set_channels ( struct ncplane * n , uint64_t channels )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
// Set the background alpha and coloring bits of the plane's current
// channels from a single 32-bit value.
API uint64_t ncplane_set_bchannel ( struct ncplane * n , uint32_t channel )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
// Set the foreground alpha and coloring bits of the plane's current
// channels from a single 32-bit value.
API uint64_t ncplane_set_fchannel ( struct ncplane * n , uint32_t channel )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API void ncplane_set_channels ( struct ncplane * n , uint64_t channels ) ;
// Set the specified style bits for the ncplane 'n', whether they're actively
// supported or not.
API void ncplane_set_styles ( struct ncplane * n , unsigned stylebits )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API void ncplane_set_styles ( struct ncplane * n , unsigned stylebits ) ;
// Add the specified styles to the ncplane's existing spec.
API void ncplane_on_styles ( struct ncplane * n , unsigned stylebits )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API void ncplane_on_styles ( struct ncplane * n , unsigned stylebits ) ;
// Remove the specified styles from the ncplane's existing spec.
API void ncplane_off_styles ( struct ncplane * n , unsigned stylebits )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
API void ncplane_off_styles ( struct ncplane * n , unsigned stylebits ) ;
// Extract 24 bits of working foreground RGB from an ncplane, shifted to LSBs.
static inline uint32_t
@ -2984,6 +2792,10 @@ ncplane_bg_rgb8(const struct ncplane* n, unsigned* r, unsigned* g, unsigned* b){
return ncchannels_bg_rgb8 ( ncplane_channels ( n ) , r , g , b ) ;
}
// Set an entire 32-bit channel of the plane
API uint64_t ncplane_set_fchannel ( struct ncplane * n , uint32_t channel ) ;
API uint64_t ncplane_set_bchannel ( struct ncplane * n , uint32_t channel ) ;
// Set the current fore/background color using RGB specifications. If the
// terminal does not support directly-specified 3x8b cells (24-bit "TrueColor",
// indicated by the "RGB" terminfo capability), the provided values will be
@ -3007,8 +2819,8 @@ API void ncplane_set_bg_default(struct ncplane* n);
// Set the ncplane's foreground palette index, set the foreground palette index
// bit, set it foreground-opaque, and clear the foreground default color bit.
API int ncplane_set_fg_palindex ( struct ncplane * n , unsigned idx ) ;
API int ncplane_set_bg_palindex ( struct ncplane * n , unsigned idx ) ;
API int ncplane_set_fg_palindex ( struct ncplane * n , int idx ) ;
API int ncplane_set_bg_palindex ( struct ncplane * n , int idx ) ;
// Set the alpha parameters for ncplane 'n'.
API int ncplane_set_fg_alpha ( struct ncplane * n , int alpha ) ;
@ -3072,7 +2884,7 @@ API void ncfadectx_free(struct ncfadectx* nctx);
// have loaded before the error are nccell_release()d. There must be at least
// six EGCs in gcluster.
static inline int
nccells_load_box ( struct ncplane * n , uint 16 _t styles , uint64_t channels ,
nccells_load_box ( struct ncplane * n , uint 32 _t styles , uint64_t channels ,
nccell * ul , nccell * ur , nccell * ll , nccell * lr ,
nccell * hl , nccell * vl , const char * gclusters ) {
int ulen ;
@ -3262,27 +3074,21 @@ API ALLOC struct ncvisual* ncvisual_from_file(const char* file)
// memory at 'rgba'. 'rgba' is laid out as 'rows' lines, each of which is
// 'rowstride' bytes in length. Each line has 'cols' 32-bit 8bpc RGBA pixels
// followed by possible padding (there will be 'rowstride' - 'cols' * 4 bytes
// of padding). The total size of 'rgba' is thus ('rows' * 'rowstride') bytes,
// of which ('rows' * 'cols' * 4) bytes are actual non-padding data. It is an
// error if any argument is not positive, if 'rowstride' is not a multiple of
// 4, or if 'rowstride' is less than 'cols' * 4.
// of padding). The total size of 'rgba' is thus (rows * rowstride) bytes, of
// which (rows * cols * 4) bytes are actual non-padding data.
API ALLOC struct ncvisual * ncvisual_from_rgba ( const void * rgba , int rows ,
int rowstride , int cols )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
// ncvisual_from_rgba(), but the pixels are 3-byte RGB. A is filled in
// throughout using 'alpha'. It is an error if 'rows', 'rowstride', or 'cols'
// is not positive, if 'rowstride' is not a multiple of 3, or if 'rowstride'
// is less than 'cols' * 3.
// throughout using 'alpha'.
API ALLOC struct ncvisual * ncvisual_from_rgb_packed ( const void * rgba , int rows ,
int rowstride , int cols ,
int alpha )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
// ncvisual_from_rgba(), but the pixels are 4-byte RGBx. A is filled in
// throughout using 'alpha'. It is an error if 'rows', 'cols', or 'rowstride'
// are not positive, if 'rowstride' is not a multiple of 4, or if 'rowstride'
// is less than 'cols' * 4.
// throughout using 'alpha'. rowstride must be a multiple of 4.
API ALLOC struct ncvisual * ncvisual_from_rgb_loose ( const void * rgba , int rows ,
int rowstride , int cols ,
int alpha )
@ -3291,8 +3097,6 @@ API ALLOC struct ncvisual* ncvisual_from_rgb_loose(const void* rgba, int rows,
// ncvisual_from_rgba(), but 'bgra' is arranged as BGRA. note that this is a
// byte-oriented layout, despite being bunched in 32-bit pixels; the lowest
// memory address ought be B, and A is reached by adding 3 to that address.
// It is an error if 'rows', 'cols', or 'rowstride' are not positive, if
// 'rowstride' is not a multiple of 4, or if 'rowstride' is less than 'cols' * 4.
API ALLOC struct ncvisual * ncvisual_from_bgra ( const void * bgra , int rows ,
int rowstride , int cols )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
@ -3300,9 +3104,6 @@ API ALLOC struct ncvisual* ncvisual_from_bgra(const void* bgra, int rows,
// ncvisual_from_rgba(), but 'data' is 'pstride'-byte palette-indexed pixels,
// arranged in 'rows' lines of 'rowstride' bytes each, composed of 'cols'
// pixels. 'palette' is an array of at least 'palsize' ncchannels.
// It is an error if 'rows', 'cols', 'rowstride', or 'pstride' are not
// positive, if 'rowstride' is not a multiple of 'pstride', or if 'rowstride'
// is less than 'cols' * 'pstride'.
API ALLOC struct ncvisual * ncvisual_from_palidx ( const void * data , int rows ,
int rowstride , int cols ,
int palsize , int pstride ,
@ -3321,10 +3122,6 @@ API ALLOC struct ncvisual* ncvisual_from_plane(const struct ncplane* n,
unsigned leny , unsigned lenx )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
// Construct an ncvisual from a nul-terminated Sixel control sequence.
API ALLOC struct ncvisual * ncvisual_from_sixel ( const char * s , unsigned leny , unsigned lenx )
__attribute__ ( ( nonnull ( 1 ) ) ) ;
# define NCVISUAL_OPTION_NODEGRADE 0x0001ull // fail rather than degrade
# define NCVISUAL_OPTION_BLEND 0x0002ull // use NCALPHA_BLEND with visual
# define NCVISUAL_OPTION_HORALIGNED 0x0004ull // x is an alignment, not absolute
@ -3390,7 +3187,7 @@ typedef struct ncvgeom {
unsigned cdimy , cdimx ; // terminal cell geometry when this was calculated
unsigned rpixy , rpixx ; // rendered pixel geometry (per visual_options)
unsigned rcelly , rcellx ; // rendered cell geometry (per visual_options)
unsigned scaley , scalex ; // source pixels per filled cell
unsigned scaley , scalex ; // pixels per filled cell (scale == c for bitmaps)
unsigned begy , begx ; // upper-left corner of used region
unsigned leny , lenx ; // geometry of used region
unsigned maxpixely , maxpixelx ; // only defined for NCBLIT_PIXEL
@ -3584,25 +3381,25 @@ API int ncblit_rgb_loose(const void* data, int linesize,
// Extract the 8-bit alpha component from a pixel
static inline unsigned
ncpixel_a ( uint32_t pixel ) {
return ( htole ( pixel ) & 0xff000000u ) > > 24u ;
return ( htole ( pixel ) & 0xff000000u l ) > > 24u ;
}
// Extract the 8-bit red component from an ABGR pixel
static inline unsigned
ncpixel_r ( uint32_t pixel ) {
return ( htole ( pixel ) & 0x000000ffu ) ;
return ( htole ( pixel ) & 0x000000ffu l ) ;
}
// Extract the 8-bit green component from an ABGR pixel
static inline unsigned
ncpixel_g ( uint32_t pixel ) {
return ( htole ( pixel ) & 0x0000ff00u ) > > 8u ;
return ( htole ( pixel ) & 0x0000ff00u l ) > > 8u ;
}
// Extract the 8-bit blue component from an ABGR pixel
static inline unsigned
ncpixel_b ( uint32_t pixel ) {
return ( htole ( pixel ) & 0x00ff0000u ) > > 16u ;
return ( htole ( pixel ) & 0x00ff0000u l ) > > 16u ;
}
// Set the 8-bit alpha component of an ABGR pixel
@ -3611,7 +3408,7 @@ ncpixel_set_a(uint32_t* pixel, unsigned a){
if ( a > 255 ) {
return - 1 ;
}
* pixel = htole ( ( htole ( * pixel ) & 0x00ffffffu ) | ( a < < 24u ) ) ;
* pixel = htole ( ( htole ( * pixel ) & 0x00ffffffu l ) | ( a < < 24u ) ) ;
return 0 ;
}
@ -3621,7 +3418,7 @@ ncpixel_set_r(uint32_t* pixel, unsigned r){
if ( r > 255 ) {
return - 1 ;
}
* pixel = htole ( ( htole ( * pixel ) & 0xffffff00u ) | r ) ;
* pixel = htole ( ( htole ( * pixel ) & 0xffffff00u l ) | r ) ;
return 0 ;
}
@ -3631,7 +3428,7 @@ ncpixel_set_g(uint32_t* pixel, unsigned g){
if ( g > 255 ) {
return - 1 ;
}
* pixel = htole ( ( htole ( * pixel ) & 0xffff00ffu ) | ( g < < 8u ) ) ;
* pixel = htole ( ( htole ( * pixel ) & 0xffff00ffu l ) | ( g < < 8u ) ) ;
return 0 ;
}
@ -3641,19 +3438,22 @@ ncpixel_set_b(uint32_t* pixel, unsigned b){
if ( b > 255 ) {
return - 1 ;
}
* pixel = htole ( ( htole ( * pixel ) & 0xff00ffffu ) | ( b < < 16u ) ) ;
* pixel = htole ( ( htole ( * pixel ) & 0xff00ffffu l ) | ( b < < 16u ) ) ;
return 0 ;
}
// Construct a libav-compatible ABGR pixel, clipping at [0, 255).
static inline uint32_t
ncpixel ( unsigned r , unsigned g , unsigned b ) {
ncpixel ( int r , int g , int b ) {
uint32_t pixel = 0 ;
ncpixel_set_a ( & pixel , 0xff ) ;
if ( r < 0 ) r = 0 ;
if ( r > 255 ) r = 255 ;
ncpixel_set_r ( & pixel , r ) ;
if ( g < 0 ) g = 0 ;
if ( g > 255 ) g = 255 ;
ncpixel_set_g ( & pixel , g ) ;
if ( b < 0 ) b = 0 ;
if ( b > 255 ) b = 255 ;
ncpixel_set_b ( & pixel , b ) ;
return pixel ;
@ -3801,7 +3601,8 @@ API struct ncplane* nctablet_plane(struct nctablet* t);
//
// You are encouraged to consult notcurses_metric(3).
API const char * ncnmetric ( uintmax_t val , size_t s , uintmax_t decimal ,
char * buf , int omitdec , uintmax_t mult , int uprefix )
char * buf , int omitdec , uintmax_t mult ,
int uprefix )
__attribute__ ( ( nonnull ( 4 ) ) ) ;
// The number of columns is one fewer, as the STRLEN expressions must leave
@ -3823,7 +3624,7 @@ API const char* ncnmetric(uintmax_t val, size_t s, uintmax_t decimal,
# define NCMETRICFWIDTH(x, cols) \
( ( int ) ( strlen ( x ) - ncstrwidth ( x , NULL , NULL ) + ( cols ) ) )
# define NCPREFIXFMT(x) NCMETRICFWIDTH((x), NCPREFIXCOLUMNS), (x)
# define NCIPREFIXFMT(x) NCMETRI C FWIDTH((x), NCIPREFIXCOLUMNS), (x)
# define NCIPREFIXFMT(x) NCMETRI X FWIDTH((x), NCIPREFIXCOLUMNS), (x)
# define NCBPREFIXFMT(x) NCMETRICFWIDTH((x), NCBPREFIXCOLUMNS), (x)
// Mega, kilo, gigafoo. Use PREFIXSTRLEN + 1 and PREFIXCOLUMNS.
@ -3915,7 +3716,7 @@ typedef struct ncselector_options {
uint64_t titlechannels ; // title channels
uint64_t footchannels ; // secondary and footer channels
uint64_t boxchannels ; // border channels
uint64_t flags ; // bitfield of NCSELECTOR_OPTION_* , currently unused
uint64_t flags ; // bitfield of NCSELECTOR_OPTION_*
} ncselector_options ;
API ALLOC struct ncselector * ncselector_create ( struct ncplane * n , const ncselector_options * opts )
@ -3994,7 +3795,7 @@ typedef struct ncmultiselector_options {
uint64_t titlechannels ; // title channels
uint64_t footchannels ; // secondary and footer channels
uint64_t boxchannels ; // border channels
uint64_t flags ; // bitfield of NCMULTISELECTOR_OPTION_* , currently unused
uint64_t flags ; // bitfield of NCMULTISELECTOR_OPTION_*
} ncmultiselector_options ;
API ALLOC struct ncmultiselector * ncmultiselector_create ( struct ncplane * n , const ncmultiselector_options * opts )