Tons of work on ncreel (#627, #749, #694)
Improve reel demo: get input wired up once more, avoid the FPS demo at bottom, print pointer and line count in each tablet, use new ncreel API. Improve notcurses-ncreel explorer: kill memory leaks (#694), draw tablets better, use new ncreel API. Fix bug in ncreel core where cruft could be left on the screen, via a very gross brute force algorithm. I'll likely come back and make this a bit less ghastly in the future #749. Remove weird one-off input system from ncreel, residue from outcurses. Make some of the normalizing changes speced out in #627
* ncreel: give each tablet an index, and print it #749
* reel: eliminate FIXME + param to insert_tabler() #749
* ncreel: label tablets with their adress to correlate against debugging logs #749
* more terminal environment variable notes
* TERMS.md: add Sakura, st
* ncreel: move legend out of reel proper
* ncreel_options: dump min/max_supported_rows/cols #627
* ncreel: remove weird one-off input layer #627
* ncreel: add ncreel_offer_input()
* reel demo: call demo_getc()
* reel demo: rig up input to demo main
* ncreel: drop ncreel_del_focused(), properly bind tablets
* reel demo: don't free up necessary plane
* ncreel: don't pull absolute locations of tablets
* ncreel: place tablets correctly in boundrel
* reel demo: add back support for left/right
* reel demo: restore thread movement
* ncreel: remove a great deal of complexity
* reel demo: stay out of FPS graph's way
* ncreel: give each tablet an index, and print it #749
* reel: eliminate FIXME + param to insert_tabler() #749
* ncreel: label tablets with their adress to correlate against debugging logs #749
* ncreel: move legend out of reel proper
* ncreel_options: dump min/max_supported_rows/cols #627
* ncreel: remove weird one-off input layer #627
* ncreel: add ncreel_offer_input()
* reel demo: call demo_getc()
* reel demo: rig up input to demo main
* ncreel: drop ncreel_del_focused(), properly bind tablets
* reel demo: don't free up necessary plane
* ncreel: don't pull absolute locations of tablets
* ncreel: place tablets correctly in boundrel
* reel demo: add back support for left/right
* reel demo: restore thread movement
* ncreel: remove a great deal of complexity
* reel demo: stay out of FPS graph's way
* reel: tighten up reel following redraw
* reel: fix upper-left corner of topless perimeter
* ncreel: print linecount, return clipped value
* reel: draw focused tablet relative to reel
* reel: brute force decruftification, how embarrassing #749
CELL_ALPHA_OPAQUE et al were defined as 0..3, meaning
CELL_ALPHA_SHIFT had to be used to compare them to their
channel representations. Instead, define them in said
representation outright, eliminating the need to shift while
retaining arithmetic properties, and zero initialization for
CELL_ALPHA_OPAQUE. Eliminate CELL_ALPHA_SHIFT #738.
Add convenience function ncplane_home(). Add an ncblitter_e param
to ncplane_qrcode(), and split int maxversion into value-result
int* ymax and int* xmax. Write the actual sizes of the resulting
visual into these parameters. Update the qrcode demo. Add the
qrcode PoC. Update demos to ncplane_home(), where possible.
ncplane_qrcode() now takes an ncblitter_e and two value-result int*s
in the place of a single value int. The final size of the displayed qrcode
is written to *ymax and *xmax. If the code can't fit within the specified
dimensions, an error is returned. Standard rules for pluggable blitters
apply regarding fallback etc. #699
Whip the ol' llama's ass (fix ncvisual rotation)
* notcurses: flush cursor change requests #673
* rotator: verify ncplane_rgba and ncblit_rgba
* ncblit: rename, accept ncblitter_e #674
* rotator: render from rgba
* rotator: get to rotation
* rotator: add a pi/4 turn at the end
* normal: reuse incoming plane for rendering #672
* rotator poc: rotate a fullplane gradient #672
* normal demo: place visual correctly
* rotator: verify ncplane_rgba and ncblit_rgba
* ncblit: rename, accept ncblitter_e #674
* rotator: render from rgba
* rotator: add a pi/4 turn at the end
* normal: reuse incoming plane for rendering #672
* rotator poc: rotate a fullplane gradient #672
* normal demo: place visual correctly
* rotator poc: throw some red into gradient
* rotator poc: done #662
* oiio: ncvisual_resize() needs set ibuf pointer #662
* normal: only need erase at top of loop
* visual poc: shorter delay
* normal demo: center rendered visual
* comment ncvisual_resize() call
* ncvisual_rotate: call ncvisual_details_seed()
* ffmpeg ncvisual: fix rotation #662
This represents an essentially complete rewrite of ncvisual and associated code. It had two major goals:
Improve the ncvisual API based off lessons learned, pursuant to the upcoming API freeze. In particular, I wanted to:
decouple ncvisuals from ncplanes. It should be possible to render a ncvisual to multiple planes, with different scaling each time. It should be possible to create an ncvisual without a plane, etc.
normalize the various ways of constructing an ncvisual -- file, memory, plane, etc.
Support multiple blitters, from 7-bit ASCII to Sixel. This required writing the blitters in several cases, and they're not yet in their final implementations (but the API is fine)
I have not yet unified Plots and Visuals, and might not, given that the Plot code works fine. We could at this point implement Plots in terms of Visuals, though -- the blitter backend range has been unified. Sixel is not yet implemented, though it is listed.
There is a new POC tool, blitter. It renders its arguments using all possible blitter+scaling combinations. Another new POC, resize, displays its argument, then resizes it to the screen size and displays that, explicitly making use of ncvisual_resize() rather than a scaling parameter to ncvisual_render().
This also eliminates some memory leaks and bugs we were seeing in trunk, and brings in Sixel scaffolding.
The C++ wrapper will also need patching back up; I cut most of it down while wrestling with this crap, urk.
Closes#638, #562, and #622.
This is to make it possible, in the future, to create multiple instances
of `NotCurses` for multiple terminals. The first instance of
`NotCurses` becomes the default one, so that any instances of other
classes that aren't explicitly created with a pointer to another
`NotCurses` instance still work as expected.
Note that currently trying to call `notcurses_init` twice results in the
following error for me:
0x55555559bfc0 is already registered for signals
Couldn't drop signals: 0x55555559bfc0 != 0x5555555b6720
terminate called after throwing an instance of 'ncpp::init_error*'
Program received signal SIGABRT, Aborted.
The error is signalled by `setup_signals` and the pointer shown in the
message points to the first `struct notcurses` instance created.
Fixes: https://github.com/dankamongmen/notcurses/issues/616
SIGSEGV was caused by an invalid cast.
Short explanation: PEBKAC
Long explanation: `Selector.hh`, `Plot.hh` and `MultiSelector.hh` did
not include `Plane.hh`, they merely declared `class Plane;` because
inclusion of `Plane.hh` would cause circular dependencies to appear and
the compiler would be unhappy. On top of that, yours truly wrenched the
compiler's hands and caused it to believe that a pointer to `Plane` is
really a pointer to `ncplane*` which was quite a silly thing to do as
the compiler, not having included `Plane.hh` and thus not knowing full
definition of the type, wasn't able to look up the type cast operator in
`Plane`.
Don't abuse `reinterpret_cast`, kids!
Replace the singly-linked z-axis with a doubly-linked list,
and reimplement all z-axis moves as O(1) functions.
Eliminate ncplane_move_{above/below}_unsafe(), as there are no
longer unsafe moves.
Unify ffmpeg/oiio/null implementations, where possible. This effectively
required placing all three in the same file, which meant they're all now
C++. Update FFmpeg implemenation to be C++-usable. Implement
ncvisual_rotate_cw() and ncvisual_rotate_ccw() #515. Move most of tetris
over to Visual from Plane #558. Add bgra_to_rgba(), necessary for
creating ncvisual from BGRA memory. Implement ncvisual_from_rgba()
and ncvisual_from_bgra() #557. Add unit tests on ncvisual rotation.
Added:
* class FDPlane (`ncfdplane*`)
* class Subproc (`ncsubproc*`)
* NotCurses: get_inputready_fd (`notcurses_inputready_fd`)
* Plane: qrcode (`ncplane_qrcode`)
* class PlotBase: templated base class for Plot variations
* class PlotU: `uint64_t` instantiation of PlotBase (aliased to previous
`Plot` class for source compatibility), `ncuplot*`
* class PlotD: `double` instantiation of PlotBase, `ncdplot*`
* ncplane_at_* and ncplane_at_cursor_*
We had notcurses_at_yx() expanding into three distinct parts of
the cell structure, and ncplane_at_yx() / ncplane_at_cursor()
writing directly to a cell. It was annoying to remember which
was which. The latter two now have a signature matching
notcurses_at_yx(), while the old functionality has been moved
to ncplane_at_yx_cell() and ncplane_at_cursor_yx(). #476
Nick prefers error handling based on exceptions in all cases, while I
prefer to save exception handling for truly exceptional situations -
function parameter validation and class constructor. However, there's no
need to not support both approaches, to be chosen at the discretion of
the developer.
NCPP follows RAII and all classes throw exceptions from their
constructors in case they cannot initialize properly. Likewise,
functions taking pointers that are required validate them and throw
exceptions whenever the requirement isn't met.
This commit goes one step further in that it enables optional validation
of notcurses function return values and throwing an
exception (`ncpp::call_error`) should the function signal an error. This
is disabled by default but it can be enabled by defining the
`NCPP_EXCEPTIONS_PLEASE` macro (preferably on the command line or
before *each* inclusion of any NCPP headers).
Out of necessity, this breaks the ABI (plus I found a handful of minor
issues in the code), but I think it's worth having this support in
place.
* packaging: s/libtinfo/Terminfo/g
* rust: add stddim_yx()
* rust: check for valid init in unit tests
* rust: serialize up tests
* constify notcurses_term_dim_yx()
* rust: add dim wrappers
* remove notcurses_resize() from public API #367
* call notcurses_resize() from notcurses_refresh() #367
Resolves#410. notcurses_at_yx() accepted a cell*, but the
gcluster of this cell was always set to 0. The EGC is instead
a heap-allocated copy, returned as the primary return value.
This is due to the absence of an egcpool to bind against.
Existing callers can be converted thus:
* instead of passing cell 'c', pass &(c)->attrword, &(c)->channels
* either initialize 'c' with CELL_TRIVIAL_INITIALIZER, or set its
gcluster field to 0 following the call
I've updated all calls from tests/demos, updated the docs, and
updated the C++ and Python wrappers.