diff --git a/NEWS.md b/NEWS.md index 41deb7bcf..b9dadabeb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,20 @@ rearrangements of Notcurses. without an obvious replacement is the `renderfp` field of `notcurses_options`, for which I make no apology. If you've been avoiding deprecated functionality, ABI3 ought require small changes, if any. + * The handling of geometry and distance has been normalized across all + functions. Lengths are now `unsigned` as opposed to `int`. Where -1 was + being used to indicate "everything", 0 is now required. This affects + `ncplane_as_rgba()`, `ncplane_contents()`, and `ncvisual_from_plane()`, + which all used -1. A length of zero passed to line-drawing functions is + now an error. Several line-drawing functions now reliably return errors + as opposed to short successes. Dimensions of 0 to `ncplane_mergedown()` + now mean "everything". Almost all coordinates now accept -1 to indicate the + current cursor position in that dimension. `ncplane_highgradient()` has + been deprecated in favor of the new `ncplane_gradient2x1()`, which takes + origin coordinates. `ncplane_format()` and `ncplane_stain()` now take + origin coordinates. All now interpret their `unsigned` argument as + lengths rather than closing coordinates, observing the same semantics as + outlined above. * 2.4.9 (not yet released) * Added `ncnmetric()`, which uses `snprintf()` internally. `ncmetric()` @@ -28,20 +42,6 @@ rearrangements of Notcurses. `notcurses_mice_disable()` is now a `static inline` wrapper around the former, passing 0 as the event mask. This can be used to get mouse movement buttons and focus events, which were previously unavailable. - * The handling of geometry and distance has been normalized across all - functions. Lengths are now `unsigned` as opposed to `int`. Where -1 was - being used to indicate "everything", 0 is now required. This affects - `ncplane_as_rgba()`, `ncplane_contents()`, and `ncvisual_from_plane()`, - which all used -1. A length of zero passed to line-drawing functions is - now an error. Several line-drawing functions now reliably return errors - as opposed to short successes. Dimensions of 0 to `ncplane_mergedown()` - now mean "everything". Almost all coordinates now accept -1 to indicate the - current cursor position in that dimension. `ncplane_highgradient()` has - been deprecated in favor of the new `ncplane_gradient2x1()`, which takes - origin coordinates. `ncplane_format()` and `ncplane_stain()` now take - origin coordinates. All now interpret their `unsigned` argument as - lengths rather than closing coordinates, observing the same semantics as - outlined above. * `ncvisual_geom()` has been introduced, using the `ncvgeom` struct introduced for direct mode. This allows complete statement of geometry for an `ncvisual`. It replaces `ncvisual_blitter_geom()`, which has been @@ -231,7 +231,7 @@ rearrangements of Notcurses. * `notcurses_detected_terminal()` and `ncdirect_detected_terminal()` now both return a heap-allocated string, which will contain the terminal version if Notcurses was able to detect it. This result ought be free()d. - * Added `ncplane_moverel()`. + * Added `ncplane_move_rel()`. * Documented `ncplane_move_yx()` in `notcurses_plane.3`, and removed the false comment that "passing -1 as a coordinate will hold that axis constant" from `USAGE.md` and `notcurses.h`. This has never been true. diff --git a/USAGE.md b/USAGE.md index 681883a44..d1c6880f5 100644 --- a/USAGE.md +++ b/USAGE.md @@ -223,8 +223,10 @@ int notcurses_render(struct notcurses* nc); // must be freed by the caller. int ncpile_render_to_buffer(struct ncplane* p, char** buf, size_t* buflen); -// Write the last rendered frame, in its entirety, to 'fp'. If -// notcurses_render() has not yet been called, nothing will be written. +// Write the last rendered frame, in its entirety, to 'fp'. If a frame has +// not yet been rendered, nothing will be written. +int ncpile_render_to_file(struct ncplane* p, FILE* fp); + int ncpile_render_to_file(struct ncplane* p, FILE* fp); // Retrieve the contents of the specified cell as last rendered. The EGC is @@ -1045,7 +1047,7 @@ int ncplane_move_yx(struct ncplane* n, int y, int x); // Move this plane relative to its current location. Negative values move up // and left, respectively. Pass 0 to hold an axis constant. __attribute__ ((nonnull (1))) static inline int -ncplane_moverel(struct ncplane* n, int y, int x){ +ncplane_move_rel(struct ncplane* n, int y, int x){ int oy, ox; ncplane_yx(n, &oy, &ox); return ncplane_move_yx(n, oy + y, ox + x); @@ -1084,10 +1086,10 @@ ncplane_dim_x(const struct ncplane* n){ // ('celldimy', 'celldimx'), and the maximum displayable bitmap ('maxbmapy', // 'maxbmapx'). If bitmaps are not supported, 'maxbmapy' and 'maxbmapx' will // be 0. Any of the geometry arguments may be NULL. -void ncplane_pixelgeom(struct ncplane* n, - unsigned* restrict pxy, unsigned* restrict pxx, - unsigned* restrict celldimy, unsigned* restrict celldimx, - unsigned* restrict maxbmapy, unsigned* restrict maxbmapx); +void ncplane_pixel_geom(struct ncplane* n, + unsigned* restrict pxy, unsigned* restrict pxx, + unsigned* restrict celldimy, unsigned* restrict celldimx, + unsigned* restrict maxbmapy, unsigned* restrict maxbmapx); // provided a coordinate relative to the origin of 'src', map it to the same // absolute coordinate relative to the origin of 'dst'. either or both of 'y' @@ -1144,8 +1146,17 @@ int ncplane_base(struct ncplane* ncp, nccell* c); ```c // Splice ncplane 'n' out of the z-buffer, and reinsert it at the top or bottom. -void ncplane_move_top(struct ncplane* n); -void ncplane_move_bottom(struct ncplane* n); +__attribute__ ((nonnull (1))) +static inline void +ncplane_move_top(struct ncplane* n){ + ncplane_move_below(n, NULL); +} + +__attribute__ ((nonnull (1))) +static inline void +ncplane_move_bottom(struct ncplane* n){ + ncplane_move_above(n, NULL); +} // Splice ncplane 'n' and its bound planes out of the z-buffer, and reinsert // them at the top or bottom. Relative order will be maintained between the @@ -3602,12 +3613,12 @@ typedef struct ncstats { uint64_t writeouts; // successful ncpile_rasterize() runs uint64_t failed_renders; // aborted renders, should be 0 uint64_t failed_writeouts; // aborted writes - uint64_t render_bytes; // bytes emitted to ttyfp - int64_t render_max_bytes; // max bytes emitted for a frame - int64_t render_min_bytes; // min bytes emitted for a frame + uint64_t raster_bytes; // bytes emitted to ttyfp + int64_t raster_max_bytes; // max bytes emitted for a frame + int64_t raster_min_bytes; // min bytes emitted for a frame uint64_t render_ns; // nanoseconds spent rendering - int64_t render_max_ns; // max ns spent in render+raster for a frame - int64_t render_min_ns; // min ns spent in render+raster for a frame + int64_t render_max_ns; // max ns spent in render for a frame + int64_t render_min_ns; // min ns spent in render for a frame uint64_t raster_ns; // nanoseconds spent rasterizing int64_t raster_max_ns; // max ns spent in raster for a frame int64_t raster_min_ns; // min ns spent in raster for a frame @@ -3626,8 +3637,9 @@ typedef struct ncstats { uint64_t sprixelemissions; // sprixel draw count uint64_t sprixelelisions; // sprixel elision count uint64_t sprixelbytes; // sprixel bytes emitted - uint64_t appsync_updates; // application-synchronized updates + uint64_t appsync_updates; // how many application-synchronized updates? uint64_t input_errors; // errors processing control sequences/utf8 + uint64_t input_events; // characters returned to userspace uint64_t hpa_gratuitous; // unnecessary hpas issued // current state -- these can decrease diff --git a/doc/man/man3/notcurses_input.3.md b/doc/man/man3/notcurses_input.3.md index ec8111432..425a7b3cc 100644 --- a/doc/man/man3/notcurses_input.3.md +++ b/doc/man/man3/notcurses_input.3.md @@ -197,7 +197,7 @@ issues are resolved. You can determine whether the protocol is in use by examining the output of **notcurses-info(1)**. If the **kbd** property is indicated, you're using the Kitty protocol. -Mouse events in the top and left margins will never be delivered to the +Mouse events in the left margins will never be delivered to the application (as is intended), but mouse events in the bottom and right margins sometimes can be if the event occurs prior to a window resize. diff --git a/doc/man/man3/notcurses_metric.3.md b/doc/man/man3/notcurses_metric.3.md index c6b41aec8..c83c807a1 100644 --- a/doc/man/man3/notcurses_metric.3.md +++ b/doc/man/man3/notcurses_metric.3.md @@ -23,7 +23,7 @@ notcurses_metric - fixed-width numeric output with metric suffixes #define NCBPREFIXFMT(x) NCMETRICFWIDTH((x), NCBPREFIXCOLUMNS), (x) ``` -**const char* ncmetric(uintmax_t ***val***, uintmax_t ***decimal***, char* ***buf***, int ***omitdec***, unsigned ***mult***, int ***uprefix***);** +**const char* ncnmetric(uintmax_t ***val***, size_t s, uintmax_t ***decimal***, char* ***buf***, int ***omitdec***, unsigned ***mult***, int ***uprefix***);** **static inline const char* ncqprefix(uintmax_t ***val***, uintmax_t ***decimal***, char* ***buf***, int ***omitdec***);** @@ -44,15 +44,18 @@ Giga, Tera, Peta, Exa, Zetta, and Yotta) and the small suffixes mµnpfazy range 1e24 (one septillion) through 1e-24, sufficing for all possible values of a 64-bit **uintmax_t**. -**val** is the value being output, having been scaled by **decimal**. -**decimal** will typically be 1; to represent values less than 1, **decimal** -should be larger than **val**. The output will be written to **buf**, which +***val*** is the value being output, having been scaled by ***decimal***. +***decimal*** will typically be 1; to represent values less than 1, ***decimal*** +should be larger than ***val***. The output will be written to ***buf***, which must be at least: * **NCPREFIXSTRLEN** + 1 bytes for a 1000-based value * **NCIPREFIXSTRLEN** + 1 bytes for a 1024-based value * **NCBPREFIXSTRLEN** + 1 bytes for a 1024-based value with an 'i' suffix +***s*** is the maximum output size, including '\0', used in the same +fashion as **snprintf(3)** (which **ncnmetric** calls). + Three helper functions are provided to simplify these common cases: ``` @@ -78,7 +81,7 @@ ncbprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){ If **omitdec** is not zero, the decimal point and mantissa will be omitted if all digits to be displayed would be zero. The decimal point takes the current locale into account (see **setlocale(3)** and **localeconv(3)**). -**mult** is the relative multiple for each suffix. **uprefix**, if not zero, +***mult*** is the relative multiple for each suffix. ***uprefix***, if not zero, will be used as a suffix following any metric suffix. The maximum number of columns is not directly related to the maximum number of @@ -93,9 +96,9 @@ length are: In general, the maximum-width output will take the form **CCC.mmMu**, where C are digits of the characteristic (up to ceil(log10(**mult**)) digits), the decimal point follows, m are digits of the mantissa (up to 2), M is the metric -suffix, and u is the **uprefix**. The minimum-width output will take the form -**C**. This minimal form can occur if **omitdec** is non-zero and a -single-column value such as 5 is passed for **val**. +suffix, and u is the ***uprefix***. The minimum-width output will take the form +**C**. This minimal form can occur if ***omitdec*** is non-zero and a +single-column value such as 5 is passed for ***val***. Three more defines are provided to simplify formatted fixed-width output using the results of **ncmetric**. Each of these macros accepts a character buffer @@ -113,26 +116,26 @@ to ensure that the output is always **NCPREFIXCOLUMNS** wide. # RETURN VALUES -**NULL** if input parameters were invalid. Otherwise, a pointer to **buf**, +**NULL** if input parameters were invalid. Otherwise, a pointer to ***buf***, filled in with the formatted output. # EXAMPLES -**ncmetric(0, 1, buf, 0, 1000, '\0')**: "0.00". +**ncnmetric(0, INT_MAX, buf, 0, 1000, '\0')**: "0.00". -**ncmetric(0, 1, buf, 1, 1000, '\0')**: "0". +**ncnmetric(0, INT_MAX, buf, 1, 1000, '\0')**: "0". -**ncmetric(1023, 1, buf, 1, 1000, '\0')**: "1.02K". +**ncnmetric(1023, INT_MAX, buf, 1, 1000, '\0')**: "1.02K". -**ncmetric(1023, 1, buf, 1, 1024, 'i')**: "1023". +**ncnmetric(1023, INT_MAX, buf, 1, 1024, 'i')**: "1023". -**ncmetric(1024, 1, buf, 1, 1024, 'i')**: "1Ki". +**ncnmetric(1024, INT_MAX, buf, 1, 1024, 'i')**: "1Ki". -**ncmetric(4096, 1, buf, 0, 1024, 'i')**: "4.00Ki". +**ncnmetric(4096, INT_MAX, buf, 0, 1024, 'i')**: "4.00Ki". -**ncmetric(0x7fffffffffffffff, 1, buf, 0, 1000, '\0')**: "9.22E". +**ncnmetric(0x7fffffffffffffff, INT_MAX, buf, 0, 1000, '\0')**: "9.22E". -**ncmetric(0xffffffffffffffff, 1, buf, 0, 1000, '\0')**: "18.45E". +**ncnmetric(0xffffffffffffffff, INT_MAX, buf, 0, 1000, '\0')**: "18.45E". # BUGS @@ -143,4 +146,5 @@ This function is difficult to understand. **localeconv(3)**, **notcurses(3)**, **notcurses_output(3)**, -**setlocale(3)** +**setlocale(3)**, +**snprintf(3)** diff --git a/doc/man/man3/notcurses_plane.3.md b/doc/man/man3/notcurses_plane.3.md index 2c403092f..e03d48604 100644 --- a/doc/man/man3/notcurses_plane.3.md +++ b/doc/man/man3/notcurses_plane.3.md @@ -71,7 +71,7 @@ typedef struct ncplane_options { **int ncplane_move_yx(struct ncplane* ***n***, int ***y***, int ***x***);** -**int ncplane_moverel(struct ncplane* ***n***, int ***y***, int ***x***);** +**int ncplane_move_rel(struct ncplane* ***n***, int ***y***, int ***x***);** **void ncplane_yx(const struct ncplane* ***n***, int* restrict ***y***, int* restrict ***x***);** @@ -95,9 +95,9 @@ typedef struct ncplane_options { **int ncplane_base(struct ncplane* ***ncp***, nccell* ***c***);** -**void ncplane_move_top(struct ncplane* ***n***);** +**static inline void ncplane_move_top(struct ncplane* ***n***);** -**void ncplane_move_bottom(struct ncplane* ***n***);** +**static inline void ncplane_move_bottom(struct ncplane* ***n***);** **void ncplane_move_family_top(struct ncplane* ***n***);** @@ -225,7 +225,7 @@ typedef struct ncplane_options { **int ncplane_rotate_ccw(struct ncplane* ***n***);** -**void ncplane_pixelgeom(const struct notcurses* ***n***, unsigned* restrict ***pxy***, unsigned* restrict ***pxx***, unsigned* restrict ***celldimy***, unsigned* restrict ***celldimx***, unsigned* restrict ***maxbmapy***, unsigned* restrict ***maxbmapx***);** +**void ncplane_pixel_geom(const struct notcurses* ***n***, unsigned* restrict ***pxy***, unsigned* restrict ***pxx***, unsigned* restrict ***celldimy***, unsigned* restrict ***celldimx***, unsigned* restrict ***maxbmapy***, unsigned* restrict ***maxbmapx***);** **int ncplane_set_name(struct ncplane* ***n***, const char* ***name***);** @@ -433,7 +433,7 @@ they intersect the plane. This can be disabled with the ## Bitmaps -**ncplane_pixelgeom** retrieves pixel geometry details. **pxy** and **pxx** +**ncplane_pixel_geom** retrieves pixel geometry details. **pxy** and **pxx** return the size of the plane in pixels. **celldimy** and **celldimx** return the size of a cell in pixels (these ought be the same across planes). **maxbmapy** and **maxbmapx** describe the largest bitmap which can be @@ -505,9 +505,6 @@ All other functions cannot fail (and return **void**). # NOTES -**ncplane_new** is defined as a deprecated wrapper around **ncplane_create**. -It should not be used in new code. - # BUGS **ncplane_at_yx** doesn't yet account for bitmap-based graphics (see diff --git a/doc/man/man3/notcurses_render.3.md b/doc/man/man3/notcurses_render.3.md index a2f85d262..1e317e7be 100644 --- a/doc/man/man3/notcurses_render.3.md +++ b/doc/man/man3/notcurses_render.3.md @@ -63,9 +63,7 @@ requires determining an extended grapheme cluster, foreground color, background color, and style for each cell of the physical terminal. Writing the scene requires synthesizing a set of UTF-8-encoded characters and escape codes appropriate for the terminal (relying on terminfo(5)), and writing this -sequence to the output **FILE**. If the **renderfp** value was not NULL in the -original call to **notcurses_init**, the frame will be written to that **FILE** -as well. This write does not affect statistics. +sequence to the output **FILE**. Each cell can be rendered in isolation, though synthesis of the stream carries dependencies between cells. diff --git a/doc/man/man3/notcurses_stats.3.md b/doc/man/man3/notcurses_stats.3.md index e2b78bb02..3593e0653 100644 --- a/doc/man/man3/notcurses_stats.3.md +++ b/doc/man/man3/notcurses_stats.3.md @@ -17,9 +17,9 @@ typedef struct ncstats { uint64_t writeouts; // successful ncpile_rasterize() runs uint64_t failed_renders; // aborted renders, should be 0 uint64_t failed_writeouts; // aborted writes - uint64_t render_bytes; // bytes emitted to ttyfp - int64_t render_max_bytes; // max bytes emitted for a frame - int64_t render_min_bytes; // min bytes emitted for a frame + uint64_t raster_bytes; // bytes emitted to ttyfp + int64_t raster_max_bytes; // max bytes emitted for a frame + int64_t raster_min_bytes; // min bytes emitted for a frame uint64_t render_ns; // nanoseconds spent rendering int64_t render_max_ns; // max ns spent for a frame int64_t render_min_ns; // min ns spent for a frame @@ -76,7 +76,7 @@ renders are not expected to fail except under exceptional circumstances. should **notcurses_render(3)** fail while writing out a frame to the terminal, it counts as a failed render. -**render_max_bytes** and **render_min_bytes** track the maximum and minimum +**raster_max_bytes** and **raster_min_bytes** track the maximum and minimum number of bytes used rasterizing a frame. A given state of Notcurses does not correspond to a unique number of bytes; the size is also dependent on the existing terminal state. As a first approximation, the time a terminal takes to @@ -135,7 +135,7 @@ Linux framebuffer bitmaps are not written through the terminal device, but instead directly into the memory-mapped framebuffer (see **mmap(2)**). Bytes used for framebuffer graphics are thus independent of bytes written to the terminal. This explains why **sprixelbytes** may be surprising given the -value of **render_bytes**. +value of **raster_bytes**. # RETURN VALUES diff --git a/include/ncpp/NotCurses.hh b/include/ncpp/NotCurses.hh index 416ad2848..2a8d1308f 100644 --- a/include/ncpp/NotCurses.hh +++ b/include/ncpp/NotCurses.hh @@ -66,7 +66,7 @@ namespace ncpp static const char* ncmetric (uintmax_t val, uintmax_t decimal, char *buf, int omitdec, unsigned mult, int uprefix) noexcept { - return ::ncmetric (val, decimal, buf, omitdec, mult, uprefix); + return ::ncnmetric (val, INT_MAX, decimal, buf, omitdec, mult, uprefix); } static const char* ncqprefix (uintmax_t val, uintmax_t decimal, char *buf, int omitdec) noexcept diff --git a/include/notcurses/direct.h b/include/notcurses/direct.h index 063a88e20..35118b77c 100644 --- a/include/notcurses/direct.h +++ b/include/notcurses/direct.h @@ -71,43 +71,11 @@ API int ncdirect_set_fg_rgb(struct ncdirect* nc, unsigned rgb) API int ncdirect_set_bg_rgb(struct ncdirect* nc, unsigned rgb) __attribute__ ((nonnull (1))); -static inline int ncdirect_fg_rgb(struct ncdirect* nc, unsigned rgb) - __attribute__ ((deprecated)); - -static inline int -ncdirect_fg_rgb(struct ncdirect* nc, unsigned rgb){ - return ncdirect_set_fg_rgb(nc, rgb); -} - -static inline int ncdirect_bg_rgb(struct ncdirect* nc, unsigned rgb) - __attribute__ ((deprecated)); - -static inline int -ncdirect_bg_rgb(struct ncdirect* nc, unsigned rgb){ - return ncdirect_set_bg_rgb(nc, rgb); -} - API int ncdirect_set_fg_palindex(struct ncdirect* nc, int pidx) __attribute__ ((nonnull (1))); API int ncdirect_set_bg_palindex(struct ncdirect* nc, int pidx) __attribute__ ((nonnull (1))); -static inline int ncdirect_fg_palindex(struct ncdirect* nc, int pidx) - __attribute__ ((deprecated)); - -static inline int -ncdirect_fg_palindex(struct ncdirect* nc, int pidx){ - return ncdirect_set_fg_palindex(nc, pidx); -} - -static inline int ncdirect_bg_palindex(struct ncdirect* nc, int pidx) - __attribute__ ((deprecated)); - -static inline int -ncdirect_bg_palindex(struct ncdirect* nc, int pidx){ - return ncdirect_set_bg_palindex(nc, pidx); -} - // Returns the number of simultaneous colors claimed to be supported, or 1 if // there is no color support. Note that several terminal emulators advertise // more colors than they actually support, downsampling internally. @@ -154,45 +122,11 @@ ncdirect_set_fg_rgb8(struct ncdirect* nc, unsigned r, unsigned g, unsigned b){ return ncdirect_set_fg_rgb(nc, (r << 16u) + (g << 8u) + b); } -static inline int -ncdirect_fg_rgb8(struct ncdirect* nc, unsigned r, unsigned g, unsigned b) - __attribute__ ((deprecated)); - -static inline int -ncdirect_fg_rgb8(struct ncdirect* nc, unsigned r, unsigned g, unsigned b){ - return ncdirect_set_fg_rgb8(nc, r, g, b); -} - -static inline int -ncdirect_bg_rgb8(struct ncdirect* nc, unsigned r, unsigned g, unsigned b) - __attribute__ ((deprecated)); - -static inline int -ncdirect_bg_rgb8(struct ncdirect* nc, unsigned r, unsigned g, unsigned b){ - return ncdirect_set_bg_rgb8(nc, r, g, b); -} - API int ncdirect_set_fg_default(struct ncdirect* nc) __attribute__ ((nonnull (1))); API int ncdirect_set_bg_default(struct ncdirect* nc) __attribute__ ((nonnull (1))); -static inline int ncdirect_fg_default(struct ncdirect* nc) - __attribute__ ((deprecated)); - -static inline int -ncdirect_fg_default(struct ncdirect* nc){ - return ncdirect_set_fg_default(nc); -} - -static inline int ncdirect_bg_default(struct ncdirect* nc) - __attribute__ ((deprecated)); - -static inline int -ncdirect_bg_default(struct ncdirect* nc){ - return ncdirect_set_bg_default(nc); -} - // Get the current number of columns/rows. API unsigned ncdirect_dim_x(struct ncdirect* nc) __attribute__ ((nonnull (1))); API unsigned ncdirect_dim_y(struct ncdirect* nc) __attribute__ ((nonnull (1))); @@ -201,7 +135,7 @@ API unsigned ncdirect_dim_y(struct ncdirect* nc) __attribute__ ((nonnull (1))); // (NCSTYLE_UNDERLINE, NCSTYLE_BOLD, etc.) The attribute is only // indicated as supported if the terminal can support it together with color. // For more information, see the "ncv" capability in terminfo(5). -API unsigned ncdirect_supported_styles(const struct ncdirect* nc) +API uint16_t ncdirect_supported_styles(const struct ncdirect* nc) __attribute__ ((nonnull (1))); // ncplane_styles_*() analogues @@ -211,17 +145,9 @@ API int ncdirect_on_styles(struct ncdirect* n, unsigned stylebits) __attribute__ ((nonnull (1))); API int ncdirect_off_styles(struct ncdirect* n, unsigned stylebits) __attribute__ ((nonnull (1))); -API unsigned ncdirect_styles(const struct ncdirect* n) +API uint16_t ncdirect_styles(const struct ncdirect* n) __attribute__ ((nonnull (1))); -// Deprecated forms of above. -API int ncdirect_styles_set(struct ncdirect* n, unsigned stylebits) - __attribute__ ((deprecated)); -API int ncdirect_styles_on(struct ncdirect* n, unsigned stylebits) - __attribute__ ((deprecated)); -API int ncdirect_styles_off(struct ncdirect* n, unsigned stylebits) - __attribute__ ((deprecated)); - // Move the cursor in direct mode. -1 to retain current location on that axis. API int ncdirect_cursor_move_yx(struct ncdirect* n, int y, int x) __attribute__ ((nonnull (1))); diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index cb9ce6f78..6fccc7f54 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -95,11 +95,6 @@ typedef enum { NCSCALE_SCALE_HIRES, } ncscale_e; -// Returns the number of columns occupied by a multibyte (UTF-8) string, or -// -1 if a non-printable/illegal character is encountered. -// FIXME becomes a static inline in ABI3. -API int ncstrwidth(const char* mbs); - // Returns the number of columns occupied by a the valid prefix of a multibyte // (UTF-8) string. If an invalid character is encountered, -1 will be returned, // and the number of valid bytes and columns will be written into *|validbytes| @@ -107,6 +102,13 @@ API int ncstrwidth(const char* mbs); // *|validbytes| and *|validwidth| reflect the entire string. API int ncstrwidth_valid(const char* egcs, int* validbytes, int* validwidth); +// Returns the number of columns occupied by a multibyte (UTF-8) string, or +// -1 if a non-printable/illegal character is encountered. +static inline int +ncstrwidth(const char* mbs){ + return ncstrwidth_valid(mbs, NULL, NULL); +} + // Returns a heap-allocated copy of the user name under which we are running. API ALLOC char* notcurses_accountname(void); @@ -716,7 +718,7 @@ nccell_set_styles(nccell* c, unsigned stylebits){ } // Extract the style bits from the nccell. -static inline unsigned +static inline uint16_t nccell_styles(const nccell* c){ return c->stylemask; } @@ -923,7 +925,6 @@ typedef struct notcurses_options { // the environment variable TERM is used. Failure to open the terminal // definition will result in failure to initialize notcurses. const char* termtype; - FILE* renderfp; // deprecated, must be NULL, will be removed for ABI3 FIXME // Progressively higher log levels result in more logging to stderr. By // default, nothing is printed to stderr once fullscreen service begins. ncloglevel_e loglevel; @@ -981,6 +982,12 @@ API int notcurses_enter_alternate_screen(struct notcurses* nc) API int notcurses_leave_alternate_screen(struct notcurses* nc) __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); + // Return the topmost plane of the pile containing 'n'. API struct ncplane* ncpile_top(struct ncplane* n) __attribute__ ((nonnull (1))); @@ -1001,8 +1008,14 @@ API int ncpile_rasterize(struct ncplane* n) __attribute__ ((nonnull (1))); // Renders and rasterizes the standard pile in one shot. Blocking call. -API int notcurses_render(struct notcurses* nc) - __attribute__ ((nonnull (1))); +static inline int +notcurses_render(struct notcurses* nc){ + struct ncplane* stdn = notcurses_stdplane(nc); + if(ncpile_render(stdn)){ + return -1; + } + return ncpile_rasterize(stdn); +} // Perform the rendering and rasterization portion of ncpile_render() and // ncpile_rasterize(), but do not write the resulting buffer out to the @@ -1011,8 +1024,8 @@ API int notcurses_render(struct notcurses* nc) API int ncpile_render_to_buffer(struct ncplane* p, char** buf, size_t* buflen) __attribute__ ((nonnull (1, 2, 3))); -// Write the last rendered frame, in its entirety, to 'fp'. If -// notcurses_render() has not yet been called, nothing will be written. +// Write the last rendered frame, in its entirety, to 'fp'. If a frame has +// not yet been rendered, nothing will be written. API int ncpile_render_to_file(struct ncplane* p, FILE* fp) __attribute__ ((nonnull (1, 2))); @@ -1223,7 +1236,7 @@ ncplane_dim_x(const struct ncplane* n){ // 'maxbmapx'). If bitmaps are not supported, or if there is no artificial // limit on bitmap size, 'maxbmapy' and 'maxbmapx' will be 0. Any of the // geometry arguments may be NULL. -API void ncplane_pixelgeom(const struct ncplane* n, +API void ncplane_pixel_geom(const struct ncplane* n, unsigned* RESTRICT pxy, unsigned* RESTRICT pxx, unsigned* RESTRICT celldimy, unsigned* RESTRICT celldimx, unsigned* RESTRICT maxbmapy, unsigned* RESTRICT maxbmapx) @@ -1420,7 +1433,7 @@ typedef struct nccapabilities { // (NCSTYLE_UNDERLINE, NCSTYLE_BOLD, etc.) The attribute is only // indicated as supported if the terminal can support it together with color. // For more information, see the "ncv" capability in terminfo(5). -API unsigned notcurses_supported_styles(const struct notcurses* nc) +API uint16_t notcurses_supported_styles(const struct notcurses* nc) __attribute__ ((nonnull (1))) __attribute__ ((pure)); // Returns the number of simultaneous colors claimed to be supported, or 1 if @@ -1529,13 +1542,15 @@ typedef struct ncstats { uint64_t writeouts; // successful ncpile_rasterize() runs uint64_t failed_renders; // aborted renders, should be 0 uint64_t failed_writeouts; // aborted writes - // FIXME these next three all ought be "writeout" or "raster" - uint64_t render_bytes; // bytes emitted to ttyfp - int64_t render_max_bytes; // max bytes emitted for a frame - int64_t render_min_bytes; // min bytes emitted for a frame + uint64_t raster_bytes; // bytes emitted to ttyfp + int64_t raster_max_bytes; // max bytes emitted for a frame + int64_t raster_min_bytes; // min bytes emitted for a frame uint64_t render_ns; // nanoseconds spent rendering int64_t render_max_ns; // max ns spent in render for a frame int64_t render_min_ns; // min ns spent in render for a frame + uint64_t raster_ns; // nanoseconds spent rasterizing + int64_t raster_max_ns; // max ns spent in raster for a frame + int64_t raster_min_ns; // min ns spent in raster for a frame uint64_t writeout_ns; // nanoseconds spent writing frames to terminal int64_t writeout_max_ns; // max ns spent writing out a frame int64_t writeout_min_ns; // min ns spent writing out a frame @@ -1548,22 +1563,17 @@ typedef struct ncstats { uint64_t defaultelisions; // default color was emitted uint64_t defaultemissions; // default color was elided uint64_t refreshes; // refresh requests (non-optimized redraw) - uint64_t appsync_updates; // how many application-synchronized updates? - - // current state -- these can decrease - uint64_t fbbytes; // total bytes devoted to all active framebuffers - unsigned planes; // number of planes currently in existence - - // FIXME placed here for ABI compatibility; move up for ABI3 - uint64_t raster_ns; // nanoseconds spent rasterizing - int64_t raster_max_ns; // max ns spent in raster for a frame - int64_t raster_min_ns; // min ns spent in raster for a frame uint64_t sprixelemissions; // sprixel draw count uint64_t sprixelelisions; // sprixel elision count uint64_t sprixelbytes; // sprixel bytes emitted + uint64_t appsync_updates; // how many application-synchronized updates? uint64_t input_errors; // errors processing control sequences/utf8 uint64_t input_events; // characters returned to userspace uint64_t hpa_gratuitous; // unnecessary hpas issued + + // current state -- these can decrease + uint64_t fbbytes; // total bytes devoted to all active framebuffers + unsigned planes; // number of planes currently in existence } ncstats; // Allocate an ncstats object. Use this rather than allocating your own, since @@ -1648,7 +1658,7 @@ API int ncplane_move_yx(struct ncplane* n, int y, int x); // Move this plane relative to its current location. Negative values move up // and left, respectively. Pass 0 to hold an axis constant. __attribute__ ((nonnull (1))) static inline int -ncplane_moverel(struct ncplane* n, int y, int x){ +ncplane_move_rel(struct ncplane* n, int y, int x){ int oy, ox; ncplane_yx(n, &oy, &ox); return ncplane_move_yx(n, oy + y, ox + x); @@ -1694,13 +1704,18 @@ API int ncplane_move_below(struct ncplane* RESTRICT n, struct ncplane* RESTRICT below) __attribute__ ((nonnull (1))); -// Splice ncplane 'n' out of the z-buffer, and reinsert it at the top or -// bottom. FIXME these both become static inline wrappers around -// ncplane_move_below() and ncplane_move_above() in ABI3. -API void ncplane_move_top(struct ncplane* n) - __attribute__ ((nonnull (1))); -API void ncplane_move_bottom(struct ncplane* n) - __attribute__ ((nonnull (1))); +// Splice ncplane 'n' out of the z-buffer; reinsert it at the top or bottom. +__attribute__ ((nonnull (1))) +static inline void +ncplane_move_top(struct ncplane* n){ + ncplane_move_below(n, NULL); +} + +__attribute__ ((nonnull (1))) +static inline void +ncplane_move_bottom(struct ncplane* n){ + ncplane_move_above(n, NULL); +} // Splice ncplane 'n' and its bound planes out of the z-buffer, and reinsert // them above or below 'targ'. Relative order will be maintained between the @@ -1980,19 +1995,68 @@ API int ncplane_putwegc_stained(struct ncplane* n, const wchar_t* gclust, int* s // (though not beyond the end of the plane); this number is returned on success. // On error, a non-positive number is returned, indicating the number of columns // which were written before the error. -API int ncplane_putstr_yx(struct ncplane* n, int y, int x, const char* gclusters); +static inline int +ncplane_putstr_yx(struct ncplane* n, int y, int x, const char* gclusters){ + int ret = 0; + while(*gclusters){ + int wcs; + int cols = ncplane_putegc_yx(n, y, x, gclusters, &wcs); +//fprintf(stderr, "wrote %.*s %d cols %d bytes now at %d/%d\n", wcs, gclusters, cols, wcs, n->y, n->x); + if(cols < 0){ + return -ret; + } + if(wcs == 0){ + break; + } + // after the first iteration, just let the cursor code control where we + // print, so that scrolling is taken into account + y = -1; + x = -1; + gclusters += wcs; + ret += cols; + } + return ret; +} static inline int ncplane_putstr(struct ncplane* n, const char* gclustarr){ return ncplane_putstr_yx(n, -1, -1, gclustarr); } -API int ncplane_putstr_aligned(struct ncplane* n, int y, ncalign_e align, - const char* s); +static inline int +ncplane_putstr_aligned(struct ncplane* n, int y, ncalign_e align, const char* s){ + int validbytes, validwidth; + // we'll want to do the partial write if there's an error somewhere within + ncstrwidth_valid(s, &validbytes, &validwidth); + int xpos = ncplane_halign(n, align, validwidth); + if(xpos < 0){ + return -1; + } + return ncplane_putstr_yx(n, y, xpos, s); +} // Replace a string's worth of glyphs at the current cursor location, but // retain the styling. The current styling of the plane will not be changed. -API int ncplane_putstr_stained(struct ncplane* n, const char* s); +static inline int +ncplane_putstr_stained(struct ncplane* n, const char* gclusters){ + int ret = 0; + while(*gclusters){ + int wcs; + int cols = ncplane_putegc_stained(n, gclusters, &wcs); + if(cols < 0){ + return -ret; + } + if(wcs == 0){ + break; + } + gclusters += wcs; + ret += cols; + } + return ret; +} + +API int ncplane_putnstr_aligned(struct ncplane* n, int y, ncalign_e align, size_t s, const char* str) + __attribute__ ((nonnull (1, 5))); // Write a series of EGCs to the current location, using the current style. // They will be interpreted as a series of columns (according to the definition @@ -2000,16 +2064,35 @@ API int ncplane_putstr_stained(struct ncplane* n, const char* s); // (though not beyond the end of the plane); this number is returned on success. // On error, a non-positive number is returned, indicating the number of columns // which were written before the error. No more than 's' bytes will be written. -API int ncplane_putnstr_yx(struct ncplane* n, int y, int x, size_t s, const char* gclusters); +static inline int +ncplane_putnstr_yx(struct ncplane* n, int y, int x, size_t s, const char* gclusters){ + int ret = 0; + int offset = 0; +//fprintf(stderr, "PUT %zu at %d/%d [%.*s]\n", s, y, x, (int)s, gclusters); + while((size_t)offset < s && gclusters[offset]){ + int wcs; + int cols = ncplane_putegc_yx(n, y, x, gclusters + offset, &wcs); + if(cols < 0){ + return -ret; + } + if(wcs == 0){ + break; + } + // after the first iteration, just let the cursor code control where we + // print, so that scrolling is taken into account + y = -1; + x = -1; + offset += wcs; + ret += cols; + } + return ret; +} static inline int ncplane_putnstr(struct ncplane* n, size_t s, const char* gclustarr){ return ncplane_putnstr_yx(n, -1, -1, s, gclustarr); } -API int ncplane_putnstr_aligned(struct ncplane* n, int y, ncalign_e align, - size_t s, const char* gclustarr); - // ncplane_putstr(), but following a conversion from wchar_t to UTF-8 multibyte. // FIXME do this as a loop over ncplane_putegc_yx and save the big allocation+copy static inline int @@ -2687,16 +2770,30 @@ nccells_load_box(struct ncplane* n, uint32_t styles, uint64_t channels, return -1; } -API int nccells_rounded_box(struct ncplane* n, uint16_t styles, uint64_t channels, - nccell* ul, nccell* ur, nccell* ll, - nccell* lr, nccell* hl, nccell* vl); - static inline int nccells_ascii_box(struct ncplane* n, uint16_t attr, uint64_t channels, nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){ return nccells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, NCBOXASCII); } +static inline int +nccells_double_box(struct ncplane* n, uint16_t attr, uint64_t channels, + nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){ + if(notcurses_canutf8(ncplane_notcurses(n))){ + return nccells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, NCBOXDOUBLE); + } + return nccells_ascii_box(n, attr, channels, ul, ur, ll, lr, hl, vl); +} + +static inline int +nccells_rounded_box(struct ncplane* n, uint16_t attr, uint64_t channels, + nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){ + if(notcurses_canutf8(ncplane_notcurses(n))){ + return nccells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, NCBOXROUND); + } + return nccells_ascii_box(n, attr, channels, ul, ur, ll, lr, hl, vl); +} + static inline int nccells_light_box(struct ncplane* n, uint16_t attr, uint64_t channels, nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){ @@ -2764,10 +2861,6 @@ ncplane_rounded_box_sized(struct ncplane* n, uint16_t styles, uint64_t channels, x + xlen - 1, ctlword); } -API int nccells_double_box(struct ncplane* n, uint16_t styles, uint64_t channels, - nccell* ul, nccell* ur, nccell* ll, - nccell* lr, nccell* hl, nccell* vl); - static inline int ncplane_double_box(struct ncplane* n, uint16_t styles, uint64_t channels, unsigned ylen, unsigned xlen, unsigned ctlword){ @@ -3000,21 +3093,6 @@ API int ncvisual_set_yx(const struct ncvisual* n, unsigned y, unsigned x, uint32_t pixel) __attribute__ ((nonnull (1))); -// Render the decoded frame according to the provided options (which may be -// NULL). The plane used for rendering depends on vopts->n and vopts->flags. If -// NCVISUAL_OPTION_CHILDPLANE is set, vopts->n must not be NULL, and the plane -// will always be created as a child of vopts->n. If this flag is not set, and -// vopts->n is NULL, a new plane is created as a child of the standard plane. -// If the flag is not set and vopts->n is not NULL, we render to vopts->n. A -// subregion of the visual can be rendered using 'begx', 'begy', 'lenx', and -// 'leny'. Negative values for 'begy' or 'begx' are an error. It is an error to -// specify any region beyond the boundaries of the frame. Returns the (possibly -// newly-created) plane to which we drew. Pixels may not be blitted to the -// standard plane. -API struct ncplane* ncvisual_render(struct notcurses* nc, struct ncvisual* ncv, - const struct ncvisual_options* vopts) - __attribute__ ((deprecated)) __attribute__ ((nonnull (2))); - // Render the decoded frame according to the provided options (which may be // NULL). The plane used for rendering depends on vopts->n and vopts->flags. // If NCVISUAL_OPTION_CHILDPLANE is set, vopts->n must not be NULL, and the @@ -3343,11 +3421,14 @@ API void* nctablet_userptr(struct nctablet* t); API struct ncplane* nctablet_plane(struct nctablet* t); // Takes an arbitrarily large number, and prints it into a fixed-size buffer by -// adding the necessary SI suffix. Usually, pass a |[IB]PREFIXSTRLEN+1|-sized -// buffer to generate up to |[IB]PREFIXCOLUMNS| columns' worth of EGCs. The +// adding the necessary SI suffix. Usually, pass a |NC[IB]?PREFIXSTRLEN+1|-sized +// buffer to generate up to |NC[IB]?PREFIXCOLUMNS| columns' worth of EGCs. The // characteristic can occupy up through |mult-1| characters (3 for 1000, 4 for // 1024). The mantissa can occupy either zero or two characters. - +// +// snprintf(3) is used internally, with 's' as its size bound. If the output +// requires more size than is available, NULL will be returned. +// // Floating-point is never used, because an IEEE758 double can only losslessly // represent integers through 2^53-1. // @@ -3355,6 +3436,7 @@ API struct ncplane* nctablet_plane(struct nctablet* t); // an 89-bit uintmax_t. Beyond Z(etta) and Y(otta) lie lands unspecified by SI. // 2^-63 is 0.000000000000000000108, 1.08a(tto). // val: value to print +// s: maximum output size; see snprintf(3) // decimal: scaling. '1' if none has taken place. // buf: buffer in which string will be generated // omitdec: inhibit printing of all-0 decimal portions @@ -3363,11 +3445,6 @@ API struct ncplane* nctablet_plane(struct nctablet* t); // only printed if suffix is actually printed (input >= mult). // // You are encouraged to consult notcurses_metric(3). -API const char* ncmetric(uintmax_t val, uintmax_t decimal, char* buf, - int omitdec, uintmax_t mult, int uprefix) - __attribute__ ((nonnull (3))); - -// uses snprintf() internally with the argument 's' as its bound API const char* ncnmetric(uintmax_t val, size_t s, uintmax_t decimal, char* buf, int omitdec, uintmax_t mult, int uprefix) @@ -3376,7 +3453,7 @@ API const char* ncnmetric(uintmax_t val, size_t s, uintmax_t decimal, // The number of columns is one fewer, as the STRLEN expressions must leave // an extra byte open in case 'µ' (U+00B5, 0xC2 0xB5) shows up. NCPREFIXCOLUMNS // is the maximum number of columns used by a mult == 1000 (standard) -// ncmetric() call. NCIPREFIXCOLUMNS is the maximum number of columns used by a +// ncnmetric() call. NCIPREFIXCOLUMNS is the maximum number of columns used by a // mult == 1024 (digital information) ncmetric(). NCBPREFIXSTRLEN is the maximum // number of columns used by a mult == 1024 call making use of the 'i' suffix. // This is the true number of columns; to set up a printf()-style maximum @@ -3397,19 +3474,19 @@ API const char* ncnmetric(uintmax_t val, size_t s, uintmax_t decimal, // Mega, kilo, gigafoo. Use PREFIXSTRLEN + 1 and PREFIXCOLUMNS. static inline const char* ncqprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){ - return ncmetric(val, decimal, buf, omitdec, 1000, '\0'); + return ncnmetric(val, NCPREFIXSTRLEN + 1, decimal, buf, omitdec, 1000, '\0'); } // Mibi, kebi, gibibytes sans 'i' suffix. Use IPREFIXSTRLEN + 1. static inline const char* nciprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){ - return ncmetric(val, decimal, buf, omitdec, 1024, '\0'); + return ncnmetric(val, NCIPREFIXSTRLEN + 1, decimal, buf, omitdec, 1024, '\0'); } // Mibi, kebi, gibibytes. Use BPREFIXSTRLEN + 1 and BPREFIXCOLUMNS. static inline const char* ncbprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){ - return ncmetric(val, decimal, buf, omitdec, 1024, 'i'); + return ncnmetric(val, NCBPREFIXSTRLEN + 1, decimal, buf, omitdec, 1024, 'i'); } // Enable or disable the terminal's cursor, if supported, placing it at @@ -4204,122 +4281,6 @@ API void ncreader_destroy(struct ncreader* n, char** contents); API void notcurses_debug(const struct notcurses* nc, FILE* debugfp) __attribute__ ((nonnull (1, 2))); -// DEPRECATED MATERIAL, GOING AWAY IN ABI3 - -__attribute__ ((deprecated)) API int cell_duplicate(struct ncplane* n, nccell* targ, const nccell* c); - -__attribute__ ((deprecated)) API void cell_release(struct ncplane* n, nccell* c); - -// This function will be removed in ABI3 in favor of ncplane_create(). -// It persists in ABI2 only for backwards compatibility. -API ALLOC struct ncplane* ncplane_new(struct ncplane* n, int rows, int cols, int y, int x, void* opaque, const char* name) - __attribute__ ((deprecated)); - -API void ncplane_styles_set(struct ncplane* n, unsigned stylebits) - __attribute__ ((deprecated)); -API void ncplane_styles_on(struct ncplane* n, unsigned stylebits) - __attribute__ ((deprecated)); -API void ncplane_styles_off(struct ncplane* n, unsigned stylebits) - __attribute__ ((deprecated)); - -__attribute__ ((deprecated)) API int -cells_rounded_box(struct ncplane* n, uint16_t styles, uint64_t channels, - nccell* ul, nccell* ur, nccell* ll, - nccell* lr, nccell* hl, nccell* vl); - -__attribute__ ((deprecated)) API int -cells_double_box(struct ncplane* n, uint16_t styles, uint64_t channels, - nccell* ul, nccell* ur, nccell* ll, - nccell* lr, nccell* hl, nccell* vl); - -// Deprecated form of nctablet_plane(). -API struct ncplane* nctablet_ncplane(struct nctablet* t) - __attribute__ ((deprecated)); - -API ALLOC ncpalette* palette256_new(struct notcurses* nc) - __attribute__ ((deprecated)); - -API int palette256_use(struct notcurses* nc, const ncpalette* p) - __attribute__ ((deprecated)); - -API void palette256_free(ncpalette* p) __attribute__ ((deprecated)); - -// Inflate each pixel in the image to 'scale'x'scale' pixels. It is an error -// if 'scale' is less than 1. The original color is retained. -// Deprecated; use ncvisual_resize_noninterpolative(), which this now wraps. -API __attribute__ ((deprecated)) int ncvisual_inflate(struct ncvisual* n, int scale) - __attribute__ ((nonnull (1))); - -API int notcurses_render_to_buffer(struct notcurses* nc, char** buf, size_t* buflen) - __attribute__ ((deprecated)); - -API int notcurses_render_to_file(struct notcurses* nc, FILE* fp) - __attribute__ ((deprecated)); - -API void notcurses_debug_caps(const struct notcurses* nc, FILE* debugfp) - __attribute__ ((deprecated)) __attribute__ ((nonnull (1, 2))); - -__attribute__ ((deprecated)) API int nccell_width(const struct ncplane* n, const nccell* c); - -API ALLOC char* ncvisual_subtitle(const struct ncvisual* ncv) - __attribute__ ((nonnull (1))) __attribute__ ((deprecated)); - -API uint32_t notcurses_getc(struct notcurses* nc, const struct timespec* ts, - const void* unused, ncinput* ni) - __attribute__ ((nonnull (1))) __attribute__ ((deprecated)); - -API uint32_t ncdirect_getc(struct ncdirect* nc, const struct timespec *ts, - const void* unused, ncinput* ni) - __attribute__ ((nonnull (1))) __attribute__ ((deprecated)); - -// Get the size and ratio of ncvisual pixels to output cells along the y -// and x axes. The input size (in pixels) will be written to 'y' and 'x'. -// The scaling will be written to 'scaley' and 'scalex'. With these: -// rows = (y / scaley) + !!(y % scaley) or (y + scaley - 1) / scaley -// cols = (x / scalex) + !!(x % scalex) or (x + scalex - 1) / scalex -// Returns non-zero for an invalid 'vopts'. The blitter that will be used -// is returned in '*blitter'. -API int ncvisual_blitter_geom(const struct notcurses* nc, const struct ncvisual* n, - const struct ncvisual_options* vopts, int* y, int* x, - int* scaley, int* scalex, ncblitter_e* blitter) - __attribute__ ((nonnull (1))) __attribute__ ((deprecated)); - -API int notcurses_mouse_enable(struct notcurses* n) - __attribute__ ((nonnull (1))) __attribute__ ((deprecated)); -API int notcurses_mouse_disable(struct notcurses* n) - __attribute__ ((nonnull (1))) __attribute__ ((deprecated)); - -API int ncplane_highgradient_sized(struct ncplane* n, uint32_t ul, uint32_t ur, - uint32_t ll, uint32_t lr, int ylen, int xlen) - __attribute__ ((deprecated)); - -__attribute__ ((deprecated)) static inline const char* -qprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){ - return ncmetric(val, decimal, buf, omitdec, 1000, '\0'); -} - -// Mibi, kebi, gibibytes sans 'i' suffix. Use IPREFIXSTRLEN + 1. -__attribute__ ((deprecated)) static inline const char* -iprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){ - return ncmetric(val, decimal, buf, omitdec, 1024, '\0'); -} - -// Mibi, kebi, gibibytes. Use BPREFIXSTRLEN + 1 and BPREFIXCOLUMNS. -__attribute__ ((deprecated)) static inline const char* -bprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){ - return ncmetric(val, decimal, buf, omitdec, 1024, 'i'); -} - -#define PREFIXCOLUMNS 7 -#define IPREFIXCOLUMNS 8 -#define BPREFIXCOLUMNS 9 -#define PREFIXSTRLEN (PREFIXCOLUMNS + 1) // Does not include a '\0' (xxx.xxU) -#define IPREFIXSTRLEN (IPREFIXCOLUMNS + 1) // Does not include a '\0' (xxxx.xxU) -#define BPREFIXSTRLEN (BPREFIXCOLUMNS + 1) // Does not include a '\0' (xxxx.xxUi), i == prefix -#define PREFIXFMT(x) NCMETRICFWIDTH((x), PREFIXCOLUMNS), (x) -#define IPREFIXFMT(x) NCMETRIXFWIDTH((x), IPREFIXCOLUMNS), (x) -#define BPREFIXFMT(x) NCMETRICFWIDTH((x), BPREFIXCOLUMNS), (x) - #undef API #undef ALLOC diff --git a/python/notcurses/notcurses.py b/python/notcurses/notcurses.py index f5f2c9727..41b84a82a 100644 --- a/python/notcurses/notcurses.py +++ b/python/notcurses/notcurses.py @@ -524,7 +524,7 @@ class NcPlane: """Return Y dimension of this NcPlane.""" raise NotImplementedError('Stub') - def pixelgeom(self) -> Tuple[int, int, int, int, int, int]: + def pixel_geom(self) -> Tuple[int, int, int, int, int, int]: """Retrieve pixel geometry for the display region, each cell and the maximum displayable bitmap.""" raise NotImplementedError('Stub') diff --git a/python/notcurses/plane.c b/python/notcurses/plane.c index f77f0b45a..17b400010 100644 --- a/python/notcurses/plane.c +++ b/python/notcurses/plane.c @@ -110,10 +110,10 @@ NcPlane_dim_y(NcPlaneObject *self, PyObject *Py_UNUSED(args)) } static PyObject * -NcPlane_pixelgeom(NcPlaneObject *self, PyObject *Py_UNUSED(args)) +NcPlane_pixel_geom(NcPlaneObject *self, PyObject *Py_UNUSED(args)) { unsigned pxy = 0, pxx = 0, celldimy = 0, celldimx = 0, maxbmapy = 0, maxbmapx = 0; - ncplane_pixelgeom(self->ncplane_ptr, &pxy, &pxx, &celldimy, &celldimx, &maxbmapy, &maxbmapx); + ncplane_pixel_geom(self->ncplane_ptr, &pxy, &pxx, &celldimy, &celldimx, &maxbmapy, &maxbmapx); return Py_BuildValue("II II II", pxy, pxx, celldimy, celldimx, maxbmapy, maxbmapx); } @@ -1666,7 +1666,7 @@ static PyMethodDef NcPlane_methods[] = { {"dim_yx", (PyCFunction)NcPlane_dim_yx, METH_NOARGS, PyDoc_STR("Return the dimensions of this ncplane.")}, {"dim_x", (PyCFunction)NcPlane_dim_x, METH_NOARGS, PyDoc_STR("Return X dimension of this ncplane.")}, {"dim_y", (PyCFunction)NcPlane_dim_y, METH_NOARGS, PyDoc_STR("Return Y dimension of this ncplane.")}, - {"pixelgeom", (PyCFunction)NcPlane_pixelgeom, METH_NOARGS, PyDoc_STR("Retrieve pixel geometry for the display region ('pxy', 'pxx'), each cell ('celldimy', 'celldimx'), and the maximum displayable bitmap ('maxbmapy', 'maxbmapx'). Note that this will call notcurses_check_pixel_support(), possibly leading to an interrogation of the terminal. If bitmaps are not supported, 'maxbmapy' and 'maxbmapx' will be 0. Any of the geometry arguments may be NULL.")}, + {"pixel_geom", (PyCFunction)NcPlane_pixel_geom, METH_NOARGS, PyDoc_STR("Retrieve pixel geometry for the display region ('pxy', 'pxx'), each cell ('celldimy', 'celldimx'), and the maximum displayable bitmap ('maxbmapy', 'maxbmapx'). Note that this will call notcurses_check_pixel_support(), possibly leading to an interrogation of the terminal. If bitmaps are not supported, 'maxbmapy' and 'maxbmapx' will be 0. Any of the geometry arguments may be NULL.")}, {"set_resizecb", (PyCFunction)NcPlane_set_resizecb, METH_VARARGS, PyDoc_STR("Replace the ncplane's existing resizecb with 'resizecb' (which may be NULL). The standard plane's resizecb may not be changed.")}, {"reparent", (PyCFunction)NcPlane_reparent, METH_VARARGS, PyDoc_STR("Plane 'n' will be unbound from its parent plane, and will be made a bound child of 'newparent'.")}, diff --git a/src/compat/compat.h b/src/compat/compat.h index 81784f580..0b194dae2 100644 --- a/src/compat/compat.h +++ b/src/compat/compat.h @@ -44,8 +44,6 @@ extern "C" { typedef struct siginfo_t { int aieeee; } siginfo_t; -// not declared in MSYS2 header files, but implemented...? -int faccessat(int dirfd, const char *pathname, int mode, int flags); #define sigset_t int #define nl_langinfo(x) "UTF-8" #define ppoll(w, x, y, z) WSAPoll((w), (x), (y)) diff --git a/src/demo/boxdemo.c b/src/demo/boxdemo.c index 687d9cad7..b043eabe0 100644 --- a/src/demo/boxdemo.c +++ b/src/demo/boxdemo.c @@ -130,7 +130,7 @@ get_ships(struct notcurses* nc, struct ship* ships, unsigned shipcount){ return -1; } unsigned cdimy, cdimx; - ncplane_pixelgeom(notcurses_stdplane(nc), NULL, NULL, &cdimy, &cdimx, NULL, NULL); + ncplane_pixel_geom(notcurses_stdplane(nc), NULL, NULL, &cdimy, &cdimx, NULL, NULL); if(ncvisual_resize(wmv, cdimy * SHIPHEIGHT, cdimx * SHIPWIDTH)){ ncvisual_destroy(wmv); return -1; diff --git a/src/demo/demo.c b/src/demo/demo.c index 86e1a4cf7..2449bf5bf 100644 --- a/src/demo/demo.c +++ b/src/demo/demo.c @@ -377,7 +377,7 @@ summary_json(FILE* f, const char* spec, int rows, int cols){ continue; } ret |= (fprintf(f, "\"%s\":{\"bytes\":\"%"PRIu64"\",\"frames\":\"%"PRIu64"\",\"ns\":\"%"PRIu64"\"}%s", - demos[results[i].selector - 'a'].name, results[i].stats.render_bytes, + demos[results[i].selector - 'a'].name, results[i].stats.raster_bytes, results[i].stats.renders, results[i].timens, i < strlen(spec) - 1 ? "," : "") < 0); } ret |= (fprintf(f, "}}}\n") < 0); @@ -411,7 +411,7 @@ summary_table(struct notcurses* nc, const char* spec, bool canimage, bool canvid for(size_t i = 0 ; i < strlen(spec) ; ++i){ nsdelta += results[i].timens; ncqprefix(results[i].timens, NANOSECS_IN_SEC, timebuf, 0); - ncbprefix(results[i].stats.render_bytes, 1, totalbuf, 0); + ncbprefix(results[i].stats.raster_bytes, 1, totalbuf, 0); uint64_t divisor = results[i].stats.render_ns + results[i].stats.writeout_ns + results[i].stats.raster_ns; if(divisor){ ncqprefix((uintmax_t)results[i].stats.writeouts * NANOSECS_IN_SEC * 1000 / divisor, @@ -455,7 +455,7 @@ summary_table(struct notcurses* nc, const char* spec, bool canimage, bool canvid failed = true; } totalframes += results[i].stats.renders; - totalbytes += results[i].stats.render_bytes; + totalbytes += results[i].stats.raster_bytes; totalrenderns += results[i].stats.render_ns; totalwriteoutns += results[i].stats.writeout_ns; } diff --git a/src/demo/zoo.c b/src/demo/zoo.c index 952216b0e..9e9ad7065 100644 --- a/src/demo/zoo.c +++ b/src/demo/zoo.c @@ -14,6 +14,7 @@ draw_background(struct notcurses* nc){ struct ncvisual_options vopts = { .scaling = NCSCALE_STRETCH, .n = n, + .flags = NCVISUAL_OPTION_CHILDPLANE, }; if(ncvisual_blit(nc, ncv, &vopts) == NULL){ ncvisual_destroy(ncv); diff --git a/src/fetch/main.c b/src/fetch/main.c index 0598acc79..047ac0283 100644 --- a/src/fetch/main.c +++ b/src/fetch/main.c @@ -65,29 +65,6 @@ fetch_env_vars(struct notcurses* nc, fetched_info* fi){ return 0; } -static distro_info distros[] = { - { - .name = "arch", - // from core/filesystem - .logofile = "/usr/share/pixmaps/archlinux.png", - }, { - .name = "artix", - // from system/filesystem - .logofile = "/usr/share/pixmaps/artixlinux-logo.png", - }, { - .name = "debian", - // from desktop-base package - .logofile = "/usr/share/desktop-base/debian-logos/logo-text-256.png", - }, { - .name = "fedora", - // from redhat-lsb-core package - .logofile = "/usr/share/pixmaps/fedora-logo.png", - }, { - .name = NULL, - .logofile = NULL, - }, -}; - static int fetch_bsd_cpuinfo(fetched_info* fi){ #if defined(__linux__) || defined(__gnu_hurd__) || defined(__MINGW64__) @@ -110,6 +87,32 @@ fetch_bsd_cpuinfo(fetched_info* fi){ return 0; } +static int +fetch_windows_cpuinfo(fetched_info* fi){ +#ifdef __MINGW64__ + LPSYSTEM_INFO info; + GetSystemInfo(info); + switch(info->wProcessorArchitecture){ + case PROCESSOR_ARCHITECTURE_AMD64: + fi->cpu_model = strdup("amd64"); break; + case PROCESSOR_ARCHITECTURE_ARM: + fi->cpu_model = strdup("ARM"); break; + case PROCESSOR_ARCHITECTURE_ARM64: + fi->cpu_model = strdup("AArch64"); break; + case PROCESSOR_ARCHITECTURE_IA64: + fi->cpu_model = strdup("Itanium"); break; + case PROCESSOR_ARCHITECTURE_INTEL: + fi->cpu_model = strdup("i386"); break; + default: + fi->cpu_model = strdup("Unknown processor"); break; + } + fi->core_count = info->dwNumberOfProcessors; +#else + (void)fi; +#endif + return 0; +} + static int fetch_cpu_info(fetched_info* fi){ FILE* cpuinfo = fopen("/proc/cpuinfo", "re"); @@ -197,6 +200,7 @@ fetch_x_props(fetched_info* fi){ return 0; } +#ifdef __linux__ // Given a filename, check for its existence in the directories specified by // https://specifications.freedesktop.org/icon-theme-spec/latest/ar01s03.html. // Returns NULL if no such file can be found. Return value is heap-allocated. @@ -217,10 +221,35 @@ get_xdg_logo(const char *spec){ strcat(p, spec); return p; } +#endif // FIXME deal more forgivingly with quotation marks static const distro_info* linux_ncneofetch(fetched_info* fi){ + const distro_info* dinfo = NULL; +#ifdef __linux__ + static const distro_info distros[] = { + { + .name = "arch", + // from core/filesystem + .logofile = "/usr/share/pixmaps/archlinux.png", + }, { + .name = "artix", + // from system/filesystem + .logofile = "/usr/share/pixmaps/artixlinux-logo.png", + }, { + .name = "debian", + // from desktop-base package + .logofile = "/usr/share/desktop-base/debian-logos/logo-text-256.png", + }, { + .name = "fedora", + // from redhat-lsb-core package + .logofile = "/usr/share/pixmaps/fedora-logo.png", + }, { + .name = NULL, + .logofile = NULL, + }, + }; FILE* osinfo = fopen("/etc/os-release", "re"); if(osinfo == NULL){ return NULL; @@ -266,7 +295,6 @@ linux_ncneofetch(fetched_info* fi){ if(distro == NULL){ return NULL; } - const distro_info* dinfo = NULL; for(dinfo = distros ; dinfo->name ; ++dinfo){ if(strcmp(dinfo->name, distro) == 0){ break; @@ -276,6 +304,9 @@ linux_ncneofetch(fetched_info* fi){ fi->neologo = get_neofetch_art(distro); } free(distro); +#else + (void)fi; +#endif return dinfo; } @@ -309,7 +340,14 @@ get_kernel(fetched_info* fi){ } fprintf(stderr, "Unknown operating system via uname: %s\n", uts.sysname); #else - (void)fi; + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + char ver[20]; // sure why not + snprintf(ver, sizeof(ver), "%lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion); + fi->kernver = strdup(ver); + fi->kernel = strdup("Windows NT"); return NCNEO_WINDOWS; #endif return NCNEO_UNKNOWN; @@ -440,7 +478,7 @@ infoplane_notcurses(struct notcurses* nc, const fetched_info* fi, int planeheigh size_t oldlenp = sizeof(ram); if(sysctlbyname("hw.memsize", &ram, &oldlenp, NULL, 0) == 0){ char tram[NCBPREFIXSTRLEN + 1]; - bprefix(ram, 1, tram, 1); + ncbprefix(ram, 1, tram, 1); ncplane_printf_aligned(infop, 2, NCALIGN_LEFT, " RAM: %sB", tram); } #endif @@ -664,6 +702,8 @@ ncneofetch(struct notcurses* nc){ } if(kern == NCNEO_LINUX){ fetch_cpu_info(&fi); + }else if(kern == NCNEO_WINDOWS){ + fetch_windows_cpuinfo(&fi); }else{ fetch_bsd_cpuinfo(&fi); } diff --git a/src/info/main.c b/src/info/main.c index 67eeab89c..90dea2663 100644 --- a/src/info/main.c +++ b/src/info/main.c @@ -331,7 +331,7 @@ unicodedumper(struct ncplane* n, const char* indent){ static int display_logo(struct ncplane* n, const char* path){ unsigned cpixy, cpixx; - ncplane_pixelgeom(n, NULL, NULL, &cpixy, &cpixx, NULL, NULL); + ncplane_pixel_geom(n, NULL, NULL, &cpixy, &cpixx, NULL, NULL); struct ncvisual* ncv = ncvisual_from_file(path); if(ncv == NULL){ return -1; diff --git a/src/input/input.cpp b/src/input/input.cpp index 1d252ba7c..bd787fbfd 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -255,7 +255,7 @@ int input_demo(ncpp::NotCurses* nc) { auto n = nc->get_stdplane(&dimy, &dimx); // FIXME no ncpp wrapper for Plane::pixelgeom? unsigned celldimx, maxbmapx; - ncplane_pixelgeom(*n, nullptr, nullptr, nullptr, &celldimx, nullptr, &maxbmapx); + ncplane_pixel_geom(*n, nullptr, nullptr, nullptr, &celldimx, nullptr, &maxbmapx); struct ncplane_options nopts = { .y = static_cast(dimy) - PLOTHEIGHT - 1, .x = NCALIGN_CENTER, diff --git a/src/lib/debug.c b/src/lib/debug.c index 6724fe979..dc86796c7 100644 --- a/src/lib/debug.c +++ b/src/lib/debug.c @@ -2,12 +2,6 @@ int loglevel = NCLOGLEVEL_SILENT; -void notcurses_debug_caps(const notcurses* nc, FILE* debugfp){ - // FIXME deprecated, remove for ABI3 - (void)nc; - (void)debugfp; -} - void notcurses_debug(const notcurses* nc, FILE* debugfp){ fbuf f; if(fbuf_init_small(&f)){ diff --git a/src/lib/direct.c b/src/lib/direct.c index 4dd94d13a..ea14bfa90 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -1124,11 +1124,6 @@ ncdirect_style_emit(ncdirect* n, unsigned stylebits, fbuf* f){ return r; } -// turn on any specified stylebits -int ncdirect_styles_on(ncdirect* n, unsigned stylebits){ - return ncdirect_on_styles(n, stylebits); -} - int ncdirect_on_styles(ncdirect* n, unsigned stylebits){ if((stylebits & n->tcache.supported_styles) < stylebits){ // unsupported styles return -1; @@ -1148,11 +1143,7 @@ int ncdirect_on_styles(ncdirect* n, unsigned stylebits){ return 0; } -int ncdirect_styles_off(ncdirect* n, unsigned stylebits){ - return ncdirect_off_styles(n, stylebits); -} - -unsigned ncdirect_styles(const ncdirect* n){ +uint16_t ncdirect_styles(const ncdirect* n){ return n->stylemask; } @@ -1173,10 +1164,6 @@ int ncdirect_off_styles(ncdirect* n, unsigned stylebits){ return 0; } -int ncdirect_styles_set(ncdirect* n, unsigned stylebits){ - return ncdirect_set_styles(n, stylebits); -} - // set the current stylebits to exactly those provided int ncdirect_set_styles(ncdirect* n, unsigned stylebits){ if((stylebits & n->tcache.supported_styles) < stylebits){ // unsupported styles @@ -1595,7 +1582,7 @@ int ncdirectf_geom(ncdirect* n, ncdirectf* frame, &placey, &placex); } -unsigned ncdirect_supported_styles(const ncdirect* nc){ +uint16_t ncdirect_supported_styles(const ncdirect* nc){ return term_supported_styles(&nc->tcache); } diff --git a/src/lib/fd.c b/src/lib/fd.c index b70052b99..965c83679 100644 --- a/src/lib/fd.c +++ b/src/lib/fd.c @@ -233,11 +233,11 @@ launch_pipe_process(int* pipefd, int* pidfd, unsigned usepath, } #endif +#ifndef __MINGW64__ // nuke the just-spawned process, and reap it. called before the subprocess // reader thread is launched (which otherwise reaps the subprocess). static int kill_and_wait_subproc(pid_t pid, int pidfd, int* status){ -#ifndef __MINGW64__ int ret = -1; // on linux, we try pidfd_send_signal, if the pidfd has been defined. // otherwise, we fall back to regular old kill(); @@ -258,12 +258,6 @@ kill_and_wait_subproc(pid_t pid, int pidfd, int* status){ return -1; } return 0; -#else - (void)pid; - (void)pidfd; - (void)status; - return -1; -#endif } // need a poll on both main fd and pidfd @@ -335,6 +329,7 @@ ncsubproc_launch(ncplane* n, ncsubproc* ret, const ncsubproc_options* opts, int } return ret->nfp; } +#endif // use of env implies usepath static ncsubproc* diff --git a/src/lib/in.c b/src/lib/in.c index 25102cc7d..12f3184b9 100644 --- a/src/lib/in.c +++ b/src/lib/in.c @@ -502,11 +502,11 @@ mouse_click(inputctx* ictx, unsigned release, char follow){ logwarn("dropping click in margins %ld/%ld\n", y, x); return; } - if(x >= ictx->ti->dimx - (ictx->rmargin + ictx->lmargin)){ + if((unsigned)x >= ictx->ti->dimx - (ictx->rmargin + ictx->lmargin)){ logwarn("dropping click in margins %ld/%ld\n", y, x); return; } - if(y >= ictx->ti->dimy - (ictx->bmargin + ictx->tmargin)){ + if((unsigned)y >= ictx->ti->dimy - (ictx->bmargin + ictx->tmargin)){ logwarn("dropping click in margins %ld/%ld\n", y, x); return; } @@ -2200,18 +2200,6 @@ uint32_t ncdirect_get(ncdirect* n, const struct timespec* ts, ncinput* ni){ return internal_get(n->tcache.ictx, ts, ni); } -uint32_t notcurses_getc(notcurses* nc, const struct timespec* ts, - const void* unused, ncinput* ni){ - (void)unused; // FIXME remove for abi3 - return notcurses_get(nc, ts, ni); -} - -uint32_t ncdirect_getc(ncdirect* nc, const struct timespec *ts, - const void* unused, ncinput* ni){ - (void)unused; // FIXME remove for abi3 - return ncdirect_get(nc, ts, ni); -} - int get_cursor_location(inputctx* ictx, const char* u7, unsigned* y, unsigned* x){ pthread_mutex_lock(&ictx->clock); while(ictx->cvalid == 0){ diff --git a/src/lib/internal.h b/src/lib/internal.h index 4b98deb13..ffa72557a 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -393,7 +393,7 @@ void summarize_stats(notcurses* nc); void update_raster_stats(const struct timespec* time1, const struct timespec* time0, ncstats* stats); void update_render_stats(const struct timespec* time1, const struct timespec* time0, ncstats* stats); -void update_render_bytes(ncstats* stats, int bytes); +void update_raster_bytes(ncstats* stats, int bytes); void update_write_stats(const struct timespec* time1, const struct timespec* time0, ncstats* stats, int bytes); void sigwinch_handler(int signo); diff --git a/src/lib/metric.c b/src/lib/metric.c index aab43de5d..ab78ed751 100644 --- a/src/lib/metric.c +++ b/src/lib/metric.c @@ -116,8 +116,3 @@ const char* ncnmetric(uintmax_t val, size_t s, uintmax_t decimal, } return buf; } - -const char *ncmetric(uintmax_t val, uintmax_t decimal, char *buf, int omitdec, - uintmax_t mult, int uprefix){ - return ncnmetric(val, INT_MAX, decimal, buf, omitdec, mult, uprefix); -} diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 77b9302bf..455bdd084 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -125,35 +125,6 @@ notcurses_stop_minimal(void* vnc){ return ret; } -// make a heap-allocated wchar_t expansion of the multibyte string at s -wchar_t* wchar_from_utf8(const char* s){ - mbstate_t ps; - memset(&ps, 0, sizeof(ps)); - // worst case is a wchar_t for every byte of input (all-ASCII case) - const size_t maxw = strlen(s) + 1; - wchar_t* dst = malloc(sizeof(*dst) * maxw); - size_t wcount = mbsrtowcs(dst, &s, maxw, &ps); - if(wcount == (size_t)-1){ - free(dst); - return NULL; - } - if(s){ - free(dst); - return NULL; - } - return dst; -} - -int ncplane_putstr_aligned(ncplane* n, int y, ncalign_e align, const char* s){ - wchar_t* w = wchar_from_utf8(s); - if(w == NULL){ - return -1; - } - int r = ncplane_putwstr_aligned(n, y, align, w); - free(w); - return r; -} - static const char NOTCURSES_VERSION[] = NOTCURSES_VERSION_MAJOR "." NOTCURSES_VERSION_MINOR "." @@ -605,20 +576,6 @@ ncplane* ncpile_create(notcurses* nc, const struct ncplane_options* nopts){ return ncplane_new_internal(nc, NULL, nopts); } -struct ncplane* ncplane_new(struct ncplane* n, int rows, int cols, int y, int x, void* opaque, const char* name){ - ncplane_options nopts = { - .y = y, - .x = x, - .rows = rows, - .cols = cols, - .userptr = opaque, - .name = name, - .resizecb = NULL, - .flags = 0, - }; - return ncplane_create(n, &nopts); -} - void ncplane_home(ncplane* n){ n->x = 0; n->y = 0; @@ -1383,32 +1340,44 @@ const char* cell_extended_gcluster(const struct ncplane* n, const nccell* c){ // 'n' ends up above 'above' int ncplane_move_above(ncplane* restrict n, ncplane* restrict above){ - if(n == above){ + if(n == above){ // probably gets optimized out =/ return -1; } + ncpile* p = ncplane_pile(n); if(above == NULL){ - ncplane_move_bottom(n); + if(n->below){ + if( (n->below->above = n->above) ){ + n->above->below = n->below; + }else{ + p->top = n->below; + } + n->below = NULL; + if( (n->above = p->bottom) ){ + n->above->below = n; + } + p->bottom = n; + } return 0; } - if(ncplane_pile(n) != ncplane_pile(above)){ // can't move among piles - return -1; - } if(n->below != above){ + if(p != ncplane_pile(above)){ // can't move among piles + return -1; + } // splice out 'n' if(n->below){ n->below->above = n->above; }else{ - ncplane_pile(n)->bottom = n->above; + p->bottom = n->above; } if(n->above){ n->above->below = n->below; }else{ - ncplane_pile(n)->top = n->below; + p->top = n->below; } if( (n->above = above->above) ){ above->above->below = n; }else{ - ncplane_pile(n)->top = n; + p->top = n; } above->above = n; n->below = above; @@ -1416,33 +1385,45 @@ int ncplane_move_above(ncplane* restrict n, ncplane* restrict above){ return 0; } -// 'n' ends up below 'below' +// 'n' ends up below 'below', or on top if 'below' == NULL int ncplane_move_below(ncplane* restrict n, ncplane* restrict below){ - if(n == below){ + if(n == below){ // probably gets optimized out =/ return -1; } + ncpile* p = ncplane_pile(n); if(below == NULL){ - ncplane_move_top(n); + if(n->above){ + if( (n->above->below = n->below) ){ + n->below->above = n->above; + }else{ + p->bottom = n->above; + } + n->above = NULL; + if( (n->below = p->top) ){ + n->below->above = n; + } + p->top = n; + } return 0; } - if(ncplane_pile(n) != ncplane_pile(below)){ // can't move among piles - return -1; - } if(n->above != below){ + if(p != ncplane_pile(below)){ // can't move among piles + return -1; + } if(n->below){ n->below->above = n->above; }else{ - ncplane_pile(n)->bottom = n->above; + p->bottom = n->above; } if(n->above){ n->above->below = n->below; }else{ - ncplane_pile(n)->top = n->below; + p->top = n->below; } if( (n->below = below->below) ){ below->below->above = n; }else{ - ncplane_pile(n)->bottom = n; + p->bottom = n; } below->below = n; n->above = below; @@ -1450,36 +1431,6 @@ int ncplane_move_below(ncplane* restrict n, ncplane* restrict below){ return 0; } -void ncplane_move_top(ncplane* n){ - if(n->above){ - if( (n->above->below = n->below) ){ - n->below->above = n->above; - }else{ - ncplane_pile(n)->bottom = n->above; - } - n->above = NULL; - if( (n->below = ncplane_pile(n)->top) ){ - n->below->above = n; - } - ncplane_pile(n)->top = n; - } -} - -void ncplane_move_bottom(ncplane* n){ - if(n->below){ - if( (n->below->above = n->above) ){ - n->above->below = n->below; - }else{ - ncplane_pile(n)->top = n->below; - } - n->below = NULL; - if( (n->above = ncplane_pile(n)->bottom) ){ - n->above->below = n; - } - ncplane_pile(n)->bottom = n; - } -} - // if above is NULL, we're moving to the bottom int ncplane_move_family_above(ncplane* restrict n, ncplane* restrict bpoint){ ncplane* above = ncplane_above(n); @@ -1584,7 +1535,7 @@ void scroll_down(ncplane* n){ for(struct ncplane* c = n->blist ; c ; c = c->bnext){ if(!c->fixedbound){ if(ncplanes_intersect_p(n, c)){ - ncplane_moverel(c, -1, 0); + ncplane_move_rel(c, -1, 0); } } } @@ -1627,10 +1578,6 @@ int ncplane_scrollup_child(ncplane* n, const ncplane* child){ return ret; } -int nccell_width(const ncplane* n __attribute__ ((unused)), const nccell* c){ - return nccell_cols(c); -} - int nccell_load(ncplane* n, nccell* c, const char* gcluster){ int cols; int bytes = utf8_egc_len(gcluster, &cols); @@ -1787,7 +1734,7 @@ int ncplane_putegc_stained(ncplane* n, const char* gclust, int* sbytes){ } int ncplane_cursor_at(const ncplane* n, nccell* c, char** gclust){ - if(n->y == n->leny && n->x == n->lenx){ + if(n->y >= n->leny || n->x >= n->lenx){ return -1; } const nccell* src = &n->fb[nfbcellidx(n, n->y, n->x)]; @@ -1800,7 +1747,7 @@ int ncplane_cursor_at(const ncplane* n, nccell* c, char** gclust){ return 0; } -unsigned notcurses_supported_styles(const notcurses* nc){ +uint16_t notcurses_supported_styles(const notcurses* nc){ return term_supported_styles(&nc->tcache); } @@ -1821,28 +1768,16 @@ void ncplane_set_styles(ncplane* n, unsigned stylebits){ n->stylemask = (stylebits & NCSTYLE_MASK); } -void ncplane_styles_set(ncplane* n, unsigned stylebits){ // deprecated - ncplane_set_styles(n, stylebits); -} - // turn on any specified stylebits void ncplane_on_styles(ncplane* n, unsigned stylebits){ n->stylemask |= (stylebits & NCSTYLE_MASK); } -void ncplane_styles_on(ncplane* n, unsigned stylebits){ // deprecated - ncplane_on_styles(n, stylebits); -} - // turn off any specified stylebits void ncplane_off_styles(ncplane* n, unsigned stylebits){ n->stylemask &= ~(stylebits & NCSTYLE_MASK); } -void ncplane_styles_off(ncplane* n, unsigned stylebits){ // deprecated - ncplane_off_styles(n, stylebits); -} - // i hate the big allocation and two copies here, but eh what you gonna do? // well, for one, we don't need the huge allocation FIXME char* ncplane_vprintf_prep(const char* format, va_list ap){ @@ -1904,6 +1839,13 @@ int ncplane_vprintf_stained(struct ncplane* n, const char* format, va_list ap){ return ret; } +int ncplane_putnstr_aligned(struct ncplane* n, int y, ncalign_e align, size_t s, const char* str){ + char* chopped = strndup(str, s); + int ret = ncplane_putstr_aligned(n, y, align, chopped); + free(chopped); + return ret; +} + int ncplane_hline_interp(ncplane* n, const nccell* c, unsigned len, uint64_t c1, uint64_t c2){ if(len <= 0){ @@ -2370,10 +2312,6 @@ ncpalette* ncpalette_new(notcurses* nc){ return p; } -ncpalette* palette256_new(notcurses* nc){ - return ncpalette_new(nc); -} - int ncpalette_use(notcurses* nc, const ncpalette* p){ int ret = -1; if(!notcurses_canchangecolor(nc)){ @@ -2389,18 +2327,10 @@ int ncpalette_use(notcurses* nc, const ncpalette* p){ return ret; } -int palette256_use(notcurses* nc, const ncpalette* p){ - return ncpalette_use(nc, p); -} - void ncpalette_free(ncpalette* p){ free(p); } -void palette256_free(ncpalette* p){ - ncpalette_free(p); -} - bool ncplane_translate_abs(const ncplane* n, int* restrict y, int* restrict x){ ncplane_translate(ncplane_stdplane_const(n), n, y, x); if(y){ @@ -3006,32 +2936,6 @@ char* ncplane_contents(ncplane* nc, int begy, int begx, unsigned leny, unsigned return ret; } -int nccells_double_box(ncplane* n, uint16_t attr, uint64_t channels, - nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){ - if(notcurses_canutf8(ncplane_notcurses(n))){ - return nccells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, NCBOXDOUBLE); - } - return nccells_ascii_box(n, attr, channels, ul, ur, ll, lr, hl, vl); -} - -int cells_double_box(ncplane* n, uint16_t attr, uint64_t channels, - nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){ - return nccells_double_box(n, attr, channels, ul, ur, ll, lr, hl, vl); -} - -int nccells_rounded_box(ncplane* n, uint16_t attr, uint64_t channels, - nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){ - if(notcurses_canutf8(ncplane_notcurses(n))){ - return nccells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, NCBOXROUND); - } - return nccells_ascii_box(n, attr, channels, ul, ur, ll, lr, hl, vl); -} - -int cells_rounded_box(ncplane* n, uint16_t attr, uint64_t channels, - nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){ - return nccells_rounded_box(n, attr, channels, ul, ur, ll, lr, hl, vl); -} - // 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 @@ -3053,45 +2957,6 @@ void nclog(const char* fmt, ...){ va_end(va); } -int ncplane_putstr_yx(struct ncplane* n, int y, int x, const char* gclusters){ - int ret = 0; - while(*gclusters){ - int wcs; - int cols = ncplane_putegc_yx(n, y, x, gclusters, &wcs); -//fprintf(stderr, "wrote %.*s %d cols %d bytes now at %d/%d\n", wcs, gclusters, cols, wcs, n->y, n->x); - if(cols < 0){ - return -ret; - } - if(wcs == 0){ - break; - } - // after the first iteration, just let the cursor code control where we - // print, so that scrolling is taken into account - y = -1; - x = -1; - gclusters += wcs; - ret += cols; - } - return ret; -} - -int ncplane_putstr_stained(struct ncplane* n, const char* gclusters){ - int ret = 0; - while(*gclusters){ - int wcs; - int cols = ncplane_putegc_stained(n, gclusters, &wcs); - if(cols < 0){ - return -ret; - } - if(wcs == 0){ - break; - } - gclusters += wcs; - ret += cols; - } - return ret; -} - int ncplane_putwstr_stained(ncplane* n, const wchar_t* gclustarr){ mbstate_t ps = {}; const wchar_t** wset = &gclustarr; @@ -3115,36 +2980,6 @@ int ncplane_putwstr_stained(ncplane* n, const wchar_t* gclustarr){ return r; } -int ncplane_putnstr_aligned(struct ncplane* n, int y, ncalign_e align, size_t s, const char* str){ - char* chopped = strndup(str, s); - int ret = ncplane_putstr_aligned(n, y, align, chopped); - free(chopped); - return ret; -} - -int ncplane_putnstr_yx(struct ncplane* n, int y, int x, size_t s, const char* gclusters){ - int ret = 0; - int offset = 0; -//fprintf(stderr, "PUT %zu at %d/%d [%.*s]\n", s, y, x, (int)s, gclusters); - while((size_t)offset < s && gclusters[offset]){ - int wcs; - int cols = ncplane_putegc_yx(n, y, x, gclusters + offset, &wcs); - if(cols < 0){ - return -ret; - } - if(wcs == 0){ - break; - } - // after the first iteration, just let the cursor code control where we - // print, so that scrolling is taken into account - y = -1; - x = -1; - offset += wcs; - ret += cols; - } - return ret; -} - int notcurses_ucs32_to_utf8(const uint32_t* ucs32, unsigned ucs32count, unsigned char* resultbuf, size_t buflen){ if(u32_to_u8(ucs32, ucs32count, resultbuf, &buflen) == NULL){ @@ -3153,19 +2988,17 @@ int notcurses_ucs32_to_utf8(const uint32_t* ucs32, unsigned ucs32count, return buflen; } -int ncstrwidth(const char* mbs){ - return ncstrwidth_valid(mbs, NULL, NULL); -} - int ncstrwidth_valid(const char* egcs, int* validbytes, int* validwidth){ - int cols = 0; // number of columns consumed thus far + int cols; if(validwidth == NULL){ validwidth = &cols; } - int bytes = 0; // number of bytes consumed thus far + *validwidth = 0; + int bytes; if(validbytes == NULL){ validbytes = &bytes; } + *validbytes = 0; do{ int thesecols, thesebytes; thesebytes = utf8_egc_len(egcs, &thesecols); @@ -3179,9 +3012,10 @@ int ncstrwidth_valid(const char* egcs, int* validbytes, int* validwidth){ return *validwidth; } -void ncplane_pixelgeom(const ncplane* n, unsigned* RESTRICT pxy, unsigned* RESTRICT pxx, - unsigned* RESTRICT celldimy, unsigned* RESTRICT celldimx, - unsigned* RESTRICT maxbmapy, unsigned* RESTRICT maxbmapx){ +void ncplane_pixel_geom(const ncplane* n, + unsigned* RESTRICT pxy, unsigned* RESTRICT pxx, + unsigned* RESTRICT celldimy, unsigned* RESTRICT celldimx, + unsigned* RESTRICT maxbmapy, unsigned* RESTRICT maxbmapx){ notcurses* nc = ncplane_notcurses(n); if(celldimy){ *celldimy = nc->tcache.cellpixy; diff --git a/src/lib/plot.c b/src/lib/plot.c index d6b69dee7..5cd5975a4 100644 --- a/src/lib/plot.c +++ b/src/lib/plot.c @@ -127,12 +127,12 @@ int redraw_pixelplot_##T(nc##X##plot* ncp){ \ char buf[NCPREFIXSTRLEN + 1]; \ if(ncp->plot.exponentiali){ \ if(y == dimy - 1){ /* we cheat on the top row to exactly match maxy */ \ - ncmetric(ncp->maxy * 100, 100, buf, 0, 1000, '\0'); \ + ncqprefix(ncp->maxy * 100, 100, buf, 0); \ }else{ \ - ncmetric(pow(interval, (y + 1) * states) * 100, 100, buf, 0, 1000, '\0'); \ + ncqprefix(pow(interval, (y + 1) * states) * 100, 100, buf, 0); \ } \ }else{ \ - ncmetric((ncp->maxy - interval * states * (dimy - y - 1)) * 100, 100, buf, 0, 1000, '\0'); \ + ncqprefix((ncp->maxy - interval * states * (dimy - y - 1)) * 100, 100, buf, 0); \ } \ if(y == dimy - 1 && strlen(ncp->plot.title)){ \ ncplane_printf_yx(ncp->plot.ncp, dimy - y - 1, 0, "%*.*s %s", \ @@ -297,12 +297,12 @@ int redraw_plot_##T(nc##X##plot* ncp){ \ char buf[NCPREFIXSTRLEN + 1]; \ if(ncp->plot.exponentiali){ \ if(y == dimy - 1){ /* we cheat on the top row to exactly match maxy */ \ - ncmetric(ncp->maxy * 100, 100, buf, 0, 1000, '\0'); \ + ncqprefix(ncp->maxy * 100, 100, buf, 0); \ }else{ \ - ncmetric(pow(interval, (y + 1) * states) * 100, 100, buf, 0, 1000, '\0'); \ + ncqprefix(pow(interval, (y + 1) * states) * 100, 100, buf, 0); \ } \ }else{ \ - ncmetric((ncp->maxy - interval * states * (dimy - y - 1)) * 100, 100, buf, 0, 1000, '\0'); \ + ncqprefix((ncp->maxy - interval * states * (dimy - y - 1)) * 100, 100, buf, 0); \ } \ if(y == dimy - 1 && strlen(ncp->plot.title)){ \ ncplane_printf_yx(ncp->plot.ncp, dimy - y - 1, NCPREFIXCOLUMNS - strlen(buf), "%s %s", buf, ncp->plot.title); \ diff --git a/src/lib/reel.c b/src/lib/reel.c index a4ab71cdd..8a5e0efe3 100644 --- a/src/lib/reel.c +++ b/src/lib/reel.c @@ -754,10 +754,6 @@ ncplane* nctablet_plane(nctablet* t){ return t->cbp; } -ncplane* nctablet_ncplane(nctablet* t){ // deprecated - return nctablet_plane(t); -} - ncplane* ncreel_plane(ncreel* nr){ return nr->p; } diff --git a/src/lib/render.c b/src/lib/render.c index 0fd160d04..ef8917cb3 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -122,11 +122,6 @@ void nccell_release(ncplane* n, nccell* c){ pool_release(&n->pool, c); } -// FIXME deprecated, goes away in abi3 -void cell_release(ncplane* n, nccell* c){ - nccell_release(n, c); -} - // Duplicate one cell onto another when they share a plane. Convenience wrapper. int nccell_duplicate(ncplane* n, nccell* targ, const nccell* c){ if(cell_duplicate_far(&n->pool, targ, n, c) < 0){ @@ -136,11 +131,6 @@ int nccell_duplicate(ncplane* n, nccell* targ, const nccell* c){ return 0; } -// deprecated, goes away in abi3 -int cell_duplicate(struct ncplane* n, nccell* targ, const nccell* c){ - return nccell_duplicate(n, targ, c); -} - // Emit fchannel with RGB changed to contrast effectively against bchannel. static uint32_t highcontrast(const tinfo* ti, uint32_t bchannel){ @@ -1458,10 +1448,6 @@ int ncpile_render_to_file(ncplane* n, FILE* fp){ return ret; } -int notcurses_render_to_file(notcurses* nc, FILE* fp){ - return ncpile_render_to_file(notcurses_stdplane(nc), fp); -} - // We execute the painter's algorithm, starting from our topmost plane. The // damagevector should be all zeros on input. On success, it will reflect // which cells were changed. We solve for each coordinate's cell by walking @@ -1505,7 +1491,7 @@ int ncpile_rasterize(ncplane* n){ // accepts -1 as an indication of failure clock_gettime(CLOCK_MONOTONIC, &writedone); pthread_mutex_lock(&nc->stats.lock); - update_render_bytes(&nc->stats.s, bytes); + update_raster_bytes(&nc->stats.s, bytes); update_raster_stats(&rasterdone, &start, &nc->stats.s); update_write_stats(&writedone, &rasterdone, &nc->stats.s, bytes); pthread_mutex_unlock(&nc->stats.lock); @@ -1556,18 +1542,6 @@ int ncpile_render(ncplane* n){ return 0; } -int notcurses_render(notcurses* nc){ -//fprintf(stderr, "--------------- BEGIN RENDER\n"); -//notcurses_debug(nc, stderr); - ncplane* stdn = notcurses_stdplane(nc); - if(ncpile_render(stdn)){ - return -1; - } - int i = ncpile_rasterize(stdn); -//fprintf(stderr, "----------------- END RENDER\n"); - return i; -} - // run the top half of notcurses_render(), and steal the buffer from rstate. int ncpile_render_to_buffer(ncplane* p, char** buf, size_t* buflen){ if(ncpile_render(p)){ @@ -1578,7 +1552,7 @@ int ncpile_render_to_buffer(ncplane* p, char** buf, size_t* buflen){ fbuf_reset(&nc->rstate.f); int bytes = notcurses_rasterize_inner(nc, ncplane_pile(p), &nc->rstate.f, &useasu); pthread_mutex_lock(&nc->stats.lock); - update_render_bytes(&nc->stats.s, bytes); + update_raster_bytes(&nc->stats.s, bytes); pthread_mutex_unlock(&nc->stats.lock); if(bytes < 0){ return -1; @@ -1589,10 +1563,6 @@ int ncpile_render_to_buffer(ncplane* p, char** buf, size_t* buflen){ return 0; } -int notcurses_render_to_buffer(notcurses* nc, char** buf, size_t* buflen){ - return ncpile_render_to_buffer(notcurses_stdplane(nc), buf, buflen); -} - // copy the UTF8-encoded EGC out of the cell, whether simple or complex. the // result is not tied to the ncplane, and persists across erases / destruction. static inline char* diff --git a/src/lib/stats.c b/src/lib/stats.c index eb8511a17..a05193d18 100644 --- a/src/lib/stats.c +++ b/src/lib/stats.c @@ -22,16 +22,16 @@ void update_write_stats(const struct timespec* time1, const struct timespec* tim } // negative 'bytes' are ignored as failures. call only while holding statlock. -// we don't increment failed_renders here because 'bytes' < 0 actually indicates -// a rasterization failure -- we can't fail in rendering anymore. -void update_render_bytes(ncstats* stats, int bytes){ +// we don't increment failed_rasters here because 'bytes' < 0 actually indicates +// a rasterization failure -- we can't fail in rastering anymore. +void update_raster_bytes(ncstats* stats, int bytes){ if(bytes >= 0){ - stats->render_bytes += bytes; - if(bytes > stats->render_max_bytes){ - stats->render_max_bytes = bytes; + stats->raster_bytes += bytes; + if(bytes > stats->raster_max_bytes){ + stats->raster_max_bytes = bytes; } - if(bytes < stats->render_min_bytes){ - stats->render_min_bytes = bytes; + if(bytes < stats->raster_min_bytes){ + stats->raster_min_bytes = bytes; } } } @@ -76,7 +76,7 @@ void reset_stats(ncstats* stats){ unsigned planes = stats->planes; memset(stats, 0, sizeof(*stats)); stats->render_min_ns = 1ull << 62u; - stats->render_min_bytes = 1ull << 62u; + stats->raster_min_bytes = 1ull << 62u; stats->raster_min_ns = 1ull << 62u; stats->writeout_min_ns = 1ull << 62u; stats->fbbytes = fbbytes; @@ -108,8 +108,8 @@ void notcurses_stats_reset(notcurses* nc, ncstats* stats){ if(nc->stats.s.render_min_ns < stash->render_min_ns){ stash->render_min_ns = nc->stats.s.render_min_ns; } - if(nc->stats.s.render_min_bytes < stash->render_min_bytes){ - stash->render_min_bytes = nc->stats.s.render_min_bytes; + if(nc->stats.s.raster_min_bytes < stash->raster_min_bytes){ + stash->raster_min_bytes = nc->stats.s.raster_min_bytes; } if(nc->stats.s.raster_min_ns < stash->raster_min_ns){ stash->raster_min_ns = nc->stats.s.raster_min_ns; @@ -120,8 +120,8 @@ void notcurses_stats_reset(notcurses* nc, ncstats* stats){ if(nc->stats.s.render_max_ns > stash->render_max_ns){ stash->render_max_ns = nc->stats.s.render_max_ns; } - if(nc->stats.s.render_max_bytes > stash->render_max_bytes){ - stash->render_max_bytes = nc->stats.s.render_max_bytes; + if(nc->stats.s.raster_max_bytes > stash->raster_max_bytes){ + stash->raster_max_bytes = nc->stats.s.raster_max_bytes; } if(nc->stats.s.raster_max_ns > stash->raster_max_ns){ stash->raster_max_ns = nc->stats.s.raster_max_ns; @@ -132,7 +132,7 @@ void notcurses_stats_reset(notcurses* nc, ncstats* stats){ stash->writeout_ns += nc->stats.s.writeout_ns; stash->raster_ns += nc->stats.s.raster_ns; stash->render_ns += nc->stats.s.render_ns; - stash->render_bytes += nc->stats.s.render_bytes; + stash->raster_bytes += nc->stats.s.raster_bytes; stash->failed_renders += nc->stats.s.failed_renders; stash->failed_writeouts += nc->stats.s.failed_writeouts; stash->renders += nc->stats.s.renders; @@ -199,11 +199,11 @@ void summarize_stats(notcurses* nc){ totalbuf, minbuf, avgbuf, maxbuf); } if(stats->renders || stats->input_events){ - ncbprefix(stats->render_bytes, 1, totalbuf, 1), - ncbprefix(stats->render_bytes ? stats->render_min_bytes : 0, - 1, minbuf, 1), - ncbprefix(stats->renders ? stats->render_bytes / stats->renders : 0, 1, avgbuf, 1); - ncbprefix(stats->render_max_bytes, 1, maxbuf, 1), + ncbprefix(stats->raster_bytes, 1, totalbuf, 1), + ncbprefix(stats->raster_bytes ? stats->raster_min_bytes : 0, + 1, minbuf, 1), + ncbprefix(stats->renders ? stats->raster_bytes / stats->renders : 0, 1, avgbuf, 1); + ncbprefix(stats->raster_max_bytes, 1, maxbuf, 1), fprintf(stderr, "%s%sB (%sB min, %sB avg, %sB max) %"PRIu64" input%s Ghpa: %"PRIu64 NL, clreol, totalbuf, minbuf, avgbuf, maxbuf, stats->input_events, @@ -240,7 +240,7 @@ void summarize_stats(notcurses* nc){ (stats->sprixelemissions + stats->sprixelelisions) == 0 ? 0 : (stats->sprixelelisions * 100.0) / (stats->sprixelemissions + stats->sprixelelisions), totalbuf, - stats->render_bytes ? (stats->sprixelbytes * 100.0) / stats->render_bytes : 0, + stats->raster_bytes ? (stats->sprixelbytes * 100.0) / stats->raster_bytes : 0, stats->appsync_updates, stats->writeouts ? stats->appsync_updates * 100.0 / stats->writeouts : 0); } diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index e26474bd8..36c5c7aa9 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -832,8 +832,10 @@ int interrogate_terminfo(tinfo* ti, FILE* out, unsigned utf8, logpanic("failed opening Windows ConPTY\n"); return -1; } - if(cursor_y && cursor_x){ - locate_cursor(ti, cursor_y, cursor_x); + unsigned ucy, ucx; + if(locate_cursor(ti, &ucy, &ucx) == 0){ + *cursor_y = ucy; + *cursor_x = ucx; } #elif defined(__linux__) ti->linux_fb_fd = -1; diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index 13f3849cb..1186d40b1 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -221,7 +221,7 @@ get_escape(const tinfo* tdesc, escape_e e){ return NULL; } -static inline int +static inline uint16_t term_supported_styles(const tinfo* ti){ return ti->supported_styles; } diff --git a/src/lib/visual.c b/src/lib/visual.c index 28f2544fe..c0c644ec3 100644 --- a/src/lib/visual.c +++ b/src/lib/visual.c @@ -70,11 +70,6 @@ ncplane* ncvisual_subtitle_plane(ncplane* parent, const ncvisual* ncv){ return visual_implementation.visual_subtitle(parent, ncv); } -char* ncvisual_subtitle(const ncvisual* ncv){ - (void)ncv; // FIXME remove for abi3 - return NULL; -} - int ncvisual_blit_internal(ncvisual* ncv, int rows, int cols, ncplane* n, const struct blitset* bset, const blitterargs* barg){ if(!(barg->flags & NCVISUAL_OPTION_NOINTERPOLATE)){ @@ -127,38 +122,6 @@ ncvisual_origin(const struct ncvisual_options* vopts, unsigned* restrict begy, *begx = vopts ? vopts->begx : 0; } - -int ncvisual_blitter_geom(const notcurses* nc, const ncvisual* n, - const struct ncvisual_options* vopts, - int* y, int* x, int* scaley, int* scalex, - ncblitter_e* blitter){ - ncvgeom geom; - const struct blitset* bset; - unsigned disppxy, disppxx, outy, outx; - int placey, placex; - if(ncvisual_geom_inner(&nc->tcache, n, vopts, &geom, &bset, - &disppxy, &disppxx, &outy, &outx, - &placey, &placex)){ - return -1; - } - if(y){ - *y = geom.pixy; - } - if(x){ - *x = geom.pixx; - } - if(scaley){ - *scaley = geom.scaley; - } - if(scalex){ - *scalex = geom.scalex; - } - if(blitter){ - *blitter = bset->geom; - } - return 0; -} - // create a plane in which to blit the sprixel. |disppixx| and |disppixy| are // scaled pixel geometry on output, and unused on input. |placey| and |placex| // are used to position the new plane, and reset to 0 on output. |outy| and @@ -1175,23 +1138,6 @@ ncplane* ncvisual_blit(notcurses* nc, ncvisual* ncv, const struct ncvisual_optio return n; } -// compatability wrapper around ncvisual_blit that provides the standard plane -// plus NCVISUAL_OPTION_CHILDPLANE if vopts->n is NULL. -ncplane* ncvisual_render(notcurses* nc, ncvisual* ncv, const struct ncvisual_options* vopts){ - struct ncvisual_options fakevopts; - if(vopts == NULL){ - memset(&fakevopts, 0, sizeof(fakevopts)); - }else{ - memcpy(&fakevopts, vopts, sizeof(fakevopts)); - } - vopts = &fakevopts; - if(vopts->n == NULL){ - fakevopts.n = notcurses_stdplane(nc); - fakevopts.flags |= NCVISUAL_OPTION_CHILDPLANE; - } - return ncvisual_blit(nc, ncv, vopts); -} - ncvisual* ncvisual_from_plane(const ncplane* n, ncblitter_e blit, int begy, int begx, unsigned leny, unsigned lenx){ @@ -1345,10 +1291,3 @@ bool notcurses_canopen_videos(const notcurses* nc __attribute__ ((unused))){ } return visual_implementation.canopen_videos; } - -int ncvisual_inflate(ncvisual* n, int scale){ - if(scale <= 0){ - return -1; - } - return ncvisual_resize_noninterpolative(n, n->pixy * scale, n->pixx * scale); -} diff --git a/src/libcpp/NotCurses.cc b/src/libcpp/NotCurses.cc index 05099583e..c8c477756 100644 --- a/src/libcpp/NotCurses.cc +++ b/src/libcpp/NotCurses.cc @@ -5,7 +5,6 @@ using namespace ncpp; notcurses_options NotCurses::default_notcurses_options = { /* termtype */ nullptr, - /* renderfp */ nullptr, /* loglevel */ NCLogLevel::Silent, /* margin_t */ 0, /* margin_r */ 0, diff --git a/src/poc/bitmapstates.c b/src/poc/bitmapstates.c index 624e20bf8..760ee7416 100644 --- a/src/poc/bitmapstates.c +++ b/src/poc/bitmapstates.c @@ -12,8 +12,8 @@ emit(struct ncplane* n, const char* str){ static int wipebitmap(struct notcurses* nc){ unsigned cellpxy, cellpxx; - ncplane_pixelgeom(notcurses_stdplane(nc), NULL, NULL, - &cellpxy, &cellpxx, NULL, NULL); + ncplane_pixel_geom(notcurses_stdplane(nc), NULL, NULL, + &cellpxy, &cellpxx, NULL, NULL); int pixy = cellpxy * 6; int pixx = cellpxx * 6; uint32_t* pixels = malloc(sizeof(*pixels) * pixx * pixy); diff --git a/src/poc/grid.c b/src/poc/grid.c index fa0f283e4..7ea1c113c 100644 --- a/src/poc/grid.c +++ b/src/poc/grid.c @@ -4,7 +4,7 @@ struct ncvisual* draw_grid(struct ncplane* stdn){ unsigned maxby, maxbx; unsigned cellpxy, cellpxx; - ncplane_pixelgeom(stdn, NULL, NULL, &cellpxy, &cellpxx, &maxby, &maxbx); + ncplane_pixel_geom(stdn, NULL, NULL, &cellpxy, &cellpxx, &maxby, &maxbx); if(cellpxy <= 1 || cellpxx <= 1){ fprintf(stderr, "cell-pixel geometry: %d %d\n", cellpxy, cellpxx); return NULL; diff --git a/src/poc/interp.c b/src/poc/interp.c index ca10fc06a..eea0a3827 100644 --- a/src/poc/interp.c +++ b/src/poc/interp.c @@ -105,14 +105,14 @@ int main(void){ } struct ncplane* stdn = notcurses_stdplane(nc); unsigned cellpixy, cellpixx; - ncplane_pixelgeom(stdn, NULL, NULL, &cellpixy, &cellpixx, NULL, NULL); + ncplane_pixel_geom(stdn, NULL, NULL, &cellpixy, &cellpixx, NULL, NULL); if(interp(nc, cellpixy, cellpixx)){ goto err; } ncinput ni; do{ notcurses_getc_blocking(nc, &ni); - }while(ni.evtype == NCTYPE_RELEASE); + }while(ni.id != (uint32_t)-1 && ni.evtype != NCTYPE_RELEASE); notcurses_stop(nc); return EXIT_SUCCESS; diff --git a/src/tests/bitmap.cpp b/src/tests/bitmap.cpp index 43514b577..6ac8bce0b 100644 --- a/src/tests/bitmap.cpp +++ b/src/tests/bitmap.cpp @@ -53,7 +53,7 @@ TEST_CASE("Bitmaps") { vopts.blitter = NCBLIT_PIXEL; vopts.flags = NCVISUAL_OPTION_NODEGRADE; unsigned maxy, maxx; - ncplane_pixelgeom(n_, nullptr, nullptr, nullptr, nullptr, &maxy, &maxx); + ncplane_pixel_geom(n_, nullptr, nullptr, nullptr, nullptr, &maxy, &maxx); CHECK(0 == ncvisual_resize(ncv, maxy, maxx)); auto n = ncvisual_blit(nc_, ncv, &vopts); REQUIRE(nn == n); @@ -306,8 +306,8 @@ TEST_CASE("Bitmaps") { vopts.x = 5; vopts.scaling = NCSCALE_NONE; auto ninf = ncvisual_blit(nc_, ncv, &vopts); - ncplane_set_name(ninf, "ninf"); REQUIRE(nullptr != ninf); + ncplane_set_name(ninf, "ninf"); // y of scaled might not be exactly equal to y of inflated since one // is based around what can be fit into a specific space, whereas the // other is based on a multiple of the original image size, which might diff --git a/src/tests/metric.cpp b/src/tests/metric.cpp index 954555e85..0c25cf95f 100644 --- a/src/tests/metric.cpp +++ b/src/tests/metric.cpp @@ -10,7 +10,7 @@ char* impericize_ncmetric(uintmax_t val, uintmax_t decimal, char* buf, const char* decisep = localeconv()->decimal_point; REQUIRE(decisep); REQUIRE(1 == strlen(decisep)); - REQUIRE(ncmetric(val, decimal, buf, omitdec, mult, uprefix)); + REQUIRE(ncnmetric(val, INT_MAX, decimal, buf, omitdec, mult, uprefix)); char* commie = buf; while( (commie = strstr(commie, decisep)) ){ *commie = '.'; // https://dank.qemfd.net/images/16whcc.jpg @@ -89,20 +89,20 @@ TEST_CASE("Metric") { SUBCASE("Maxints1024") { char buf[NCPREFIXSTRLEN + 1], gold[NCPREFIXSTRLEN + 1]; // FIXME these will change based on the size of intmax_t and uintmax_t - REQUIRE(ncmetric(((double)(INTMAX_MAX - 1ull)), 1, buf, 0, 1024, 'i')); + REQUIRE(ncbprefix(((double)(INTMAX_MAX - 1ull)), 1, buf, 0)); sprintf(gold, "%.2fEi", ((double)(INTMAX_MAX - 1ull)) / (1ull << 60)); CHECK(!strcmp(gold, buf)); - REQUIRE(ncmetric(((double)(INTMAX_MAX - (1ull << 53))), 1, buf, 0, 1024, 'i')); + REQUIRE(ncbprefix(((double)(INTMAX_MAX - (1ull << 53))), 1, buf, 0)); sprintf(gold, "%.2fEi", ((double)(INTMAX_MAX - (1ull << 53))) / (1ull << 60)); CHECK(!strcmp(gold, buf)); - REQUIRE(ncmetric(INTMAX_MAX + 1ull, 1, buf, 0, 1024, 'i')); + REQUIRE(ncbprefix(INTMAX_MAX + 1ull, 1, buf, 0)); sprintf(gold, "%.2fEi", ((double)(INTMAX_MAX + 1ull)) / (1ull << 60)); CHECK(!strcmp(gold, buf)); impericize_ncmetric(UINTMAX_MAX - 1, 1, buf, 0, 1024, 'i'); CHECK(!strcmp("16.00Ei", buf)); impericize_ncmetric(UINTMAX_MAX, 1, buf, 0, 1024, 'i'); CHECK(!strcmp("16.00Ei", buf)); - ncmetric(UINTMAX_MAX - (1ull << 53), 1, buf, 0, 1024, 'i'); + ncbprefix(UINTMAX_MAX - (1ull << 53), 1, buf, 0); sprintf(gold, "%.2fEi", ((double)UINTMAX_MAX - (1ull << 53)) / (1ull << 60)); CHECK(!strcmp(gold, buf)); } @@ -116,7 +116,7 @@ TEST_CASE("Metric") { uintmax_t val = 1; size_t i = 0; do{ - ncmetric(val, 1, buf, 0, 1000, '\0'); + ncqprefix(val, 1, buf, 0); const int sidx = i / 3; snprintf(gold, sizeof(gold), "%ju%s00%c", goldval, decisep, suffixes[sidx]); CHECK(!strcmp(gold, buf)); @@ -139,7 +139,7 @@ TEST_CASE("Metric") { uintmax_t val = 1; size_t i = 0; do{ - ncmetric(val, 1, buf, 1, 1000, '\0'); + ncqprefix(val, 1, buf, 1); const int sidx = i / 3; snprintf(gold, sizeof(gold), "%ju%c", goldval, suffixes[sidx]); CHECK(!strcmp(gold, buf)); @@ -162,7 +162,7 @@ TEST_CASE("Metric") { uintmax_t val = 1; size_t i = 0; do{ - ncmetric(val, 1, buf, 0, 1024, 'i'); + ncbprefix(val, 1, buf, 0); const int sidx = i / 10; snprintf(gold, sizeof(gold), "%ju%s00%ci", goldval, decisep, suffixes[sidx]); CHECK(!strcmp(gold, buf)); @@ -185,7 +185,7 @@ TEST_CASE("Metric") { uintmax_t val = 1; size_t i = 0; do{ - ncmetric(val, 1, buf, 1, 1024, 'i'); + ncbprefix(val, 1, buf, 1); const int sidx = i / 10; snprintf(gold, sizeof(gold), "%ju%ci", goldval, suffixes[sidx]); CHECK(!strcmp(gold, buf)); @@ -208,7 +208,7 @@ TEST_CASE("Metric") { uintmax_t val = 1; size_t i = 0; do{ - ncmetric(val, 1, buf, 0, 1000, '\0'); + ncqprefix(val, 1, buf, 0); const int sidx = i / 10; snprintf(gold, sizeof(gold), "%.2f%c", ((double)val) / vfloor, suffixes[sidx]); CHECK(!strcmp(gold, buf)); @@ -231,7 +231,7 @@ TEST_CASE("Metric") { uintmax_t val = 1; size_t i = 0; do{ - ncmetric(val, 1, buf, 0, 1024, 'i'); + ncbprefix(val, 1, buf, 0); const int sidx = i ? (i - 1) / 3 : 0; snprintf(gold, sizeof(gold), "%.2f%ci", ((double)val) / vfloor, suffixes[sidx]); CHECK(!strcmp(gold, buf)); @@ -254,7 +254,7 @@ TEST_CASE("Metric") { uintmax_t val = 1; size_t i = 0; do{ - ncmetric(val - 1, 1, buf, 0, 1000, '\0'); + ncqprefix(val - 1, 1, buf, 0); const int sidx = i ? (i - 1) / 3 : 0; snprintf(gold, sizeof(gold), "%.2f%c", ((double)(val - 1)) / vfloor, suffixes[sidx]); CHECK(!strcmp(gold, buf)); @@ -277,7 +277,7 @@ TEST_CASE("Metric") { uintmax_t val = 1; size_t i = 0; do{ - ncmetric(val + 1, 1, buf, 0, 1000, '\0'); + ncqprefix(val + 1, 1, buf, 0); const int sidx = i / 3; snprintf(gold, sizeof(gold), "%.2f%c", ((double)(val + 1)) / vfloor, suffixes[sidx]); CHECK(!strcmp(gold, buf)); @@ -300,7 +300,7 @@ TEST_CASE("Metric") { uintmax_t val = 1; size_t i = 0; do{ - ncmetric(val - 1, 1, buf, 0, 1024, 'i'); + ncbprefix(val - 1, 1, buf, 0); const int sidx = i ? (i - 1) / 3 : 0; snprintf(gold, sizeof(gold), "%.2f%ci", ((double)(val - 1)) / vfloor, suffixes[sidx]); CHECK(!strcmp(gold, buf)); diff --git a/src/tests/plane.cpp b/src/tests/plane.cpp index 5a918d848..7d0a707dd 100644 --- a/src/tests/plane.cpp +++ b/src/tests/plane.cpp @@ -1051,22 +1051,22 @@ TEST_CASE("Plane") { CHECK(x == 2); CHECK(1 == ncplane_set_base(n, " ", 0, channels)); CHECK(0 == notcurses_render(nc_)); - CHECK(0 == ncplane_moverel(n, -1, 0)); // up + CHECK(0 == ncplane_move_rel(n, -1, 0)); // up ncplane_yx(n, &y, &x); CHECK(y == 1); CHECK(x == 2); CHECK(0 == notcurses_render(nc_)); - CHECK(0 == ncplane_moverel(n, 2, 0)); // down + CHECK(0 == ncplane_move_rel(n, 2, 0)); // down ncplane_yx(n, &y, &x); CHECK(y == 3); CHECK(x == 2); CHECK(0 == notcurses_render(nc_)); - CHECK(0 == ncplane_moverel(n, 0, -1)); // left + CHECK(0 == ncplane_move_rel(n, 0, -1)); // left ncplane_yx(n, &y, &x); CHECK(y == 3); CHECK(x == 1); CHECK(0 == notcurses_render(nc_)); - CHECK(0 == ncplane_moverel(n, 0, 2)); // right + CHECK(0 == ncplane_move_rel(n, 0, 2)); // right ncplane_yx(n, &y, &x); CHECK(y == 3); CHECK(x == 3);