cffi heap allocations are zero-initialized #942

pull/950/head
nick black 4 years ago committed by Nick Black
parent f24bdd8249
commit 026b94969d

@ -7,6 +7,7 @@ steps:
- name: debian-build
image: dankamongmen/unstable_builder:2020-08-20a
commands:
- apt-get -y install python3-cffi
- export LANG=en_US.UTF-8
- mkdir build
- cd build
@ -15,7 +16,8 @@ steps:
- env TERM=xterm make test
- make install
- cd ../python
- python3 setup.py sdist build
- LDFLAGS=-L/usr/local/lib CFLAGS=-I/usr/local/include python3 setup.py sdist build install
- env TERM=xterm LD_LIBRARY_PATH=/usr/local/lib ./notcurses-pydemo
---
kind: pipeline
type: docker

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.14.0)
project(notcurses VERSION 1.6.16
project(notcurses VERSION 1.6.17
DESCRIPTION "Blingful UI for modern terminal emulators"
HOMEPAGE_URL "https://nick-black.com/dankwiki/index.php/notcurses"
LANGUAGES C CXX)
@ -98,7 +98,7 @@ endif()
endif()
find_library(LIBRT rt)
# libnotcurses (core shared library and static library)
# libnotcurses (core shared library, core static library)
file(GLOB NCSRCS CONFIGURE_DEPENDS src/lib/*.c src/lib/*.cpp)
add_library(notcurses SHARED ${NCSRCS})
if(${USE_STATIC})

@ -1,7 +1,7 @@
This document attempts to list user-visible changes and any major internal
rearrangements of Notcurses.
* 1.6.17 (not yet released)
* 1.6.17 (2020-08-22)
* `ncdirect_flush()` now takes a `const struct ncdirect*`.
* A `const char* title` field has been added to `ncplot_options`. If not
`NULL`, this title will be displayed to the right of any labels. Plot

@ -180,9 +180,9 @@ int notcurses_render_to_file(struct notcurses* nc, FILE* fp);
// Retrieve the contents of the specified cell as last rendered. The EGC is
// returned, or NULL on error. This EGC must be free()d by the caller. The
// attrword and channels are written to 'attrword' and 'channels', respectively.
// styles and channels are written to 'attrword' and 'channels', respectively.
char* notcurses_at_yx(struct notcurses* nc, int yoff, int xoff,
uint32_t* attrword, uint64_t* channels);
uint16_t* styles, uint64_t* channels);
```
One `ncplane` is guaranteed to exist: the "standard plane". The user cannot
@ -798,7 +798,7 @@ int ncplane_set_base_cell(struct ncplane* ncp, const cell* c);
// does not reset the base cell; this function must be called with an empty
// 'egc'. 'egc' must be a single extended grapheme cluster.
int ncplane_set_base(struct ncplane* ncp, const char* egc,
uint32_t attrword, uint64_t channels);
uint32_t styles, uint64_t channels);
// Extract the ncplane's base cell into 'c'. The reference is invalidated if
// 'ncp' is destroyed.
@ -834,18 +834,18 @@ not necessarily reflect anything on the actual screen).
```c
// 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
// attrword and channels are written to 'attrword' and 'channels', respectively.
char* ncplane_at_cursor(struct ncplane* n, uint32_t* attrword, uint64_t* channels);
// styles and channels are written to 'styles' and 'channels', respectively.
char* ncplane_at_cursor(struct ncplane* n, uint16_t* styles, 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.
int ncplane_at_cursor_cell(struct ncplane* n, cell* 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 attrword and
// channels are written to 'attrword' and 'channels', respectively.
// NULL on error. This EGC must be free()d by the caller. The styles and
// channels are written to 'styles' and 'channels', respectively.
char* ncplane_at_yx(const struct ncplane* n, int y, int x,
uint32_t* attrword, uint64_t* channels);
uint16_t* styles, uint64_t* channels);
// Retrieve the current contents of the specified cell into 'c'. This cell is
// invalidated if the associated plane is destroyed.
@ -1268,7 +1268,7 @@ Similarly, areas can be filled with a cell.
int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c);
// Draw a gradient with its upper-left corner at the current cursor position,
// stopping at 'ystop'x'xstop'. The glyph composed of 'egc' and 'attrword' is
// stopping at 'ystop'x'xstop'. The glyph composed of 'egc' and 'styles' is
// used for all cells. The channels specified by 'ul', 'ur', 'll', and 'lr'
// are composed into foreground and background gradients. To do a vertical
// gradient, 'ul' ought equal 'ur' and 'll' ought equal 'lr'. To do a
@ -1276,19 +1276,19 @@ int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c);
// color everything the same, all four channels should be equivalent. The
// resulting alpha values are equal to incoming alpha values. Returns the
// number of cells filled on success, or -1 on failure.
int ncplane_gradient(struct ncplane* n, const char* egc, uint32_t attrword,
int ncplane_gradient(struct ncplane* n, const char* egc, uint32_t styles,
uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr,
int ystop, int xstop);
// Draw a gradient with its upper-left corner at the current cursor position,
// having dimensions 'ylen'x'xlen'. See ncplane_gradient for more information.
static inline int
ncplane_gradient_sized(struct ncplane* n, const char* egc, uint32_t attrword,
ncplane_gradient_sized(struct ncplane* n, const char* egc, uint32_t styles,
uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr,
int ylen, int xlen){
int y, x;
ncplane_cursor_yx(n, &y, &x);
return ncplane_gradient(n, egc, attrword, ul, ur, ll, lr, y + ylen - 1, x + xlen - 1);
return ncplane_gradient(n, egc, styles, ul, ur, ll, lr, y + ylen - 1, x + xlen - 1);
}
// Do a high-resolution gradient using upper blocks and synced backgrounds.
@ -1304,7 +1304,7 @@ int ncplane_highgradient_sized(struct ncplane* n, uint32_t ul, uint32_t ur,
// Set the given style throughout the specified region, keeping content and
// channels unchanged. Returns the number of cells set, or -1 on failure.
int ncplane_format(struct ncplane* n, int ystop, int xstop, uint32_t attrword);
int ncplane_format(struct ncplane* n, int ystop, int xstop, uint32_t styles);
// Set the given channels throughout the specified region, keeping content and
// attributes unchanged. Returns the number of cells set, or -1 on failure.
@ -1521,20 +1521,33 @@ useful to use a `cell` when the same styling is used in a discontinuous manner.
// RGB is used if neither default terminal colors nor palette indexing are in
// play, and fully supports all transparency options.
typedef struct cell {
// These 32 bits are either a single-byte, single-character grapheme cluster
// (values 0--0x7f), or an offset into a per-ncplane attached pool of
// varying-length UTF-8 grapheme clusters. This pool may thus be up to 16MB.
uint32_t gcluster; // 4B -> 4B
// NCSTYLE_* attributes (16 bits) + 8 foreground palette index bits + 8
// background palette index bits. palette index bits are used only if the
// corresponding default color bit *is not* set, and the corresponding
// palette index bit *is* set.
uint32_t attrword; // + 4B -> 8B
// These 32 bits, together with the associated plane's associated egcpool,
// completely define this cell's EGC. Unless the EGC requires more than four
// bytes to encode as UTF-8, it will be inlined here. If more than four bytes
// are required, it will be spilled into the egcpool. In either case, there's
// a NUL-terminated string available without copying, because (1) the egcpool
// is all NUL-terminated sequences and (2) the fifth byte of this struct (the
// gcluster_backstop field, see below) is guaranteed to be zero, as are any
// unused bytes in gcluster.
//
// A spilled EGC is indicated by the value 0x01XXXXXX. This cannot alias a
// true supra-ASCII EGC, because UTF-8 only encodes bytes <= 0x80 when they
// are single-byte ASCII-derived values. The XXXXXX is interpreted as a 24-bit
// index into the egcpool. These pools may thus be up to 16MB.
//
// The cost of this scheme is that the character 0x01 (SOH) cannot be encoded
// in a cell, which is absolutely fine because what 70s horseshit is SOH? It
// must not be allowed through the API, or havoc will result.
uint32_t gcluster; // 4B → 4B
uint8_t gcluster_backstop; // 1B → 5B (8 bits of zero)
uint8_t reserved; // 1B → 6B (8 reserved bits, ought be zero)
uint16_t stylemask; // 2B → 8B (16 bits of NCSTYLE_* attributes)
// (channels & 0x8000000000000000ull): part of a wide glyph
// (channels & 0x4000000000000000ull): foreground is *not* "default color"
// (channels & 0x3000000000000000ull): foreground alpha (2 bits)
// (channels & 0x0800000000000000ull): foreground uses palette index
// (channels & 0x0700000000000000ull): reserved, must be 0
// (channels & 0x0400000000000000ull): glyph is entirely foreground
// (channels & 0x0300000000000000ull): reserved, must be 0
// (channels & 0x00ffffff00000000ull): foreground in 3x8 RGB (rrggbb)
// (channels & 0x0000000080000000ull): reserved, must be 0
// (channels & 0x0000000040000000ull): background is *not* "default color"
@ -1569,9 +1582,9 @@ before any other use. `cell_init()` and `CELL_TRIVIAL_INITIALIZER` both
simply zero out the `cell`.
```c
#define CELL_TRIVIAL_INITIALIZER { .gcluster = '\0', .attrword = 0, .channels = 0, }
#define CELL_SIMPLE_INITIALIZER(c) { .gcluster = (c), .attrword = 0, .channels = 0, }
#define CELL_INITIALIZER(c, a, chan) { .gcluster = (c), .attrword = (a), .channels = (chan), }
#define CELL_TRIVIAL_INITIALIZER { }
#define CELL_SIMPLE_INITIALIZER(c) { .gcluster = (c), .gcluster_backstop = 0, .reserved = 0, .stylemask = 0, .channels = 0, }
#define CELL_INITIALIZER(c, s, chan) { .gcluster = (c), .gcluster_backstop = 0, .reserved = 0, .stylemask = (s), .channels = (chan), }
static inline void
cell_init(cell* c){
@ -1606,8 +1619,8 @@ int cell_load(struct ncplane* n, cell* c, const char* gcluster);
// cell_load(), plus blast the styling with 'attr' and 'channels'.
static inline int
cell_prime(struct ncplane* n, cell* c, const char* gcluster,
uint32_t attr, uint64_t channels){
c->attrword = attr;
uint32_t stylemask, uint64_t channels){
c->stylemask = stylemask;
c->channels = channels;
int ret = cell_load(n, c, gcluster);
return ret;
@ -1639,29 +1652,29 @@ cell_strdup(const struct ncplane* n, const cell* c){
}
// Set the specified style bits for the cell 'c', whether they're actively
// supported or not.
// supported or not. Only the lower 16 bits are meaningful.
static inline void
cell_styles_set(cell* c, unsigned stylebits){
c->attrword = (c->attrword & ~NCSTYLE_MASK) | ((stylebits & NCSTYLE_MASK));
c->stylemask = stylebits & NCSTYLE_MASK;
}
// Extract the style bits from the cell's attrword.
// Extract the style bits from the cell.
static inline unsigned
cell_styles(const cell* c){
return c->attrword & NCSTYLE_MASK;
return c->stylemask;
}
// Add the specified styles (in the LSBs) to the cell's existing spec, whether
// they're actively supported or not.
static inline void
cell_styles_on(cell* c, unsigned stylebits){
c->attrword |= (stylebits & NCSTYLE_MASK;
c->stylemask |= (stylebits & NCSTYLE_MASK);
}
// Remove the specified styles (in the LSBs) from the cell's existing spec.
static inline void
cell_styles_off(cell* c, unsigned stylebits){
c->attrword &= ~(stylebits & NCSTYLE_MASK);
c->stylemask &= ~(stylebits & NCSTYLE_MASK);
}
// does the cell contain an East Asian Wide codepoint?
@ -1687,16 +1700,16 @@ const char* cell_extended_gcluster(const struct ncplane* n, const cell* c);
// have loaded before the error are cell_release()d. There must be at least
// six EGCs in gcluster.
static inline int
cells_load_box(struct ncplane* n, uint32_t attrs, uint64_t channels,
cells_load_box(struct ncplane* n, uint32_t style, uint64_t channels,
cell* ul, cell* ur, cell* ll, cell* lr,
cell* hl, cell* vl, const char* gclusters){
int ulen;
if((ulen = cell_prime(n, ul, gclusters, attrs, channels)) > 0){
if((ulen = cell_prime(n, ur, gclusters += ulen, attrs, channels)) > 0){
if((ulen = cell_prime(n, ll, gclusters += ulen, attrs, channels)) > 0){
if((ulen = cell_prime(n, lr, gclusters += ulen, attrs, channels)) > 0){
if((ulen = cell_prime(n, hl, gclusters += ulen, attrs, channels)) > 0){
if((ulen = cell_prime(n, vl, gclusters += ulen, attrs, channels)) > 0){
if((ulen = cell_prime(n, ul, gclusters, style, channels)) > 0){
if((ulen = cell_prime(n, ur, gclusters += ulen, style, channels)) > 0){
if((ulen = cell_prime(n, ll, gclusters += ulen, style, channels)) > 0){
if((ulen = cell_prime(n, lr, gclusters += ulen, style, channels)) > 0){
if((ulen = cell_prime(n, hl, gclusters += ulen, style, channels)) > 0){
if((ulen = cell_prime(n, vl, gclusters += ulen, style, channels)) > 0){
return 0;
}
cell_release(n, hl);

@ -38,7 +38,7 @@ PROJECT_NAME = Notcurses
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 1.6.16
PROJECT_NUMBER = 1.6.17
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

@ -5,12 +5,12 @@
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Noto+Sans" />
<title>notcurses</title>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-11.6.1635-1"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-11557335-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-11.6.1635-1');
gtag('config', 'UA-11557335-1');
</script>
</head>
<body>
@ -25,7 +25,7 @@
</h2>
</center>
<hr>
<h1><a href="https://nick-black.com/dankwiki/index.php/Notcurses">notcurses</a> man pages (v1.6.16)</h1>
<h1><a href="https://nick-black.com/dankwiki/index.php/Notcurses">notcurses</a> man pages (v1.6.17)</h1>
<iframe align="right" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&OneJS=1&Operation=GetAdHtml&MarketPlace=US&source=ac&ref=qf_sp_asin_til&ad_type=product_link&tracking_id=nickblack05-20&marketplace=amazon&region=US&placement=B086PNVNC9&asins=B086PNVNC9&linkId=bef6e495a4119e9da4cf26d76b5c55a3&show_border=false&link_opens_in_new_window=false&price_color=333333&title_color=0066c0&bg_color=ffffff"></iframe>
<a href="notcurses.3.html">notcurses(3)</a>—a blingful TUI library<br/>
<h2>Binaries (section 1)</h2>

@ -1,6 +1,6 @@
% ncneofetch(1)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses-demo(1)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses-input(1)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses-ncreel(1)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses-tester(1)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses-tetris(1)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses-view(1)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_capabilities(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_cell(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_channels(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% ncdirect_init(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_error(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_fade(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_fds(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_init(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_input(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_lines(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME
@ -31,43 +31,37 @@ notcurses_lines - operations on lines and boxes
#define NCBOXCORNER_SHIFT 8u
```
**int ncplane_box(struct ncplane* n, const cell* ul, const cell* ur,
const cell* ll, const cell* lr, const cell* hline,
const cell* vline, int ystop, int xstop,
unsigned ctlword);**
**int ncplane_box(struct ncplane* n, const cell* ul, const cell* ur, const cell* ll, const cell* lr, const cell* hline, const cell* vline, int ystop, int xstop, unsigned ctlword);**
**static inline int
ncplane_box_sized(struct ncplane* n, const cell* ul, const cell* ur,
const cell* ll, const cell* lr, const cell* hline,
const cell* vline, int ylen, int xlen, unsigned ctlword);**
**static inline int ncplane_box_sized(struct ncplane* n, const cell* ul, const cell* ur, const cell* ll, const cell* lr, const cell* hline, const cell* vline, int ylen, int xlen, unsigned ctlword);**
**static inline int ncplane_perimeter(struct ncplane* n, const cell* ul, const cell* ur, const cell* ll, const cell* lr, const cell* hline, const cell* vline, unsigned ctlword)**
**static inline int cells_load_box(struct ncplane* n, uint32_t attrs, uint64_t channels, cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl, const char* gclusters);**
**static inline int cells_load_box(struct ncplane* n, uint32_t styles, uint64_t channels, cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl, const char* gclusters);**
**static inline int cells_rounded_box(struct ncplane* n, uint32_t attr, uint64_t channels, cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl);**
**static inline int cells_rounded_box(struct ncplane* n, uint32_t styles, uint64_t channels, cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl);**
**static inline int ncplane_rounded_box(struct ncplane* n, uint32_t attr, uint64_t channels, int ystop, int xstop, unsigned ctlword);**
**static inline int ncplane_rounded_box(struct ncplane* n, uint32_t styles, uint64_t channels, int ystop, int xstop, unsigned ctlword);**
**static inline int ncplane_rounded_box_sized(struct ncplane* n, uint32_t attr, uint64_t channels, int ylen, int xlen, unsigned ctlword);**
**static inline int ncplane_rounded_box_sized(struct ncplane* n, uint32_t styles, uint64_t channels, int ylen, int xlen, unsigned ctlword);**
**static inline int cells_double_box(struct ncplane* n, uint32_t attr, uint64_t channels, cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl);**
**static inline int cells_double_box(struct ncplane* n, uint32_t styles, uint64_t channels, cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl);**
**static inline int ncplane_double_box(struct ncplane* n, uint32_t attr, uint64_t channels, int ystop, int xstop, unsigned ctlword);**
**static inline int ncplane_double_box(struct ncplane* n, uint32_t styles, uint64_t channels, int ystop, int xstop, unsigned ctlword);**
**static inline int ncplane_double_box_sized(struct ncplane* n, uint32_t attr, uint64_t channels, int ylen, int xlen, unsigned ctlword);**
**static inline int ncplane_double_box_sized(struct ncplane* n, uint32_t styles, uint64_t channels, int ylen, int xlen, unsigned ctlword);**
**int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c);**
**int ncplane_gradient(struct ncplane* n, const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ystop, int xstop);**
**int ncplane_gradient(struct ncplane* n, const char* egc, uint32_t stylemask, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ystop, int xstop);**
**static inline int ncplane_gradient_sized(struct ncplane* n, const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen);**
**static inline int ncplane_gradient_sized(struct ncplane* n, const char* egc, uint32_t stylemask, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen);**
**int ncplane_highgradient(struct ncplane* n, uint32_t ul, uint32_t ur, uint32_t ll, uint32_t lr, int ystop, int xstop);**
**int ncplane_highgradient_sized(struct ncplane* n, uint32_t ul, uint32_t ur, uint32_t ll, uint32_t lr, int ylen, int xlen);**
**int ncplane_format(struct ncplane* n, int ystop, int xstop, uint32_t attrword);**
**int ncplane_format(struct ncplane* n, int ystop, int xstop, uint32_t stylemask);**
**int ncplane_stain(struct ncplane* n, int ystop, int xstop, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr);**

@ -1,6 +1,6 @@
% notcurses_menu(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_metric(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_multiselector(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_output(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_palette(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_plane(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME
@ -86,7 +86,7 @@ notcurses_plane - operations on ncplanes
**void ncplane_set_channels(struct ncplane* nc, uint64_t channels);**
**void ncplane_set_attr(struct ncplane* nc, uint32_t attrword);**
**void ncplane_set_attr(struct ncplane* nc, uint32_t styles);**
**static inline unsigned ncplane_bchannel(struct ncplane* nc);**

@ -1,6 +1,6 @@
% notcurses_plot(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_reader(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_reel(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_refresh(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_render(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME
@ -12,7 +12,7 @@ notcurses_render - sync the physical display to the virtual ncplanes
**int notcurses_render(struct notcurses* nc);**
**char* notcurses_at_yx(struct notcurses* nc, int yoff, int xoff, uint32_t* attrword, uint64_t* channels);**
**char* notcurses_at_yx(struct notcurses* nc, int yoff, int xoff, uint16_t* styles, uint64_t* channels);**
**int notcurses_render_to_file(struct notcurses* nc, FILE* fp);**

@ -1,6 +1,6 @@
% notcurses_selector(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_stats(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_stdplane(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_stop(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -1,6 +1,6 @@
% notcurses_visual(3)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME
notcurses_visual - notcurses multimedia

@ -1899,7 +1899,7 @@ ncplane_fchannel(const struct ncplane* nc){
return channels_fchannel(ncplane_channels(nc));
}
API void ncplane_set_channels(struct ncplane* nc, uint64_t channels);
API void ncplane_set_channels(struct ncplane* n, uint64_t channels);
API void ncplane_set_attr(struct ncplane* n, unsigned stylebits);
@ -2120,18 +2120,18 @@ ncplane_rounded_box_sized(struct ncplane* n, uint32_t styles, uint64_t channels,
x + xlen - 1, ctlword);
}
API int cells_double_box(struct ncplane* n, uint32_t attr, uint64_t channels,
API int cells_double_box(struct ncplane* n, uint32_t styles, uint64_t channels,
cell* ul, cell* ur, cell* ll, cell* lr,
cell* hl, cell* vl);
static inline int
ncplane_double_box(struct ncplane* n, uint32_t attr, uint64_t channels,
ncplane_double_box(struct ncplane* n, uint32_t styles, uint64_t channels,
int ystop, int xstop, unsigned ctlword){
int ret = 0;
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
if((ret = cells_double_box(n, attr, channels, &ul, &ur, &ll, &lr, &hl, &vl)) == 0){
if((ret = cells_double_box(n, styles, channels, &ul, &ur, &ll, &lr, &hl, &vl)) == 0){
ret = ncplane_box(n, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword);
}
cell_release(n, &ul); cell_release(n, &ur);
@ -2165,11 +2165,11 @@ ncplane_perimeter_double(struct ncplane* n, uint32_t stylemask,
}
static inline int
ncplane_double_box_sized(struct ncplane* n, uint32_t attr, uint64_t channels,
ncplane_double_box_sized(struct ncplane* n, uint32_t styles, uint64_t channels,
int ylen, int xlen, unsigned ctlword){
int y, x;
ncplane_cursor_yx(n, &y, &x);
return ncplane_double_box(n, attr, channels, y + ylen - 1,
return ncplane_double_box(n, styles, channels, y + ylen - 1,
x + xlen - 1, ctlword);
}

@ -1,6 +1,6 @@
% notcurses-pydemo(1)
% nick black <nickblack@linux.com>
% v1.6.16
% v1.6.17
# NAME

@ -22,7 +22,7 @@ def read(fname):
setup(
name="notcurses",
version="1.6.16",
version="1.6.17",
packages=['notcurses'],
scripts=['notcurses-pydemo'],
package_dir={'': 'src'},

@ -56,10 +56,10 @@ int notcurses_render(struct notcurses*);
int notcurses_render_to_file(struct notcurses* nc, FILE* fp);
struct ncplane* notcurses_stdplane(struct notcurses*);
const struct ncplane* notcurses_stdplane_const(const struct notcurses* nc);
void ncplane_set_channels(struct ncplane* nc, uint64_t channels);
void ncplane_set_channels(struct ncplane* n, uint64_t channels);
void ncplane_set_attr(struct ncplane* n, unsigned stylebits);
int ncplane_set_base_cell(struct ncplane* ncp, const cell* c);
int ncplane_set_base(struct ncplane* ncp, const char* egc, uint32_t attrword, uint64_t channels);
int ncplane_set_base(struct ncplane* ncp, const char* egc, uint32_t styles, uint64_t channels);
int ncplane_base(struct ncplane* ncp, cell* c);
struct ncplane* notcurses_top(struct notcurses* n);
void notcurses_drop_planes(struct notcurses* nc);
@ -123,8 +123,9 @@ void* ncplane_set_userptr(struct ncplane* n, void* opaque);
void* ncplane_userptr(struct ncplane* n);
int ncplane_resize(struct ncplane* n, int keepy, int keepx, int keepleny,
int keeplenx, int yoff, int xoff, int ylen, int xlen);
uint64_t ncplane_channels(struct ncplane* n);
uint16_t ncplane_attr(struct ncplane* n);
uint64_t ncplane_channels(const struct ncplane* n);
uint16_t ncplane_attr(const struct ncplane* n);
unsigned ncplane_styles(const struct ncplane* n);
int ncplane_set_fg_rgb(struct ncplane* n, int r, int g, int b);
int ncplane_set_bg_rgb(struct ncplane* n, int r, int g, int b);
void ncplane_set_fg_rgb_clipped(struct ncplane* n, int r, int g, int b);
@ -172,9 +173,7 @@ int ncplane_putegc_yx(struct ncplane* n, int y, int x, const char* gclust, int*
int ncplane_putstr_aligned(struct ncplane* n, int y, ncalign_e align, const char* s);
int ncplane_putstr_stainable(struct ncplane* n, const char* s);
struct ncplane* ncplane_dup(const struct ncplane* n, void* opaque);
void cell_init(cell* c);
int cell_load(struct ncplane* n, cell* c, const char* gcluster);
int cell_prime(struct ncplane* n, cell* c, const char* gcluster, uint32_t attr, uint64_t channels);
int cell_duplicate(struct ncplane* n, cell* targ, const cell* c);
void cell_release(struct ncplane* n, cell* c);
const char* cell_extended_gcluster(const struct ncplane* n, const cell* c);
@ -335,13 +334,13 @@ int ncreel_destroy(struct ncreel* pr);
void* nctablet_userptr(struct nctablet* t);
struct ncplane* nctablet_ncplane(struct nctablet* t);
int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c);
int ncplane_gradient(struct ncplane* n, const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ystop, int xstop);
int ncplane_gradient(struct ncplane* n, const char* egc, uint32_t styles, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ystop, int xstop);
int ncplane_highgradient(struct ncplane* n, uint32_t ul, uint32_t ur, uint32_t ll, uint32_t lr, int ystop, int xstop);
int ncplane_highgradient_sized(struct ncplane* n, uint32_t ul, uint32_t ur, uint32_t ll, uint32_t lr, int ylen, int xlen);
int ncplane_putsimple_stainable(struct ncplane* n, char c);
int ncplane_putegc_stainable(struct ncplane* n, const char* gclust, int* sbytes);
int ncplane_putwegc_stainable(struct ncplane* n, const wchar_t* gclust, int* sbytes);
int ncplane_format(struct ncplane* n, int ystop, int xstop, uint32_t attrword);
int ncplane_format(struct ncplane* n, int ystop, int xstop, uint32_t styles);
int ncplane_stain(struct ncplane* n, int ystop, int xstop, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr);
int ncplane_rotate_cw(struct ncplane* n);
int ncplane_rotate_ccw(struct ncplane* n);

@ -5,6 +5,11 @@ import locale
import _cffi_backend
from _notcurses import lib, ffi
NCCHANNEL_ALPHA_MASK = 0x30000000
CELL_ALPHA_HIGHCONTRAST = 0x30000000
CELL_ALPHA_TRANSPARENT = 0x20000000
CELL_ALPHA_BLEND = 0x10000000
CELL_ALPHA_OPAQUE = 0x00000000
NCOPTION_INHIBIT_SETLOCALE = 0x0001
NCOPTION_VERIFY_SIXEL = 0x0002
NCOPTION_NO_WINCH_SIGHANDLER = 0x0004
@ -13,6 +18,68 @@ NCOPTION_RETAIN_CURSOR = 0x0010
NCOPTION_SUPPRESS_BANNERS = 0x0020
NCOPTION_NO_ALTERNATE_SCREEN = 0x0040
NCOPTION_NO_FONT_CHANGES = 0x0080
CELL_WIDEASIAN_MASK = 0x8000000000000000
CELL_NOBACKGROUND_MASK = 0x0400000000000000
CELL_BGDEFAULT_MASK = 0x0000000040000000
CELL_FGDEFAULT_MASK = (CELL_BGDEFAULT_MASK << 32)
CELL_BG_RGB_MASK = 0x0000000000ffffff
CELL_FG_RGB_MASK = (CELL_BG_RGB_MASK << 32)
CELL_BG_PALETTE = 0x0000000008000000
NCPALETTESIZE = 256
CELL_FG_PALETTE = (CELL_BG_PALETTE << 32)
CELL_BG_ALPHA_MASK = NCCHANNEL_ALPHA_MASK
CELL_FG_ALPHA_MASK = (CELL_BG_ALPHA_MASK << 32)
def channel_r(channel):
return (channel & 0xff0000) >> 16;
def channel_g(channel):
return (channel & 0x00ff00) >> 8;
def channel_b(channel):
return (channel & 0x0000ff);
def channel_rgb(channel):
return (channel_r(channel), channel_g(channel), channel_b(channel))
def channel_set_rgb(channel, r, g, b):
checkRGB(r, g, b)
c = (r << 16) | (g << 8) | b
return (channel & ~CELL_BG_RGB_MASK) | CELL_BGDEFAULT_MASK | c
def channels_fchannel(channels):
return channels & 0xffffffff00000000
def channels_bchannel(channels):
return channels & 0xffffffff
def channels_fg_rgb(channels):
return channel_rgb(channels_fchannel(channels))
def channels_set_fchannel(channels, channel):
return (channel << 32) | (channels & 0xffffffff)
def channels_set_fg_rgb(channels, r, g, b):
channel = channels_fchannel(channels)
channel = channel_set_rgb(channel, r, g, b)
return channels_set_fchannel(channels, channel)
def channels_bg_rgb(channels):
return channel_rgb(channels_bchannel(channels))
def channels_set_bchannel(channels, channel):
return (channels & 0xffffffff00000000) | channel;
def channels_set_bg_rgb(channels, r, g, b):
channel = channels_bchannel(channels)
channel = channel_set_rgb(channel, r, g, b)
return channels_set_bchannel(channels, channel);
def ncplane_fg_rgb(n, r, g, b):
return channels_fg_rgb(ncplane_channels(n))
def ncplane_bg_rgb(n, r, g, b):
return channels_bg_rgb(ncplane_channels(n))
class NotcursesError(Exception):
"""Base class for notcurses exceptions."""
@ -31,23 +98,21 @@ class Cell:
def __init__(self, ncplane, egc):
self.ncp = ncplane
self.c = ffi.new("cell *")
self.c.gcluster = egc
self.c.stylemask = 0
self.c.channels = 0
self.c.gcluster = egc # FIXME need use cell_load
def __del__(self):
lib.cell_release(self.ncp.getNcplane(), self.c)
def setFgRGB(self, r, g, b):
checkRGB(r, g, b)
lib.cell_set_fg_rgb(self.c, r, g, b)
channel = channels_fchannel(self.c.channels)
c = (r << 16) | (g << 8) | b;
channel = (channel & ~CELL_BG_RGB_MASK) | CELL_BGDEFAULT_MASK | c;
self.c.channels = (channel << 32) | (self.c.channels & 0xffffffff);
def setBgRGB(self, r, g, b):
checkRGB(r, g, b)
lib.cell_set_bg_rgb(self.c, r, g, b)
def simpleP(self):
return self.c.gcluster < 0x80
channel = channels_bchannel(self.c.channels)
def getNccell(self):
return self.c
@ -68,15 +133,10 @@ class Ncplane:
if x < -1:
raise ValueError("Bad x position")
c = Cell(self, ch)
if not c.simpleP():
raise ValueError("Bad simple value")
r = ffi.new("unsigned *")
g = ffi.new("unsigned *")
b = ffi.new("unsigned *")
lib.ncplane_fg_rgb(self.n, r, g, b)
c.setFgRGB(r[0], g[0], b[0])
lib.ncplane_bg_rgb(self.n, r, g, b)
c.setBgRGB(r[0], g[0], b[0])
(r, g, b) = self.getFgRGB()
c.setFgRGB(r, g, b)
(r, g, b) = self.getBgRGB()
c.setBgRGB(r, g, b)
return lib.ncplane_putc_yx(self.n, y, x, c.getNccell())
def getDimensions(self):
@ -85,13 +145,25 @@ class Ncplane:
lib.ncplane_dim_yx(self.n, y, x)
return (y[0], x[0])
def getFChannel(self):
return channels_fchannel(lib.ncplane_channels(self.n));
def getBChannel(self):
return channels_bchannel(lib.ncplane_channels(self.n));
def getFgRGB(self):
return channel_rgb(self.getFChannel())
def getBgRGB(self):
return channel_rgb(self.getBChannel())
def setFgRGB(self, r, g, b):
checkRGB(r, g, b)
lib.ncplane_set_fg_rgb(self.n, r, g, b)
lib.ncplane_set_fg(self.n, channel_set_rgb(self.getFChannel(), r, g, b))
def setBgRGB(self, r, g, b):
checkRGB(r, g, b)
lib.ncplane_set_bg_rgb(self.n, r, g, b)
lib.ncplane_set_bg(self.n, channel_set_rgb(self.getBChannel(), r, g, b))
class Notcurses:
def __init__(self):
@ -138,3 +210,5 @@ class Ncdirect:
if __name__ == '__main__':
locale.setlocale(locale.LC_ALL, "")
nc = Notcurses()
n = nc.stdplane()
nc.render()

@ -1,6 +1,6 @@
[package]
name = "libnotcurses-sys"
version = "1.6.16"
version = "1.6.17"
authors = ["nick black <dankamongmen@gmail.com>"]
license = "Apache-2.0"
edition = "2018"

@ -7,7 +7,7 @@ use std::path::PathBuf;
// largely taken from https://rust-lang.github.io/rust-bindgen/tutorial-3.html
fn main() {
let plib = pkg_config::Config::new()
.atleast_version("1.6.16")
.atleast_version("1.6.17")
.probe("notcurses")
.unwrap();

@ -532,13 +532,13 @@ int fpsgraph_init(struct notcurses* nc){
int dimy, dimx;
notcurses_term_dim_yx(nc, &dimy, &dimx);
struct ncplane* newp = ncplane_new(nc, PLOTHEIGHT, dimx, dimy - PLOTHEIGHT, 0, NULL);
uint32_t attrword = 0;
uint32_t style = 0;
uint64_t channels = 0;
channels_set_fg_alpha(&channels, CELL_ALPHA_BLEND);
channels_set_fg(&channels, 0x201020);
channels_set_bg_alpha(&channels, CELL_ALPHA_BLEND);
channels_set_bg(&channels, 0x201020);
ncplane_set_base(newp, "", attrword, channels);
ncplane_set_base(newp, "", style, channels);
ncplot_options opts;
memset(&opts, 0, sizeof(opts));
opts.flags = NCPLOT_OPTION_LABELTICKSD | NCPLOT_OPTION_EXPONENTIALD;

@ -277,9 +277,9 @@ ncdirect_dump_plane(ncdirect* n, const ncplane* np, int xoff){
}
}
for(int x = 0 ; x < dimx ; ++x){
uint16_t attrword;
uint16_t stylemask;
uint64_t channels;
char* egc = ncplane_at_yx(np, y, x, &attrword, &channels);
char* egc = ncplane_at_yx(np, y, x, &stylemask, &channels);
if(egc == nullptr){
return -1;
}
@ -466,6 +466,11 @@ int ncdirect_stop(ncdirect* nc){
ret = -1;
}
if(nc->ctermfd >= 0){
if(nc->ctermfd >= 0){
if(nc->tcache.cnorm && tty_emit("cnorm", nc->tcache.cnorm, nc->ctermfd)){
ret = -1;
}
}
ret |= close(nc->ctermfd);
}
delete(nc);
@ -499,11 +504,11 @@ ncdirect_style_emit(ncdirect* n, const char* sgr, unsigned stylebits, FILE* out)
}
int ncdirect_styles_on(ncdirect* n, unsigned stylebits){
uint32_t attrword = n->attrword | stylebits;
if(ncdirect_style_emit(n, n->tcache.sgr, attrword, n->ttyfp) == 0){
if(term_setstyle(n->ttyfp, n->attrword, attrword, NCSTYLE_ITALIC,
uint32_t stylemask = n->stylemask | stylebits;
if(ncdirect_style_emit(n, n->tcache.sgr, stylemask, n->ttyfp) == 0){
if(term_setstyle(n->ttyfp, n->stylemask, stylemask, NCSTYLE_ITALIC,
n->tcache.italics, n->tcache.italoff) == 0){
n->attrword = attrword;
n->stylemask = stylemask;
return 0;
}
}
@ -512,11 +517,11 @@ int ncdirect_styles_on(ncdirect* n, unsigned stylebits){
// turn off any specified stylebits
int ncdirect_styles_off(ncdirect* n, unsigned stylebits){
uint32_t attrword = n->attrword & ~stylebits;
if(ncdirect_style_emit(n, n->tcache.sgr, attrword, n->ttyfp) == 0){
if(term_setstyle(n->ttyfp, n->attrword, attrword, NCSTYLE_ITALIC,
uint32_t stylemask = n->stylemask & ~stylebits;
if(ncdirect_style_emit(n, n->tcache.sgr, stylemask, n->ttyfp) == 0){
if(term_setstyle(n->ttyfp, n->stylemask, stylemask, NCSTYLE_ITALIC,
n->tcache.italics, n->tcache.italoff) == 0){
n->attrword = attrword;
n->stylemask = stylemask;
return 0;
}
}
@ -525,11 +530,11 @@ int ncdirect_styles_off(ncdirect* n, unsigned stylebits){
// set the current stylebits to exactly those provided
int ncdirect_styles_set(ncdirect* n, unsigned stylebits){
uint32_t attrword = stylebits;
if(ncdirect_style_emit(n, n->tcache.sgr, attrword, n->ttyfp) == 0){
if(term_setstyle(n->ttyfp, n->attrword, attrword, NCSTYLE_ITALIC,
uint32_t stylemask = stylebits;
if(ncdirect_style_emit(n, n->tcache.sgr, stylemask, n->ttyfp) == 0){
if(term_setstyle(n->ttyfp, n->stylemask, stylemask, NCSTYLE_ITALIC,
n->tcache.italics, n->tcache.italoff) == 0){
n->attrword = attrword;
n->stylemask = stylemask;
return 0;
}
}

@ -249,12 +249,12 @@ typedef struct tinfo {
} tinfo;
typedef struct ncdirect {
int attrword; // current styles
palette256 palette; // 256-indexed palette can be used instead of/with RGB
FILE* ttyfp; // FILE* for output tty
int ctermfd; // fd for controlling terminal
tinfo tcache; // terminfo cache
unsigned fgrgb, bgrgb; // last RGB values of foreground/background
uint16_t stylemask; // current styles
bool fgdefault, bgdefault; // are FG/BG currently using default colors?
bool utf8; // are we using utf-8 encoding, as hoped?
} ncdirect;

@ -12,9 +12,9 @@ NCDIR="$1"
[ -d "$NCDIR" ] || { usage >&2 ; exit 1 ; }
generate_lists () {
grep -h ^API "$1"/include/notcurses/*.h
grep -h -A1 ^static\ inline "$1"/include/notcurses/*.h | \
sed -e '/^--$/d' -e 'N;s/\n/ /' -e 's/\(.*\){$/\1;/'
grep -h ^API "$1"/include/notcurses/*.h | grep -v inline | sort
grep -h -A1 ^API\ inline "$1"/include/notcurses/*.h | \
sed -e '/^--$/d' -e 'N;s/\n/ /' -e 's/\(.*\){$/\1;/' | sort
}
generate_lists "$NCDIR" | sed -e 's/RESTRICT/restrict/g' | sort
generate_lists "$NCDIR" | sed -e 's/RESTRICT/restrict/g'

@ -20,9 +20,11 @@ for i in $BUMP ; do
sed -i -e "s/$OLDVERSION/$VERSION/g" $i
done
BUILDDIR="build-$VERSION"
# do a build with Doxygen enabled, upload docs, clean it up
mkdir build
cd build
mkdir "$BUILDDIR"
cd "$BUILDDIR"
cmake -DUSE_DOXYGEN=on ..
make -j
make test
@ -30,7 +32,6 @@ ssh qemfd.net rm -rf /var/www/notcurses/html
scp -r html qemfd.net:/var/www/notcurses/html
scp *.html ../doc/man/index.html qemfd.net:/var/www/notcurses/
cd ..
rm -rf build
# if that all worked, commit, push, and tag
git commit -a -m v$VERSION
@ -51,7 +52,7 @@ echo "The bastards are trying to immanentize the Eschaton"
# requires token in ~/.netrc
github-release dankamongmen/notcurses create v$VERSION --name "v$VERSION$QUIP" --publish $TARBALL.asc
cd build
cd "$BUILDDIR"
sudo make install
cd ../python
python3 setup.py sdist
@ -60,5 +61,5 @@ twine upload -s -udankamongmen dist/*
cd ../rust
cargo clean
cargo publish
cd ../build
cd "../$BUILDDIR"
cat install_manifest.txt | sudo xargs rm

Loading…
Cancel
Save