mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
Add four new fields to notcurses_options: margin_{tblr}, which requests margins to the top, right, bottom, and left. Render only within those margins, leaving the screen otherwise untouched (well, cleared if using the alternate screen). #293
This commit is contained in:
parent
982d729c69
commit
c056a0a026
21
README.md
21
README.md
@ -35,7 +35,7 @@ Packages for Debian Unstable and Ubuntu Focal are available from [DSSCAW](https:
|
||||
* [Features missing relative to NCURSES](#features-missing-relative-to-ncurses)
|
||||
* [Adapting NCURSES programs](#adapting-ncurses-programs)
|
||||
* [Environment notes](#environment-notes)
|
||||
* [DirectColor detection](#DirectColor-detection)
|
||||
* [TrueColor detection](#TrueColor-detection)
|
||||
* [Fonts](#fonts)
|
||||
* [FAQs](#faqs)
|
||||
* [Supplemental material](#supplemental-material)
|
||||
@ -57,9 +57,9 @@ Packages for Debian Unstable and Ubuntu Focal are available from [DSSCAW](https:
|
||||
|
||||
notcurses abandons the X/Open Curses API bundled as part of the Single UNIX
|
||||
Specification. The latter shows its age, and seems not capable of making use of
|
||||
terminal functionality such as unindexed 24-bit color ("DirectColor", not to be
|
||||
confused with 8-bit indexed 24-bit color, aka "TrueColor" or (by NCURSES) as
|
||||
"extended color"). For some necessary background, consult Thomas E. Dickey's
|
||||
terminal functionality such as unindexed 24-bit color ("TrueColor", not to be
|
||||
confused with the 8-bit indexed 24-bit "extended color" of NCURSES).
|
||||
For some necessary background, consult Thomas E. Dickey's
|
||||
superb and authoritative [NCURSES FAQ](https://invisible-island.net/ncurses/ncurses.faq.html#xterm_16MegaColors).
|
||||
As such, notcurses is not a drop-in Curses replacement. It is almost certainly
|
||||
less portable, and definitely tested on less hardware. Sorry about that.
|
||||
@ -212,6 +212,11 @@ typedef struct notcurses_options {
|
||||
// Progressively higher log levels result in more logging to stderr. By
|
||||
// default, nothing is printed to stderr once fullscreen service begins.
|
||||
ncloglevel_e loglevel;
|
||||
// Desirable margins. If all are 0 (default), we will render to the entirety
|
||||
// of the screen. If the screen is too small, we do what we can--this is
|
||||
// strictly best-effort. Absolute coordinates are relative to the rendering
|
||||
// area ((0, 0) is always the origin of the rendering area).
|
||||
int margin_t, margin_r, margin_b, margin_l;
|
||||
} notcurses_options;
|
||||
|
||||
// Initialize a notcurses context on the connected terminal at 'fp'. 'fp' must
|
||||
@ -2498,12 +2503,12 @@ These are pretty obvious, implementation-wise.
|
||||
* The unit tests assume dimensions of at least 80x24. They might work in a
|
||||
smaller terminal. They might not. Don't file bugs on it.
|
||||
|
||||
### DirectColor detection
|
||||
### TrueColor detection
|
||||
|
||||
notcurses aims to use only information found in the terminal's terminfo entry to detect capabilities, DirectColor
|
||||
notcurses aims to use only information found in the terminal's terminfo entry to detect capabilities, TrueColor
|
||||
being one of them. Support for this is indicated by terminfo having a flag, added in NCURSES 6.1, named `RGB` set
|
||||
to `true`. However, as of today there are few and far between terminfo entries which have the capability in their
|
||||
database entry and so DirectColor won't be used in most cases. Terminal emulators have had for years a kludge to
|
||||
database entry and so TrueColor won't be used in most cases. Terminal emulators have had for years a kludge to
|
||||
work around this limitation of terminfo in the form of the `COLORTERM` environment variable which, if set to either
|
||||
`truecolor` or `24bit` does the job of indicating the capability of sending the escapes 48 and 38 together with a
|
||||
tripartite RGB (0 ≤ c ≤ 255 for all three components) to specify fore- and background colors.
|
||||
@ -2590,7 +2595,7 @@ up someday **FIXME**.
|
||||
I study the history of NCURSES, primarily using Thomas E. Dickey's FAQ and
|
||||
the mailing list archives.
|
||||
* 2019-11-14: I file [Outcurses issue #56](https://github.com/dankamongmen/ncreels/issues/56)
|
||||
regarding use of DirectColor in outcurses. This is partially inspired by
|
||||
regarding use of TrueColor in outcurses. This is partially inspired by
|
||||
Lexi Summer Hale's essay [everything you ever wanted to know about terminals](http://xn--rpa.cc/irl/term.html).
|
||||
I get into contact with Thomas E. Dickey and confirm that what I'm hoping
|
||||
to do doesn't really fit in with the codified Curses API.
|
||||
|
@ -9,13 +9,14 @@ notcurses-demo - Show off some notcurses features
|
||||
# SYNOPSIS
|
||||
|
||||
**notcurses-demo** [**-h|--help**] [**-p path**] [**-d delaymult**]
|
||||
[**-l loglevel**] [**-f renderfile**] [**-J jsonfile**] [**-ikVc**] demospec
|
||||
[**-l loglevel**] [**-f renderfile**] [**-J jsonfile**] [**-m margins**]
|
||||
[**-ikVc**] demospec
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
**notcurses-demo** demonstrates the capabilities of the notcurses library. It
|
||||
can be run in any terminal emulator or console with a correct terminfo(5)
|
||||
database, but is at is best in a "DirectColor" 24bpp RGB environment. If
|
||||
database, but is at is best in a 24bpp TrueColor RGB environment. If
|
||||
**notcurses-demo** seems to generate garbage, something is likely configured in
|
||||
a way that is going to prevent notcurses from working.
|
||||
|
||||
@ -53,6 +54,8 @@ At any time, press 'q' to quit. The demo is best run in at least an 80x45 termin
|
||||
|
||||
**-J jsonfile**: Emit JSON summary of run to **jsonfile**.
|
||||
|
||||
**-m margins**: Define rendering margins (see below).
|
||||
|
||||
**-k**: Inhibit use of the alternate screen. Necessary if you want the output left on your terminal after the program exits.
|
||||
|
||||
**-c**: Do not attempt to seed the PRNG. This is useful when benchmarking.
|
||||
@ -65,6 +68,11 @@ At any time, press 'q' to quit. The demo is best run in at least an 80x45 termin
|
||||
|
||||
demospec: Select which demos to run, and what order to run them in. The default is **ixethbcgrwuvlfsjo**. See above for a list of demos.
|
||||
|
||||
Default margins are all 0, and thus the full screen will be rendered. Using
|
||||
**-m**, margins can be supplied. Provide a single number to set all four margins
|
||||
to the same value, or four comma-delimited values for the top, right, bottom,
|
||||
and left margins respectively. Negative margins are illegal.
|
||||
|
||||
# NOTES
|
||||
|
||||
Proper display requires:
|
||||
|
@ -17,7 +17,7 @@ notcurses - TUI library for modern terminal emulators
|
||||
notcurses builds atop the **terminfo(5)** abstraction layer to provide
|
||||
reasonably portable vivid character displays. It is an intellectual descendant
|
||||
of **ncurses(3NCURSES)**, but goes beyond that library (and the X/Open Curses
|
||||
API it implements). notcurses is capable of subregion fades, 24bpp DirectColor,
|
||||
API it implements). notcurses is capable of subregion fades, 24bpp TrueColor,
|
||||
transparency, multimedia, and safe multithreaded use.
|
||||
|
||||
A program wishing to use notcurses will need to link it, ideally using the
|
||||
|
@ -19,6 +19,7 @@ typedef struct notcurses_options {
|
||||
bool no_quit_sighandlers;
|
||||
bool no_winch_sighandler;
|
||||
FILE* renderfp;
|
||||
int margin_t, margin_r, margin_b, margin_l;
|
||||
} notcurses_options;
|
||||
```
|
||||
|
||||
@ -58,6 +59,16 @@ information and some details of the configured terminal. This can be inhibited
|
||||
with **suppress_banner**. This will also inhibit the performance summary normally
|
||||
printed by **notcurses_stop(3)**.
|
||||
|
||||
Notcurses can render to a subregion of the terminal by specifying desired
|
||||
margins on all four sides. By default, all margins are zero, and thus rendering
|
||||
will be performed on the entirety of the viewing area. This is orthogonal to
|
||||
use of the alternate screen; using the alternate screen plus margins will see
|
||||
the full screen cleared, followed by rendering to a subregion. Inhibiting the
|
||||
alternate screen plus margins will see rendering to a subregion, with the screen
|
||||
outside this region not cleared. This is the only means by which existing
|
||||
output can be undisturbed by notcurses. Margins are best-effort. Supplying any
|
||||
negative margin is an error.
|
||||
|
||||
## Fatal signals
|
||||
|
||||
It is important to reset the terminal before exiting, whether terminating due
|
||||
|
@ -107,8 +107,6 @@ mbswidth(const char* mbs){
|
||||
return cols;
|
||||
}
|
||||
|
||||
#define NCPALETTESIZE 256
|
||||
|
||||
// A cell corresponds to a single character cell on some plane, which can be
|
||||
// occupied by a single grapheme cluster (some root spacing glyph, along with
|
||||
// possible combining characters, which might span multiple columns). At any
|
||||
@ -232,6 +230,11 @@ typedef struct notcurses_options {
|
||||
// Progressively higher log levels result in more logging to stderr. By
|
||||
// default, nothing is printed to stderr once fullscreen service begins.
|
||||
ncloglevel_e loglevel;
|
||||
// Desirable margins. If all are 0 (default), we will render to the entirety
|
||||
// of the screen. If the screen is too small, we do what we can--this is
|
||||
// strictly best-effort. Absolute coordinates are relative to the rendering
|
||||
// area ((0, 0) is always the origin of the rendering area).
|
||||
int margin_t, margin_r, margin_b, margin_l;
|
||||
} notcurses_options;
|
||||
|
||||
// Initialize a notcurses context on the connected terminal at 'fp'. 'fp' must
|
||||
@ -953,6 +956,7 @@ API int ncplane_stain(struct ncplane* n, int ystop, int xstop, uint64_t ul,
|
||||
// excluding the base cell.
|
||||
API void ncplane_erase(struct ncplane* n);
|
||||
|
||||
#define NCPALETTESIZE 256
|
||||
#define CELL_WIDEASIAN_MASK 0x8000000080000000ull
|
||||
#define CELL_BGDEFAULT_MASK 0x0000000040000000ull
|
||||
#define CELL_FGDEFAULT_MASK (CELL_BGDEFAULT_MASK << 32u)
|
||||
|
@ -72,6 +72,11 @@ typedef struct notcurses_options {
|
||||
// Progressively higher log levels result in more logging to stderr. By
|
||||
// default, nothing is printed to stderr once fullscreen service begins.
|
||||
ncloglevel_e loglevel;
|
||||
// Desirable margins. If all are 0 (default), we will render to the entirety
|
||||
// of the screen. If the screen is too small, we do what we can--this is
|
||||
// strictly best-effort. Absolute coordinates are relative to the rendering
|
||||
// area ((0, 0) is always the origin of the rendering area).
|
||||
int margin_t, margin_r, margin_b, margin_l;
|
||||
} notcurses_options;
|
||||
struct notcurses* notcurses_init(const notcurses_options*, FILE*);
|
||||
int notcurses_stop(struct notcurses*);
|
||||
@ -322,7 +327,7 @@ typedef struct multiselector_options {
|
||||
uint64_t bgchannels; // background channels, used only in body
|
||||
} multiselector_options;
|
||||
struct ncmultiselector* ncmultiselector_create(struct ncplane* n, int y, int x, const multiselector_options* opts);
|
||||
int ncmultiselector_selected(struct ncmultiselector* n, bool* selected, unsigned n);
|
||||
int ncmultiselector_selected(struct ncmultiselector* n, bool* selected, unsigned count);
|
||||
struct ncplane* ncmultiselector_plane(struct ncmultiselector* n);
|
||||
bool ncmultiselector_offer_input(struct ncmultiselector* n, const struct ncinput* nc);
|
||||
void ncmultiselector_destroy(struct ncmultiselector* n, char** item);
|
||||
|
@ -21,7 +21,7 @@ fn main() {
|
||||
// to bindgen, and lets you build up options for
|
||||
// the resulting bindings.
|
||||
let bindings = bindgen::Builder::default()
|
||||
.clang_arg("-I../../include") // FIXME pass via envvar?
|
||||
.clang_arg("-I../../include -D_XOPEN_SOURCE") // FIXME pass via envvar?
|
||||
// The input header we would like to generate
|
||||
// bindings for.
|
||||
.header("wrapper.h")
|
||||
|
@ -11,3 +11,4 @@ homepage = "https://nick-black.com/dankwiki/index.php/Notcurses"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
libnotcurses-sys = "^1.2.3"
|
||||
|
@ -10,9 +10,9 @@
|
||||
#include <stdatomic.h>
|
||||
#include "demo.h"
|
||||
|
||||
// ansi terminal definition-4-life
|
||||
// (non-)ansi terminal definition-4-life
|
||||
static const int MIN_SUPPORTED_ROWS = 24;
|
||||
static const int MIN_SUPPORTED_COLS = 80;
|
||||
static const int MIN_SUPPORTED_COLS = 76; // allow a bit of margin, sigh
|
||||
|
||||
static int democount;
|
||||
static demoresult* results;
|
||||
@ -120,7 +120,7 @@ static struct {
|
||||
static void
|
||||
usage(const char* exe, int status){
|
||||
FILE* out = status == EXIT_SUCCESS ? stdout : stderr;
|
||||
fprintf(out, "usage: %s [ -hVikc ] [ -p path ] [ -l loglevel ] [ -d mult ] [ -J jsonfile ] [ -f renderfile ] demospec\n", exe);
|
||||
fprintf(out, "usage: %s [ -hVikc ] [ -m margins ] [ -p path ] [ -l loglevel ] [ -d mult ] [ -J jsonfile ] [ -f renderfile ] demospec\n", exe);
|
||||
fprintf(out, " -h: this message\n");
|
||||
fprintf(out, " -V: print program name and version\n");
|
||||
fprintf(out, " -l: logging level (%d: silent..%d: manic)\n", NCLOGLEVEL_SILENT, NCLOGLEVEL_TRACE);
|
||||
@ -131,6 +131,7 @@ usage(const char* exe, int status){
|
||||
fprintf(out, " -J: emit JSON summary to file\n");
|
||||
fprintf(out, " -c: constant PRNG seed, useful for benchmarking\n");
|
||||
fprintf(out, " -p: data file path (default: %s)\n", NOTCURSES_SHARE);
|
||||
fprintf(out, " -m: margin, or 4 comma-separated margins\n");
|
||||
fprintf(out, "if no specification is provided, run %s\n", DEFAULT_DEMO);
|
||||
for(size_t i = 0 ; i < sizeof(demos) / sizeof(*demos) ; ++i){
|
||||
if(demos[i].name){
|
||||
@ -140,6 +141,53 @@ usage(const char* exe, int status){
|
||||
exit(status);
|
||||
}
|
||||
|
||||
// extract an integer, which must be non-negative, and followed by either a
|
||||
// comma or a NUL terminator.
|
||||
static int
|
||||
lex_long(const char* op, int* i, char** endptr){
|
||||
errno = 0;
|
||||
long l = strtol(op, endptr, 10);
|
||||
if(l < 0 || (l == LONG_MAX && errno == ERANGE) || (l > INT_MAX)){
|
||||
fprintf(stderr, "Invalid margin: %s\n", op);
|
||||
return -1;
|
||||
}
|
||||
if((**endptr != ',' && **endptr) || *endptr == op){
|
||||
fprintf(stderr, "Invalid margin: %s\n", op);
|
||||
return -1;
|
||||
}
|
||||
*i = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lex_margins(const char* op, notcurses_options* opts){
|
||||
if(opts->margin_t || opts->margin_r || opts->margin_b || opts->margin_l){
|
||||
fprintf(stderr, "Provided margins twice!\n");
|
||||
return -1;
|
||||
}
|
||||
char* eptr;
|
||||
if(lex_long(op, &opts->margin_t, &eptr)){
|
||||
return -1;
|
||||
}
|
||||
if(!*eptr){ // allow a single value to be specified for all four margins
|
||||
opts->margin_r = opts->margin_l = opts->margin_b = opts->margin_t;
|
||||
return 0;
|
||||
}
|
||||
op = ++eptr; // once here, we require four values
|
||||
if(lex_long(op, &opts->margin_r, &eptr) || !*eptr){
|
||||
return -1;
|
||||
}
|
||||
op = ++eptr;
|
||||
if(lex_long(op, &opts->margin_b, &eptr) || !*eptr){
|
||||
return -1;
|
||||
}
|
||||
op = ++eptr;
|
||||
if(lex_long(op, &opts->margin_l, &eptr) || *eptr){ // must end in NUL
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static demoresult*
|
||||
ext_demos(struct notcurses* nc, const char* spec, bool ignore_failures){
|
||||
int ret = 0;
|
||||
@ -189,7 +237,7 @@ handle_opts(int argc, char** argv, notcurses_options* opts, bool* ignore_failure
|
||||
*json_output = NULL;
|
||||
int c;
|
||||
memset(opts, 0, sizeof(*opts));
|
||||
while((c = getopt(argc, argv, "VhickJ:l:r:d:f:p:")) != EOF){
|
||||
while((c = getopt(argc, argv, "VhickJ:l:r:d:f:p:m:")) != EOF){
|
||||
switch(c){
|
||||
case 'h':
|
||||
usage(*argv, EXIT_SUCCESS);
|
||||
@ -206,6 +254,11 @@ handle_opts(int argc, char** argv, notcurses_options* opts, bool* ignore_failure
|
||||
usage(*argv, EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
}case 'm':{
|
||||
if(lex_margins(optarg, opts)){
|
||||
usage(*argv, EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
}case 'V':
|
||||
printf("notcurses-demo version %s\n", notcurses_version());
|
||||
exit(EXIT_SUCCESS);
|
||||
|
@ -181,7 +181,8 @@ eagles(struct notcurses* nc){
|
||||
}else if(e[i].yoff + height >= truey){
|
||||
e[i].yoff = truey - height - 1;
|
||||
}
|
||||
e[i].xoff += (random() % (truex / 80)) + 1;
|
||||
int scale = truex >= 80 ? truex / 80 : 1;
|
||||
e[i].xoff += (random() % scale) + 1;
|
||||
ncplane_move_yx(e[i].n, e[i].yoff, e[i].xoff);
|
||||
++eaglesmoved;
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ message(struct ncplane* n, int maxy, int maxx, int num, int total,
|
||||
ncplane_printf_yx(n, 1, 4, " %03dx%03d (%d/%d) ", maxx, maxy, num + 1, total);
|
||||
ncplane_styles_off(n, NCSTYLE_ITALIC);
|
||||
ncplane_set_fg_rgb(n, 224, 128, 224);
|
||||
ncplane_putstr_yx(n, 3, 1, " 🔥 unicode 13, resize awareness, 24b directcolor…🔥 ");
|
||||
ncplane_putstr_yx(n, 3, 1, " 🔥 unicode 13, resize awareness, 24b truecolor…🔥 ");
|
||||
ncplane_set_fg_rgb(n, 255, 255, 255);
|
||||
return 0;
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ typedef struct ncdirect {
|
||||
char* initc; // set a palette entry's RGB value
|
||||
char* oc; // restore original colors
|
||||
char* clear; // clear the screen
|
||||
bool RGBflag; // terminfo-reported "RGB" flag for 24bpc directcolor
|
||||
bool RGBflag; // terminfo-reported "RGB" flag for 24bpc truecolor
|
||||
bool CCCflag; // terminfo-reported "CCC" flag for palette set capability
|
||||
FILE* ttyfp; // FILE* for controlling tty, from opts->ttyfp
|
||||
palette256 palette; // 256-indexed palette can be used instead of/with RGB
|
||||
@ -284,7 +284,7 @@ typedef struct notcurses {
|
||||
char* getm; // get mouse events
|
||||
char* initc; // set a palette entry's RGB value
|
||||
char* oc; // restore original colors
|
||||
bool RGBflag; // terminfo-reported "RGB" flag for 24bpc directcolor
|
||||
bool RGBflag; // terminfo-reported "RGB" flag for 24bpc truecolor
|
||||
bool CCCflag; // terminfo-reported "CCC" flag for palette set capability
|
||||
bool AMflag; // ti-reported "AM" flag for automatic movement to next line
|
||||
|
||||
@ -307,6 +307,9 @@ typedef struct notcurses {
|
||||
// be reset (semantics are relied upon by widgets for mouse click detection).
|
||||
uint64_t input_events;
|
||||
|
||||
// desired margins (best-effort only), copied in from notcurses_options
|
||||
int margin_t, margin_b, margin_r, margin_l;
|
||||
|
||||
palette256 palette; // 256-indexed palette can be used instead of/with RGB
|
||||
bool palette_damage[NCPALETTESIZE];
|
||||
struct esctrie* inputescapes; // trie of input escapes -> ncspecial_keys
|
||||
|
@ -283,8 +283,8 @@ ncplane_create(notcurses* nc, int rows, int cols, int yoff, int xoff){
|
||||
p->leny = rows;
|
||||
p->lenx = cols;
|
||||
p->x = p->y = 0;
|
||||
p->absx = xoff;
|
||||
p->absy = yoff;
|
||||
p->absx = xoff + nc->margin_l;
|
||||
p->absy = yoff + nc->margin_t;
|
||||
p->attrword = 0;
|
||||
p->channels = 0;
|
||||
egcpool_init(&p->pool);
|
||||
@ -301,7 +301,8 @@ ncplane_create(notcurses* nc, int rows, int cols, int yoff, int xoff){
|
||||
// the z-buffer. clear out all cells. this is for a wholly new context.
|
||||
static ncplane*
|
||||
create_initial_ncplane(notcurses* nc, int dimy, int dimx){
|
||||
nc->stdscr = ncplane_create(nc, dimy, dimx, 0, 0);
|
||||
nc->stdscr = ncplane_create(nc, dimy - (nc->margin_t + nc->margin_b),
|
||||
dimx - (nc->margin_l + nc->margin_r), 0, 0);
|
||||
return nc->stdscr;
|
||||
}
|
||||
|
||||
@ -497,6 +498,15 @@ int notcurses_resize(notcurses* n, int* rows, int* cols){
|
||||
if(update_term_dimensions(n->ttyfd, rows, cols)){
|
||||
return -1;
|
||||
}
|
||||
// FIXME can we emerge from the previous call with rows/cols <= 0?
|
||||
*rows -= n->margin_t + n->margin_b;
|
||||
if(*rows <= 0){
|
||||
*rows = 1;
|
||||
}
|
||||
*cols -= n->margin_l + n->margin_r;
|
||||
if(*cols <= 0){
|
||||
*cols = 1;
|
||||
}
|
||||
if(*rows == oldrows && *cols == oldcols){
|
||||
return 0; // no change
|
||||
}
|
||||
@ -551,7 +561,7 @@ query_rgb(void){
|
||||
if(!rgb){
|
||||
// RGB terminfo capability being a new thing (as of ncurses 6.1), it's not commonly found in
|
||||
// terminal entries today. COLORTERM, however, is a de-facto (if imperfect/kludgy) standard way
|
||||
// of indicating DirectColor support for a terminal. The variable takes one of two case-sensitive
|
||||
// of indicating TrueColor support for a terminal. The variable takes one of two case-sensitive
|
||||
// values:
|
||||
//
|
||||
// truecolor
|
||||
@ -567,8 +577,7 @@ query_rgb(void){
|
||||
}
|
||||
|
||||
static int
|
||||
interrogate_terminfo(notcurses* nc, const notcurses_options* opts,
|
||||
int* dimy, int* dimx){
|
||||
interrogate_terminfo(notcurses* nc, const notcurses_options* opts, int* dimy, int* dimx){
|
||||
update_term_dimensions(nc->ttyfd, dimy, dimx);
|
||||
char* shortname_term = termname();
|
||||
char* longname_term = longname();
|
||||
@ -826,6 +835,10 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
|
||||
if(!opts){
|
||||
opts = &defaultopts;
|
||||
}
|
||||
if(opts->margin_t < 0 || opts->margin_b < 0 || opts->margin_l < 0 || opts->margin_r < 0){
|
||||
fprintf(stderr, "Provided an illegal negative margin, refusing to start\n");
|
||||
return NULL;
|
||||
}
|
||||
const char* encoding = nl_langinfo(CODESET);
|
||||
if(encoding == NULL || (strcmp(encoding, "ANSI_X3.4-1968") && strcmp(encoding, "UTF-8"))){
|
||||
fprintf(stderr, "Encoding (\"%s\") was neither ANSI_X3.4-1968 nor UTF-8, refusing to start\n",
|
||||
@ -837,6 +850,10 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
|
||||
if(ret == NULL){
|
||||
return ret;
|
||||
}
|
||||
ret->margin_t = opts->margin_t;
|
||||
ret->margin_b = opts->margin_b;
|
||||
ret->margin_l = opts->margin_l;
|
||||
ret->margin_r = opts->margin_r;
|
||||
ret->stats.fbbytes = 0;
|
||||
ret->stashstats.fbbytes = 0;
|
||||
reset_stats(&ret->stats);
|
||||
@ -921,9 +938,9 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
|
||||
if(!opts->suppress_banner){
|
||||
char prefixbuf[BPREFIXSTRLEN + 1];
|
||||
term_fg_palindex(ret, ret->ttyfp, ret->colors <= 256 ? 50 % ret->colors : 0x20e080);
|
||||
fprintf(ret->ttyfp, "\n notcurses %s by nick black et al", notcurses_version());
|
||||
printf("\n notcurses %s by nick black et al", notcurses_version());
|
||||
term_fg_palindex(ret, ret->ttyfp, ret->colors <= 256 ? 12 % ret->colors : 0x2080e0);
|
||||
fprintf(ret->ttyfp, "\n %d rows, %d columns (%sB), %d colors (%s)\n"
|
||||
printf("\n %d rows, %d columns (%sB), %d colors (%s)\n"
|
||||
" compiled with gcc-%s\n"
|
||||
" terminfo from %s\n",
|
||||
ret->stdscr->leny, ret->stdscr->lenx,
|
||||
@ -931,25 +948,26 @@ notcurses* notcurses_init(const notcurses_options* opts, FILE* outfp){
|
||||
ret->colors, ret->RGBflag ? "direct" : "palette",
|
||||
__VERSION__, curses_version());
|
||||
#ifdef USE_FFMPEG
|
||||
fprintf(ret->ttyfp, " avformat %u.%u.%u\n avutil %u.%u.%u\n swscale %u.%u.%u\n",
|
||||
printf(" avformat %u.%u.%u\n avutil %u.%u.%u\n swscale %u.%u.%u\n",
|
||||
LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO,
|
||||
LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO,
|
||||
LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO);
|
||||
fflush(stdout);
|
||||
#else
|
||||
term_fg_palindex(ret, ret->ttyfp, ret->colors <= 88 ? 1 % ret->colors : 0xcb);
|
||||
fprintf(ret->ttyfp, "\n Warning! Notcurses was built without ffmpeg support\n");
|
||||
fprintf(stderr, "\n Warning! Notcurses was built without ffmpeg support\n");
|
||||
#endif
|
||||
term_fg_palindex(ret, ret->ttyfp, ret->colors <= 88 ? 1 % ret->colors : 0xcb);
|
||||
if(!ret->RGBflag){ // FIXME
|
||||
fprintf(ret->ttyfp, "\n Warning! Colors subject to https://github.com/dankamongmen/notcurses/issues/4");
|
||||
fprintf(ret->ttyfp, "\n Specify a (correct) DirectColor TERM, or COLORTERM=24bit.\n");
|
||||
fprintf(stderr, "\n Warning! Colors subject to https://github.com/dankamongmen/notcurses/issues/4");
|
||||
fprintf(stderr, "\n Specify a (correct) TrueColor TERM, or COLORTERM=24bit.\n");
|
||||
}else{
|
||||
if(!ret->CCCflag){
|
||||
fprintf(ret->ttyfp, "\n Warning! Advertised DirectColor but no 'ccc' flag\n");
|
||||
fprintf(stderr, "\n Warning! Advertised TrueColor but no 'ccc' flag\n");
|
||||
}
|
||||
}
|
||||
if(strcmp(encoding, "UTF-8")){
|
||||
fprintf(ret->ttyfp, "\n Warning! Encoding is not UTF-8.\n");
|
||||
if(strcmp(encoding, "UTF-8")){ // it definitely exists, but could be ASCII
|
||||
fprintf(stderr, "\n Warning! Encoding is not UTF-8.\n");
|
||||
}
|
||||
}
|
||||
// flush on the switch to alternate screen, lest initial output be swept away
|
||||
|
@ -212,8 +212,8 @@ paint(notcurses* nc, ncplane* p, struct crender* rvec, cell* fb){
|
||||
// don't use ncplane_dim_yx()/ncplane_yx() here, lest we deadlock
|
||||
dimy = p->leny;
|
||||
dimx = p->lenx;
|
||||
offy = p->absy;
|
||||
offx = p->absx;
|
||||
offy = p->absy - nc->stdscr->absy;
|
||||
offx = p->absx - nc->stdscr->absx;
|
||||
//fprintf(stderr, "PLANE %p %d %d %d %d %d %d\n", p, dimy, dimx, offy, offx, nc->stdscr->leny, nc->stdscr->lenx);
|
||||
// skip content above or to the left of the physical screen
|
||||
int starty, startx;
|
||||
@ -764,19 +764,23 @@ notcurses_rasterize(notcurses* nc, const struct crender* rvec){
|
||||
// we only need to emit a coordinate if it was damaged. the damagemap is a
|
||||
// bit per coordinate, rows by rows, column by column within a row, with the
|
||||
// MSB being the first coordinate.
|
||||
size_t damageidx = 0;
|
||||
// don't write a clearscreen. we only update things that have been changed.
|
||||
// we explicitly move the cursor at the beginning of each output line, so no
|
||||
// need to home it expliticly.
|
||||
update_palette(nc, out);
|
||||
for(y = 0 ; y < nc->stdscr->leny ; ++y){
|
||||
// FIXME need to track outer{x,y} (position on screen) and inner{x,y}
|
||||
// (position within lastframe/rvec, which is lfdimx-sized)
|
||||
for(y = nc->stdscr->absy ; y < nc->stdscr->leny + nc->stdscr->absy ; ++y){
|
||||
const int innery = y - nc->stdscr->absy;
|
||||
// how many characters have we elided? it's not worthwhile to invoke a
|
||||
// cursor movement with cup if we only elided one or two. set to INT_MAX
|
||||
// whenever we're on a new line. leave room to avoid overflow.
|
||||
int needmove = INT_MAX - nc->stdscr->lenx;
|
||||
for(x = 0 ; x < nc->stdscr->lenx ; ++x){
|
||||
for(x = nc->stdscr->absx ; x < nc->stdscr->lenx + nc->stdscr->absx ; ++x){
|
||||
const int innerx = x - nc->stdscr->absx;
|
||||
const size_t damageidx = innery * nc->lfdimx + innerx;
|
||||
unsigned r, g, b, br, bg, bb, palfg, palbg;
|
||||
const cell* srccell = &nc->lastframe[y * nc->lfdimx + x];
|
||||
const cell* srccell = &nc->lastframe[innery * nc->lfdimx + innerx];
|
||||
// cell c;
|
||||
// memcpy(c, srccell, sizeof(*c)); // unsafe copy of gcluster
|
||||
//fprintf(stderr, "COPYING: %d from %p\n", c->gcluster, &nc->pool);
|
||||
@ -907,9 +911,8 @@ fprintf(stderr, "RAST %u [%s] to %d/%d\n", srccell->gcluster, egcpool_extended_g
|
||||
}
|
||||
if(cell_double_wide_p(srccell)){
|
||||
++x;
|
||||
++damageidx;
|
||||
}
|
||||
++damageidx;
|
||||
//fprintf(stderr, "damageidx: %ld\n", damageidx);
|
||||
}
|
||||
}
|
||||
ret |= fflush(out);
|
||||
|
Loading…
x
Reference in New Issue
Block a user