mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
require explicit check for pixel support
Add `notcurses_check_pixel_support()` and `ncdirect_check_pixel_support()` per #1367. Removes NCOPTION_VERIFY_SIXEL, again per #1367. Adds `free_terminfo_cache()`, and calls it from both `notcurses_stop_minimal()` and `ncdirect_stop()`. Update all documentation. Closes #1371 and #1367.
This commit is contained in:
parent
4533d42fa0
commit
6c7c9be6d2
8
NEWS.md
8
NEWS.md
@ -3,11 +3,15 @@ rearrangements of Notcurses.
|
|||||||
|
|
||||||
* 2.2.3 (not yet released)
|
* 2.2.3 (not yet released)
|
||||||
* Add `SIGILL` to the set of fatal signals we handle.
|
* Add `SIGILL` to the set of fatal signals we handle.
|
||||||
|
* Added `NCKEY_SIGNAL`. `NCKEY_RESIZE` is now an alias for `NCKEY_SIGNAL`.
|
||||||
|
* `SIGCONT` now synthesizes a `NCKEY_SIGNAL`.
|
||||||
* Add the `nctree` widget for line-oriented hierarchical data. See
|
* Add the `nctree` widget for line-oriented hierarchical data. See
|
||||||
the new `notcurses_tree(3)` man page for complete information.
|
the new `notcurses_tree(3)` man page for complete information.
|
||||||
* Implemented `NCBLIT_PIXEL` for terminals reporting Sixel support.
|
* Implemented `NCBLIT_PIXEL` for terminals reporting Sixel support.
|
||||||
Attempt Sixel detection iff `NCOPTION_VERIFY_SIXEL` is provided to
|
Added `notcurses_check_pixel_support()` and its companion
|
||||||
`notcurses_init()`. Sixel detection can delay or even block initialization.
|
`ncdirect_check_pixel_support()`, which must be called (and must return
|
||||||
|
success) before `NCBLIT_PIXEL` will be available. `NCBLIT_PIXEL` degrades
|
||||||
|
to `NCBLIT_3x2` until support is verified.
|
||||||
|
|
||||||
* 2.2.2 (2021-02-18):
|
* 2.2.2 (2021-02-18):
|
||||||
* `notcurses_stats()` no longer qualifies its `notcurses*` argument with
|
* `notcurses_stats()` no longer qualifies its `notcurses*` argument with
|
||||||
|
18
USAGE.md
18
USAGE.md
@ -89,13 +89,14 @@ typedef enum {
|
|||||||
// prior to notcurses_init(), you should not set this bit. Even if you are
|
// prior to notcurses_init(), you should not set this bit. Even if you are
|
||||||
// invoking setlocale(), this behavior shouldn't be an issue unless you're
|
// invoking setlocale(), this behavior shouldn't be an issue unless you're
|
||||||
// doing something weird (setting a locale not based on LANG).
|
// doing something weird (setting a locale not based on LANG).
|
||||||
#define NCOPTION_INHIBIT_SETLOCALE 0x0001
|
#define NCOPTION_INHIBIT_SETLOCALE 0x0001
|
||||||
|
|
||||||
// Checking for Sixel support requires writing an escape, and then reading an
|
// Checking for pixel support might require writing a control sequence, and
|
||||||
// inline reply from the terminal. Since this can interact poorly with actual
|
// then reading a reply directly from the terminal. If the terminal doesn't
|
||||||
// user input, it's not done unless Sixel will actually be used. Set this flag
|
// support this, the application will lock up. If you'll be using pixels, set
|
||||||
// to unconditionally test for Sixel support in notcurses_init().
|
// this flag to perform the check in notcurses_init(). You must otherwise call
|
||||||
#define NCOPTION_VERIFY_SIXEL 0x0002
|
// notcurses_check_pixel() before NCBLIT_PIXEL will become available.
|
||||||
|
#define NCOPTION_VERIFY_PIXEL 0x0002ull
|
||||||
|
|
||||||
// We typically install a signal handler for SIGWINCH that generates a resize
|
// We typically install a signal handler for SIGWINCH that generates a resize
|
||||||
// event in the notcurses_getc() queue. Set to inhibit this handler.
|
// event in the notcurses_getc() queue. Set to inhibit this handler.
|
||||||
@ -306,6 +307,11 @@ bool notcurses_cansextants(const struct notcurses* nc);
|
|||||||
|
|
||||||
// Can we draw Braille? The Linux console cannot.
|
// Can we draw Braille? The Linux console cannot.
|
||||||
bool notcurses_canbraille(const struct notcurses* nc);
|
bool notcurses_canbraille(const struct notcurses* nc);
|
||||||
|
|
||||||
|
// If NCOPTION_VERIFY_PIXEL was not supplied to notcurses_init(), this
|
||||||
|
// function must successfully return before NCBLIT_PIXEL is available. Returns
|
||||||
|
// -1 on error, 0 if pixel mode is not supported, or 1 if it is supported.
|
||||||
|
int notcurses_check_pixel(struct notcurses* nc);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Direct mode
|
## Direct mode
|
||||||
|
@ -72,6 +72,8 @@ notcurses_direct - minimal notcurses instances for styling text
|
|||||||
|
|
||||||
**bool ncdirect_canutf8(const struct ncdirect* ***n***);**
|
**bool ncdirect_canutf8(const struct ncdirect* ***n***);**
|
||||||
|
|
||||||
|
**int ncdirect_check_pixel_support(struct ncdirect* ***n***);**
|
||||||
|
|
||||||
**int ncdirect_hline_interp(struct ncdirect* ***n***, const char* ***egc***, int ***len***, uint64_t ***h1***, uint64_t ***h2***);**
|
**int ncdirect_hline_interp(struct ncdirect* ***n***, const char* ***egc***, int ***len***, uint64_t ***h1***, uint64_t ***h2***);**
|
||||||
|
|
||||||
**int ncdirect_vline_interp(struct ncdirect* ***n***, const char* ***egc***, int ***len***, uint64_t ***h1***, uint64_t ***h2***);**
|
**int ncdirect_vline_interp(struct ncdirect* ***n***, const char* ***egc***, int ***len***, uint64_t ***h1***, uint64_t ***h2***);**
|
||||||
@ -144,6 +146,10 @@ information, consult **readline(3)**. If you want input echoed to the
|
|||||||
terminal while using **ncdirect_readline**, **NCDIRECT_OPTION_INHIBIT_CBREAK**
|
terminal while using **ncdirect_readline**, **NCDIRECT_OPTION_INHIBIT_CBREAK**
|
||||||
must be supplied to **ncdirect_init**.
|
must be supplied to **ncdirect_init**.
|
||||||
|
|
||||||
|
**ncdirect_check_pixel_support** must be called (and successfully return)
|
||||||
|
before **NCBLIT_PIXEL** can be used to render images; see
|
||||||
|
**notcurses_visual(3)** for more details.
|
||||||
|
|
||||||
# RETURN VALUES
|
# RETURN VALUES
|
||||||
|
|
||||||
**ncdirect_init** returns **NULL** on failure. Otherwise, the return value
|
**ncdirect_init** returns **NULL** on failure. Otherwise, the return value
|
||||||
@ -153,6 +159,9 @@ to **ncdirect_stop**.
|
|||||||
**ncdirect_putstr** and **ncdirect_printf_aligned** return the number of bytes
|
**ncdirect_putstr** and **ncdirect_printf_aligned** return the number of bytes
|
||||||
written on success. On failure, they return some negative number.
|
written on success. On failure, they return some negative number.
|
||||||
|
|
||||||
|
**ncdirect_check_pixel_support** returns -1 on error, 0 if there is no pixel
|
||||||
|
support, and 1 if pixel support is successfully detected.
|
||||||
|
|
||||||
All other functions return 0 on success, and non-zero on error.
|
All other functions return 0 on success, and non-zero on error.
|
||||||
|
|
||||||
# SEE ALSO
|
# SEE ALSO
|
||||||
@ -161,5 +170,6 @@ All other functions return 0 on success, and non-zero on error.
|
|||||||
**readline(3)**
|
**readline(3)**
|
||||||
**notcurses(3)**,
|
**notcurses(3)**,
|
||||||
**notcurses_plane(3)**,
|
**notcurses_plane(3)**,
|
||||||
|
**notcurses_visual(3)**,
|
||||||
**terminfo(5)**,
|
**terminfo(5)**,
|
||||||
**termios(3)**
|
**termios(3)**
|
||||||
|
@ -12,7 +12,6 @@ notcurses_init - initialize a notcurses instance
|
|||||||
|
|
||||||
```c
|
```c
|
||||||
#define NCOPTION_INHIBIT_SETLOCALE 0x0001ull
|
#define NCOPTION_INHIBIT_SETLOCALE 0x0001ull
|
||||||
#define NCOPTION_VERIFY_SIXEL 0x0002ull
|
|
||||||
#define NCOPTION_NO_WINCH_SIGHANDLER 0x0004ull
|
#define NCOPTION_NO_WINCH_SIGHANDLER 0x0004ull
|
||||||
#define NCOPTION_NO_QUIT_SIGHANDLERS 0x0008ull
|
#define NCOPTION_NO_QUIT_SIGHANDLERS 0x0008ull
|
||||||
#define NCOPTION_SUPPRESS_BANNERS 0x0020ull
|
#define NCOPTION_SUPPRESS_BANNERS 0x0020ull
|
||||||
@ -111,12 +110,6 @@ zero. The following flags are defined:
|
|||||||
the **LANG** environment variable. Your program should call **setlocale(3)**
|
the **LANG** environment variable. Your program should call **setlocale(3)**
|
||||||
itself, usually as one of the first lines.
|
itself, usually as one of the first lines.
|
||||||
|
|
||||||
* **NCOPTION_VERIFY_SIXEL**: Checking for Sixel support requires writing an
|
|
||||||
escape, and then reading an inline reply from the terminal. Since this can
|
|
||||||
interact poorly with actual user input, it's not done unless Sixel will
|
|
||||||
actually be used. Set this flag to unconditionally test for Sixel support
|
|
||||||
in **notcurses_init**.
|
|
||||||
|
|
||||||
* **NCOPTION_NO_WINCH_SIGHANDLER**: A signal handler will usually be installed
|
* **NCOPTION_NO_WINCH_SIGHANDLER**: A signal handler will usually be installed
|
||||||
for **SIGWINCH**, resulting in **NCKEY_RESIZE** events being generated on
|
for **SIGWINCH**, resulting in **NCKEY_RESIZE** events being generated on
|
||||||
input. With this flag, the handler will not be installed.
|
input. With this flag, the handler will not be installed.
|
||||||
|
@ -92,6 +92,8 @@ typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
|
|||||||
|
|
||||||
**int ncplane_qrcode(struct ncplane* ***n***, int* ***ymax***, int* ***xmax***, const void* ***data***, size_t ***len***)**
|
**int ncplane_qrcode(struct ncplane* ***n***, int* ***ymax***, int* ***xmax***, const void* ***data***, size_t ***len***)**
|
||||||
|
|
||||||
|
**int notcurses_check_pixel_support(struct notcurses* ***nc***);**
|
||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
An **ncvisual** is a virtual pixel framebuffer. They can be created from
|
An **ncvisual** is a virtual pixel framebuffer. They can be created from
|
||||||
@ -203,6 +205,16 @@ Finally, rendering operates slightly differently when two planes have both been
|
|||||||
blitted, and one lies atop the other. See **notcurses_render(3)** for more
|
blitted, and one lies atop the other. See **notcurses_render(3)** for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
|
# PIXEL BLITTING
|
||||||
|
|
||||||
|
Some terminals support pixel-based output, either via Sixel or some bespoke
|
||||||
|
mechanism. Checking for Sixel support requires interrogating the terminal and
|
||||||
|
reading a response. This takes time, and will never complete if the terminal
|
||||||
|
doesn't respond. Before **NCBLIT_PIXEL** can be used, it is thus necessary to
|
||||||
|
check for support with **notcurses_check_pixel_support**. If this function has
|
||||||
|
not successfully returned, attempts to use **NCBLIT_PIXEL** will fall back to
|
||||||
|
**NCBLIT_3x2** (or fail, if **NCVISUAL_OPTION_NODEGRADE** is used).
|
||||||
|
|
||||||
# RETURN VALUES
|
# RETURN VALUES
|
||||||
|
|
||||||
**ncvisual_from_file** returns an **ncvisual** object on success, or **NULL**
|
**ncvisual_from_file** returns an **ncvisual** object on success, or **NULL**
|
||||||
|
@ -217,6 +217,11 @@ namespace ncpp
|
|||||||
return ncdirect_canutf8 (direct);
|
return ncdirect_canutf8 (direct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int check_pixel_support() noexcept
|
||||||
|
{
|
||||||
|
return ncdirect_check_pixel_support (direct);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ncdirect *direct;
|
ncdirect *direct;
|
||||||
};
|
};
|
||||||
|
@ -216,6 +216,11 @@ API bool ncdirect_canopen_images(const struct ncdirect* n);
|
|||||||
// Is our encoding UTF-8? Requires LANG being set to a UTF8 locale.
|
// Is our encoding UTF-8? Requires LANG being set to a UTF8 locale.
|
||||||
API bool ncdirect_canutf8(const struct ncdirect* n);
|
API bool ncdirect_canutf8(const struct ncdirect* n);
|
||||||
|
|
||||||
|
// This function must successfully return before NCBLIT_PIXEL is available.
|
||||||
|
// Returns -1 on error, 0 for no support, or 1 if pixel output is supported.
|
||||||
|
// Must not be called concurrently with either input or rasterization.
|
||||||
|
API int ncdirect_check_pixel_support(struct ncdirect* n);
|
||||||
|
|
||||||
// Draw horizontal/vertical lines using the specified channels, interpolating
|
// Draw horizontal/vertical lines using the specified channels, interpolating
|
||||||
// between them as we go. The EGC may not use more than one column. For a
|
// between them as we go. The EGC may not use more than one column. For a
|
||||||
// horizontal line, |len| cannot exceed the screen width minus the cursor's
|
// horizontal line, |len| cannot exceed the screen width minus the cursor's
|
||||||
|
@ -9,7 +9,7 @@ extern "C" {
|
|||||||
|
|
||||||
// Special composed key definitions. These values are added to 0x100000.
|
// Special composed key definitions. These values are added to 0x100000.
|
||||||
#define NCKEY_INVALID suppuabize(0)
|
#define NCKEY_INVALID suppuabize(0)
|
||||||
#define NCKEY_SIGNAL suppuabize(1) // generated internally in response to SIGWINCH / SIGCONT
|
#define NCKEY_SIGNAL suppuabize(1) // we received either SIGWINCH or SIGCONT
|
||||||
#define NCKEY_UP suppuabize(2)
|
#define NCKEY_UP suppuabize(2)
|
||||||
#define NCKEY_RIGHT suppuabize(3)
|
#define NCKEY_RIGHT suppuabize(3)
|
||||||
#define NCKEY_DOWN suppuabize(4)
|
#define NCKEY_DOWN suppuabize(4)
|
||||||
|
@ -826,11 +826,7 @@ typedef enum {
|
|||||||
// doing something weird (setting a locale not based on LANG).
|
// doing something weird (setting a locale not based on LANG).
|
||||||
#define NCOPTION_INHIBIT_SETLOCALE 0x0001ull
|
#define NCOPTION_INHIBIT_SETLOCALE 0x0001ull
|
||||||
|
|
||||||
// Checking for Sixel support requires writing an escape, and then reading an
|
// NCOPTION_VERIFY_PIXEL was removed in 2.2.3. It ought be repurposed. FIXME.
|
||||||
// inline reply from the terminal. Since this can interact poorly with actual
|
|
||||||
// user input, it's not done unless Sixel will actually be used. Set this flag
|
|
||||||
// to unconditionally test for Sixel support in notcurses_init().
|
|
||||||
#define NCOPTION_VERIFY_SIXEL 0x0002ull
|
|
||||||
|
|
||||||
// We typically install a signal handler for SIGWINCH that generates a resize
|
// We typically install a signal handler for SIGWINCH that generates a resize
|
||||||
// event in the notcurses_getc() queue. Set to inhibit this handler.
|
// event in the notcurses_getc() queue. Set to inhibit this handler.
|
||||||
@ -1237,6 +1233,11 @@ API bool notcurses_canbraille(const struct notcurses* nc);
|
|||||||
// Can we blit to pixel graphics?
|
// Can we blit to pixel graphics?
|
||||||
API bool notcurses_canpixel(const struct notcurses* nc);
|
API bool notcurses_canpixel(const struct notcurses* nc);
|
||||||
|
|
||||||
|
// This function must successfully return before NCBLIT_PIXEL is available.
|
||||||
|
// Returns -1 on error, 0 for no support, or 1 if pixel output is supported.
|
||||||
|
// Must not be called concurrently with either input or rasterization.
|
||||||
|
API int notcurses_check_pixel_support(struct notcurses* nc);
|
||||||
|
|
||||||
typedef struct ncstats {
|
typedef struct ncstats {
|
||||||
// purely increasing stats
|
// purely increasing stats
|
||||||
uint64_t renders; // successful ncpile_render() runs
|
uint64_t renders; // successful ncpile_render() runs
|
||||||
|
@ -637,6 +637,7 @@ ncdirect_stop_minimal(void* vnc){
|
|||||||
ret |= close(nc->ctermfd);
|
ret |= close(nc->ctermfd);
|
||||||
}
|
}
|
||||||
ret |= ncdirect_flush(nc);
|
ret |= ncdirect_flush(nc);
|
||||||
|
free_terminfo_cache(&nc->tcache);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1102,3 +1103,13 @@ int ncdirect_flush(const ncdirect* nc){
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ncdirect_check_pixel_support(ncdirect* n){
|
||||||
|
if(query_term(&n->tcache, n->ctermfd)){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(n->tcache.pixelon){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -286,11 +286,12 @@ typedef struct tinfo {
|
|||||||
// background_opaque is in use. detect this, and avoid the default if so.
|
// background_opaque is in use. detect this, and avoid the default if so.
|
||||||
// bg_collides_default is either 0x0000000 or 0x1RRGGBB.
|
// bg_collides_default is either 0x0000000 or 0x1RRGGBB.
|
||||||
uint32_t bg_collides_default;
|
uint32_t bg_collides_default;
|
||||||
bool sextants; // do we have (good, vetted) Unicode 13 sextant support?
|
pthread_mutex_t pixel_query; // only query for pixel support once
|
||||||
bool braille; // do we have Braille support? (linux console does not)
|
|
||||||
char* pixelon; // enter pixel graphics mode
|
char* pixelon; // enter pixel graphics mode
|
||||||
char* pixeloff; // leave pixel graphics mode
|
char* pixeloff; // leave pixel graphics mode
|
||||||
bool sixel; // do we have Sixel support?
|
bool pixel_query_done; // have we yet performed pixel query?
|
||||||
|
bool sextants; // do we have (good, vetted) Unicode 13 sextant support?
|
||||||
|
bool braille; // do we have Braille support? (linux console does not)
|
||||||
} tinfo;
|
} tinfo;
|
||||||
|
|
||||||
typedef struct ncinputlayer {
|
typedef struct ncinputlayer {
|
||||||
@ -386,6 +387,8 @@ int terminfostr(char** gseq, const char* name);
|
|||||||
// initialized. set |utf8| if we've verified UTF8 output encoding.
|
// initialized. set |utf8| if we've verified UTF8 output encoding.
|
||||||
int interrogate_terminfo(tinfo* ti, const char* termname, unsigned utf8);
|
int interrogate_terminfo(tinfo* ti, const char* termname, unsigned utf8);
|
||||||
|
|
||||||
|
void free_terminfo_cache(tinfo* ti);
|
||||||
|
|
||||||
// perform queries that require writing to the terminal, and reading a
|
// perform queries that require writing to the terminal, and reading a
|
||||||
// response, rather than simply reading the terminfo database. can result
|
// response, rather than simply reading the terminfo database. can result
|
||||||
// in a lengthy delay or even block if the terminal doesn't respond.
|
// in a lengthy delay or even block if the terminal doesn't respond.
|
||||||
|
@ -777,14 +777,13 @@ init_banner(const notcurses* nc){
|
|||||||
term_fg_palindex(nc, stdout, nc->tcache.colors <= 256 ? 50 % nc->tcache.colors : 0x20e080);
|
term_fg_palindex(nc, stdout, nc->tcache.colors <= 256 ? 50 % nc->tcache.colors : 0x20e080);
|
||||||
printf("\n notcurses %s by nick black et al", notcurses_version());
|
printf("\n notcurses %s by nick black et al", notcurses_version());
|
||||||
term_fg_palindex(nc, stdout, nc->tcache.colors <= 256 ? 12 % nc->tcache.colors : 0x2080e0);
|
term_fg_palindex(nc, stdout, nc->tcache.colors <= 256 ? 12 % nc->tcache.colors : 0x2080e0);
|
||||||
printf("\n %d rows %d cols (%sB) %zuB cells %d colors%s%s\n"
|
printf("\n %d rows %d cols (%sB) %zuB cells %d colors%s\n"
|
||||||
" compiled with gcc-%s, %s-endian\n"
|
" compiled with gcc-%s, %s-endian\n"
|
||||||
" terminfo from %s\n",
|
" terminfo from %s\n",
|
||||||
nc->stdplane->leny, nc->stdplane->lenx,
|
nc->stdplane->leny, nc->stdplane->lenx,
|
||||||
bprefix(nc->stats.fbbytes, 1, prefixbuf, 0), sizeof(nccell),
|
bprefix(nc->stats.fbbytes, 1, prefixbuf, 0), sizeof(nccell),
|
||||||
nc->tcache.colors,
|
nc->tcache.colors,
|
||||||
nc->tcache.RGBflag ? "+RGB" : "",
|
nc->tcache.RGBflag ? "+RGB" : "",
|
||||||
nc->tcache.sixel ? "+Sixel" : "",
|
|
||||||
__VERSION__,
|
__VERSION__,
|
||||||
#ifdef __BYTE_ORDER__
|
#ifdef __BYTE_ORDER__
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
@ -908,6 +907,16 @@ recursive_lock_init(pthread_mutex_t *lock){
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int notcurses_check_pixel_support(notcurses* nc){
|
||||||
|
if(query_term(&nc->tcache, nc->ttyfd)){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(nc->tcache.pixelon){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME cut this up into a few distinct pieces, yearrrgh
|
// FIXME cut this up into a few distinct pieces, yearrrgh
|
||||||
notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){
|
notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){
|
||||||
notcurses_options defaultopts;
|
notcurses_options defaultopts;
|
||||||
@ -1033,12 +1042,6 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if(ret->ttyfd >= 0){
|
if(ret->ttyfd >= 0){
|
||||||
if(opts->flags & NCOPTION_VERIFY_SIXEL){
|
|
||||||
if(query_term(&ret->tcache, ret->ttyfd)){
|
|
||||||
free_plane(ret->stdplane);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(ret->tcache.smkx && tty_emit(ret->tcache.smkx, ret->ttyfd)){
|
if(ret->tcache.smkx && tty_emit(ret->tcache.smkx, ret->ttyfd)){
|
||||||
free_plane(ret->stdplane);
|
free_plane(ret->stdplane);
|
||||||
goto err;
|
goto err;
|
||||||
@ -1215,6 +1218,7 @@ int notcurses_stop(notcurses* nc){
|
|||||||
del_curterm(cur_term);
|
del_curterm(cur_term);
|
||||||
ret |= pthread_mutex_destroy(&nc->statlock);
|
ret |= pthread_mutex_destroy(&nc->statlock);
|
||||||
ret |= pthread_mutex_destroy(&nc->pilelock);
|
ret |= pthread_mutex_destroy(&nc->pilelock);
|
||||||
|
free_terminfo_cache(&nc->tcache);
|
||||||
free(nc);
|
free(nc);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -2073,7 +2077,7 @@ bool notcurses_canchangecolor(const notcurses* nc){
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool notcurses_canpixel(const notcurses* nc){
|
bool notcurses_canpixel(const notcurses* nc){
|
||||||
return nc->tcache.sixel;
|
return nc->tcache.pixelon;
|
||||||
}
|
}
|
||||||
|
|
||||||
palette256* palette256_new(notcurses* nc){
|
palette256* palette256_new(notcurses* nc){
|
||||||
|
@ -71,6 +71,10 @@ apply_term_heuristics(tinfo* ti, const char* termname){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_terminfo_cache(tinfo* ti){
|
||||||
|
pthread_mutex_destroy(&ti->pixel_query);
|
||||||
|
}
|
||||||
|
|
||||||
// termname is just the TERM environment variable. some details are not
|
// termname is just the TERM environment variable. some details are not
|
||||||
// exposed via terminfo, and we must make heuristic decisions based on
|
// exposed via terminfo, and we must make heuristic decisions based on
|
||||||
// the detected terminal type, yuck :/.
|
// the detected terminal type, yuck :/.
|
||||||
@ -184,6 +188,8 @@ int interrogate_terminfo(tinfo* ti, const char* termname, unsigned utf8){
|
|||||||
ti->fgop = "\x1b[39m";
|
ti->fgop = "\x1b[39m";
|
||||||
ti->bgop = "\x1b[49m";
|
ti->bgop = "\x1b[49m";
|
||||||
}
|
}
|
||||||
|
pthread_mutex_init(&ti->pixel_query, NULL);
|
||||||
|
ti->pixel_query_done = false;
|
||||||
if(apply_term_heuristics(ti, termname)){
|
if(apply_term_heuristics(ti, termname)){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -229,8 +235,8 @@ query_sixel(tinfo* ti, int fd){
|
|||||||
state = DONE;
|
state = DONE;
|
||||||
}else if(in == '4'){
|
}else if(in == '4'){
|
||||||
if(!ti->pixelon){
|
if(!ti->pixelon){
|
||||||
ti->pixelon = strdup("\ePq");
|
ti->pixelon = "\ePq";
|
||||||
ti->pixeloff = strdup("\e\\");
|
ti->pixeloff = "\e\\";
|
||||||
} // FIXME else warning?
|
} // FIXME else warning?
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -245,10 +251,18 @@ query_sixel(tinfo* ti, int fd){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fd must be a real terminal, and must not be in nonblocking mode
|
// fd must be a real terminal, and must not be in nonblocking mode. uses the
|
||||||
|
// pthread_mutex_t of |ti| to only act once.
|
||||||
int query_term(tinfo* ti, int fd){
|
int query_term(tinfo* ti, int fd){
|
||||||
if(query_sixel(ti, fd)){
|
if(fd < 0){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
int ret = 0;
|
||||||
|
pthread_mutex_lock(&ti->pixel_query);
|
||||||
|
if(!ti->pixel_query_done){
|
||||||
|
ret = query_sixel(ti, fd);
|
||||||
|
ti->pixel_query_done = true;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&ti->pixel_query);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +143,9 @@ auto perframe(struct ncvisual* ncv, struct ncvisual_options* vopts,
|
|||||||
}else if(keyp >= '0' && keyp <= '8'){ // FIXME eliminate ctrl/alt
|
}else if(keyp >= '0' && keyp <= '8'){ // FIXME eliminate ctrl/alt
|
||||||
marsh->blitter = static_cast<ncblitter_e>(keyp - '0');
|
marsh->blitter = static_cast<ncblitter_e>(keyp - '0');
|
||||||
vopts->blitter = marsh->blitter;
|
vopts->blitter = marsh->blitter;
|
||||||
|
if(vopts->blitter == NCBLIT_PIXEL){
|
||||||
|
notcurses_check_pixel_support(nc);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}else if(keyp == NCKey::Up){
|
}else if(keyp == NCKey::Up){
|
||||||
// FIXME
|
// FIXME
|
||||||
@ -280,6 +283,9 @@ int direct_mode_player(int argc, char** argv, ncscale_e scalemode, ncblitter_e b
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
|
if(blitter == NCBLIT_PIXEL){
|
||||||
|
dm.check_pixel_support();
|
||||||
|
}
|
||||||
{
|
{
|
||||||
for(auto i = 0 ; i < argc ; ++i){
|
for(auto i = 0 ; i < argc ; ++i){
|
||||||
try{
|
try{
|
||||||
@ -303,7 +309,6 @@ auto main(int argc, char** argv) -> int {
|
|||||||
float timescale, displaytime;
|
float timescale, displaytime;
|
||||||
ncscale_e scalemode;
|
ncscale_e scalemode;
|
||||||
notcurses_options ncopts{};
|
notcurses_options ncopts{};
|
||||||
ncopts.flags = NCOPTION_VERIFY_SIXEL;
|
|
||||||
ncblitter_e blitter = NCBLIT_PIXEL;
|
ncblitter_e blitter = NCBLIT_PIXEL;
|
||||||
bool quiet = false;
|
bool quiet = false;
|
||||||
bool loop = false;
|
bool loop = false;
|
||||||
@ -348,6 +353,9 @@ auto main(int argc, char** argv) -> int {
|
|||||||
vopts.n = *stdn;
|
vopts.n = *stdn;
|
||||||
vopts.scaling = scalemode;
|
vopts.scaling = scalemode;
|
||||||
vopts.blitter = blitter;
|
vopts.blitter = blitter;
|
||||||
|
if(vopts.blitter == NCBLIT_PIXEL){
|
||||||
|
notcurses_check_pixel_support(nc);
|
||||||
|
}
|
||||||
do{
|
do{
|
||||||
struct marshal marsh = {
|
struct marshal marsh = {
|
||||||
.subtitle_plane = nullptr,
|
.subtitle_plane = nullptr,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user