mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
input thread #2136
This commit is contained in:
parent
c286c01d16
commit
3cf5a67b84
8
NEWS.md
8
NEWS.md
@ -5,6 +5,14 @@ rearrangements of Notcurses.
|
|||||||
* `notcurses_check_pixel_support()` still returns 0 if there is no support
|
* `notcurses_check_pixel_support()` still returns 0 if there is no support
|
||||||
for bitmap graphics, but now returns an `ncpixelimple_e` to differentiate
|
for bitmap graphics, but now returns an `ncpixelimple_e` to differentiate
|
||||||
the pixel backend otherwise. This result is strictly informative.
|
the pixel backend otherwise. This result is strictly informative.
|
||||||
|
* Added `NCOPTION_DRAIN_INPUT`. Notcurses now launches a thread to process
|
||||||
|
input, so that it can respond to terminal messages with minimal latency.
|
||||||
|
Input read from `stdin` intended for the client is buffered until
|
||||||
|
retrieved. If your client never intends to read this input, provide this
|
||||||
|
flag to eliminate unnecessary processing, and ensure Notcurses can always
|
||||||
|
retrieve terminal messages (if buffers are full, Notcurses cannot
|
||||||
|
continue reading). Likewise added `NCDIRECT_OPTION_DRAIN_INPUT`.
|
||||||
|
* Removed a bunch of deprecated `static inline` functions from the headers.
|
||||||
|
|
||||||
* 2.4.0 (2021-09-06)
|
* 2.4.0 (2021-09-06)
|
||||||
* Mouse events in the Linux console are now reported from GPM when built
|
* Mouse events in the Linux console are now reported from GPM when built
|
||||||
|
19
README.md
19
README.md
@ -248,6 +248,25 @@ If things break or seem otherwise lackluster, **please** consult the
|
|||||||
more importantly, it will link against minimal Notcurses installations.
|
more importantly, it will link against minimal Notcurses installations.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Does it work with hardware terminals?</summary>
|
||||||
|
With the correct `TERM` value, many hardware terminals are supported. The VT100
|
||||||
|
is sadly unsupported due to its extensive need for delays. In general, if the
|
||||||
|
terminfo database entry indicates mandatory delays, Notcurses will not currently
|
||||||
|
support that terminal properly. It's known that Notcurses can drive the VT320
|
||||||
|
and VT340, including Sixel graphics on the latter.
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>What happens if I try blitting bitmap graphics on a terminal which
|
||||||
|
doesn't support them?</summary>
|
||||||
|
Notcurses will not make use of bitmap protocols unless the terminal positively
|
||||||
|
indicates support for them, even if `NCBLIT_PIXEL` has been requested. Likewise,
|
||||||
|
sextants (`NCBLIT_3x2`) won't be used without Unicode 13 support, etc.
|
||||||
|
`ncvisual_render()` will use the best blitter available, unless
|
||||||
|
`NCVISUAL_OPTION_NODEGRADE` is provided (in which case it will fail).
|
||||||
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Notcurses looks like absolute crap in <code>screen</code>.</summary>
|
<summary>Notcurses looks like absolute crap in <code>screen</code>.</summary>
|
||||||
<code>screen</code> doesn't support RGB colors (at least as of 4.08.00);
|
<code>screen</code> doesn't support RGB colors (at least as of 4.08.00);
|
||||||
|
34
USAGE.md
34
USAGE.md
@ -95,7 +95,7 @@ typedef enum {
|
|||||||
// to do this, pass NCOPTION_NO_CLEAR_BITMAPS. Note that they might still
|
// to do this, pass NCOPTION_NO_CLEAR_BITMAPS. Note that they might still
|
||||||
// get cleared even if this is set, and they might not get cleared even if
|
// get cleared even if this is set, and they might not get cleared even if
|
||||||
// this is not set. It's a tough world out there.
|
// this is not set. It's a tough world out there.
|
||||||
#define NCOPTION_NO_CLEAR_BITMAPS 0x0002ull
|
#define NCOPTION_NO_CLEAR_BITMAPS 0x0002
|
||||||
|
|
||||||
// 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_get() queue. Set to inhibit this handler.
|
// event in the notcurses_get() queue. Set to inhibit this handler.
|
||||||
@ -110,7 +110,7 @@ typedef enum {
|
|||||||
// at context creation time. Together with NCOPTION_NO_ALTERNATE_SCREEN and a
|
// at context creation time. Together with NCOPTION_NO_ALTERNATE_SCREEN and a
|
||||||
// scrolling standard plane, this facilitates easy scrolling-style programs in
|
// scrolling standard plane, this facilitates easy scrolling-style programs in
|
||||||
// rendered mode.
|
// rendered mode.
|
||||||
#define NCOPTION_PRESERVE_CURSOR 0x0010ull
|
#define NCOPTION_PRESERVE_CURSOR 0x0010
|
||||||
|
|
||||||
// Notcurses typically prints version info in notcurses_init() and performance
|
// Notcurses typically prints version info in notcurses_init() and performance
|
||||||
// info in notcurses_stop(). This inhibits that output.
|
// info in notcurses_stop(). This inhibits that output.
|
||||||
@ -120,6 +120,17 @@ typedef enum {
|
|||||||
// of the "alternate screen". This flag inhibits use of smcup/rmcup.
|
// of the "alternate screen". This flag inhibits use of smcup/rmcup.
|
||||||
#define NCOPTION_NO_ALTERNATE_SCREEN 0x0040
|
#define NCOPTION_NO_ALTERNATE_SCREEN 0x0040
|
||||||
|
|
||||||
|
// Do not modify the font. Notcurses might attempt to change the font slightly,
|
||||||
|
// to support certain glyphs (especially on the Linux console). If this is set,
|
||||||
|
// no such modifications will be made. Note that font changes will not affect
|
||||||
|
// anything but the virtual console/terminal in which Notcurses is running.
|
||||||
|
#define NCOPTION_NO_FONT_CHANGES 0x0080
|
||||||
|
|
||||||
|
// Input may be freely dropped. This ought be provided when the program does not
|
||||||
|
// intend to handle input. Otherwise, input can accumulate in internal buffers,
|
||||||
|
// eventually preventing Notcurses from processing terminal messages.
|
||||||
|
#define NCOPTION_DRAIN_INPUT 0x0100
|
||||||
|
|
||||||
// Configuration for notcurses_init().
|
// Configuration for notcurses_init().
|
||||||
typedef struct notcurses_options {
|
typedef struct notcurses_options {
|
||||||
// The name of the terminfo database entry describing this terminal. If NULL,
|
// The name of the terminfo database entry describing this terminal. If NULL,
|
||||||
@ -378,11 +389,23 @@ struct ncdirect* ncdirect_core_init(const char* termtype, FILE* fp, uint64_t fla
|
|||||||
// echo and line buffering are turned off.
|
// echo and line buffering are turned off.
|
||||||
#define NCDIRECT_OPTION_INHIBIT_CBREAK 0x0002ull
|
#define NCDIRECT_OPTION_INHIBIT_CBREAK 0x0002ull
|
||||||
|
|
||||||
|
// Input may be freely dropped. This ought be provided when the program does not
|
||||||
|
// intend to handle input. Otherwise, input can accumulate in internal buffers,
|
||||||
|
// eventually preventing Notcurses from processing terminal messages.
|
||||||
|
#define NCDIRECT_OPTION_DRAIN_INPUT 0x0004ull
|
||||||
|
|
||||||
// We typically install a signal handler for SIG{INT, SEGV, ABRT, QUIT} that
|
// We typically install a signal handler for SIG{INT, SEGV, ABRT, QUIT} that
|
||||||
// restores the screen, and then calls the old signal handler. Set to inhibit
|
// restores the screen, and then calls the old signal handler. Set to inhibit
|
||||||
// registration of these signal handlers. Chosen to match fullscreen mode.
|
// registration of these signal handlers. Chosen to match fullscreen mode.
|
||||||
#define NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS 0x0008ull
|
#define NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS 0x0008ull
|
||||||
|
|
||||||
|
// Enable logging (to stderr) at the NCLOGLEVEL_WARNING level.
|
||||||
|
#define NCDIRECT_OPTION_VERBOSE 0x0010ull
|
||||||
|
|
||||||
|
// Enable logging (to stderr) at the NCLOGLEVEL_TRACE level. This will enable
|
||||||
|
// all diagnostics, a superset of NCDIRECT_OPTION_VERBOSE (which this implies).
|
||||||
|
#define NCDIRECT_OPTION_VERY_VERBOSE 0x0020ull
|
||||||
|
|
||||||
// Release 'nc' and any associated resources. 0 on success, non-0 on failure.
|
// Release 'nc' and any associated resources. 0 on success, non-0 on failure.
|
||||||
int ncdirect_stop(struct ncdirect* nc);
|
int ncdirect_stop(struct ncdirect* nc);
|
||||||
```
|
```
|
||||||
@ -671,7 +694,12 @@ typedef struct ncinput {
|
|||||||
// event is processed, the return value is the 'id' field from that event.
|
// event is processed, the return value is the 'id' field from that event.
|
||||||
// 'ni' may be NULL.
|
// 'ni' may be NULL.
|
||||||
uint32_t notcurses_get(struct notcurses* n, const struct timespec* ts,
|
uint32_t notcurses_get(struct notcurses* n, const struct timespec* ts,
|
||||||
ncinput* ni)
|
ncinput* ni);
|
||||||
|
|
||||||
|
// Acquire up to 'vcount' ncinputs at the vector 'ni'. The number read will be
|
||||||
|
// returned, or -1 on error without any reads, 0 on timeout.
|
||||||
|
int notcurses_getvec(struct notcurses* n, const struct timespec* ts,
|
||||||
|
ncinput* ni, int vcount);
|
||||||
|
|
||||||
// 'ni' may be NULL if the caller is uninterested in event details. If no event
|
// 'ni' may be NULL if the caller is uninterested in event details. If no event
|
||||||
// is ready, returns 0.
|
// is ready, returns 0.
|
||||||
|
@ -169,6 +169,11 @@ The following flags are defined:
|
|||||||
will place the terminal into cbreak mode (i.e. disabling echo and line
|
will place the terminal into cbreak mode (i.e. disabling echo and line
|
||||||
buffering; see **tcgetattr(3)**).
|
buffering; see **tcgetattr(3)**).
|
||||||
|
|
||||||
|
* **NCDIRECT_OPTION_DRAIN_INPUT**: Standard input may be freely discarded. If
|
||||||
|
you do not intend to process input, pass this flag. Otherwise, input can
|
||||||
|
buffer up, eventually preventing Notcurses from processing terminal
|
||||||
|
messages. It will furthermore avoid wasting time processing useless input.
|
||||||
|
|
||||||
* **NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS**: A signal handler will usually be installed
|
* **NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS**: A signal handler will usually be installed
|
||||||
for **SIGABRT**, **SIGFPE**, **SIGILL**, **SIGINT**, **SIGQUIT**,
|
for **SIGABRT**, **SIGFPE**, **SIGILL**, **SIGINT**, **SIGQUIT**,
|
||||||
**SIGSEGV**, and **SIGTERM**, cleaning up the terminal on such exceptions.
|
**SIGSEGV**, and **SIGTERM**, cleaning up the terminal on such exceptions.
|
||||||
|
@ -19,6 +19,7 @@ notcurses_init - initialize a notcurses instance
|
|||||||
#define NCOPTION_SUPPRESS_BANNERS 0x0020ull
|
#define NCOPTION_SUPPRESS_BANNERS 0x0020ull
|
||||||
#define NCOPTION_NO_ALTERNATE_SCREEN 0x0040ull
|
#define NCOPTION_NO_ALTERNATE_SCREEN 0x0040ull
|
||||||
#define NCOPTION_NO_FONT_CHANGES 0x0080ull
|
#define NCOPTION_NO_FONT_CHANGES 0x0080ull
|
||||||
|
#define NCOPTION_DRAIN_INPUT 0x0100ull
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NCLOGLEVEL_SILENT, // print nothing once fullscreen service begins
|
NCLOGLEVEL_SILENT, // print nothing once fullscreen service begins
|
||||||
@ -139,6 +140,11 @@ zero. The following flags are defined:
|
|||||||
* **NCOPTION_NO_FONT_CHANGES**: Do not touch the font. Notcurses might
|
* **NCOPTION_NO_FONT_CHANGES**: Do not touch the font. Notcurses might
|
||||||
otherwise attempt to extend the font, especially in the Linux console.
|
otherwise attempt to extend the font, especially in the Linux console.
|
||||||
|
|
||||||
|
* **NCOPTION_DRAIN_INPUT**: Standard input may be freely discarded. If you do not
|
||||||
|
intend to process input, pass this flag. Otherwise, input can buffer up, and
|
||||||
|
eventually prevent Notcurses from processing messages from the terminal. It
|
||||||
|
will furthermore avoid wasting time processing useless input.
|
||||||
|
|
||||||
## Fatal signals
|
## Fatal signals
|
||||||
|
|
||||||
It is important to reset the terminal before exiting, whether terminating due
|
It is important to reset the terminal before exiting, whether terminating due
|
||||||
|
@ -31,6 +31,8 @@ typedef struct ncinput {
|
|||||||
|
|
||||||
**uint32_t notcurses_get(struct notcurses* ***n***, const struct timespec* ***ts***, ncinput* ***ni***);**
|
**uint32_t notcurses_get(struct notcurses* ***n***, const struct timespec* ***ts***, ncinput* ***ni***);**
|
||||||
|
|
||||||
|
**int notcurses_getvec(struct notcurses* ***n***, const struct timespec* ***ts***, ncinput* ***ni***, int vcount);**
|
||||||
|
|
||||||
**uint32_t notcurses_getc_nblock(struct notcurses* ***n***, ncinput* ***ni***);**
|
**uint32_t notcurses_getc_nblock(struct notcurses* ***n***, ncinput* ***ni***);**
|
||||||
|
|
||||||
**uint32_t notcurses_getc_blocking(struct notcurses* ***n***, ncinput* ***ni***);**
|
**uint32_t notcurses_getc_blocking(struct notcurses* ***n***, ncinput* ***ni***);**
|
||||||
@ -128,6 +130,10 @@ temporary one (especially e.g. **EINTR**), **notcurses_get** probably cannot
|
|||||||
be usefully called forthwith. On a timeout, 0 is returned. Otherwise, the
|
be usefully called forthwith. On a timeout, 0 is returned. Otherwise, the
|
||||||
UCS-32 value of a Unicode codepoint, or a synthesized event, is returned.
|
UCS-32 value of a Unicode codepoint, or a synthesized event, is returned.
|
||||||
|
|
||||||
|
If an error is encountered before **notcurses_getvec** has read any input,
|
||||||
|
it will return -1. If it times out before reading any input, it will return
|
||||||
|
0. Otherwise, it returns the number of **ncinput** objects written back.
|
||||||
|
|
||||||
**notcurses_mouse_enable** returns 0 on success, and non-zero on failure, as
|
**notcurses_mouse_enable** returns 0 on success, and non-zero on failure, as
|
||||||
does **notcurses_mouse_disable**.
|
does **notcurses_mouse_disable**.
|
||||||
|
|
||||||
|
@ -24,6 +24,11 @@ extern "C" {
|
|||||||
// echo and input's line buffering are turned off.
|
// echo and input's line buffering are turned off.
|
||||||
#define NCDIRECT_OPTION_INHIBIT_CBREAK 0x0002ull
|
#define NCDIRECT_OPTION_INHIBIT_CBREAK 0x0002ull
|
||||||
|
|
||||||
|
// Input may be freely dropped. This ought be provided when the program does not
|
||||||
|
// intend to handle input. Otherwise, input can accumulate in internal buffers,
|
||||||
|
// eventually preventing Notcurses from processing terminal messages.
|
||||||
|
#define NCDIRECT_OPTION_DRAIN_INPUT 0x0004ull
|
||||||
|
|
||||||
// We typically install a signal handler for SIG{INT, SEGV, ABRT, QUIT} that
|
// We typically install a signal handler for SIG{INT, SEGV, ABRT, QUIT} that
|
||||||
// restores the screen, and then calls the old signal handler. Set to inhibit
|
// restores the screen, and then calls the old signal handler. Set to inhibit
|
||||||
// registration of these signal handlers. Chosen to match fullscreen mode.
|
// registration of these signal handlers. Chosen to match fullscreen mode.
|
||||||
@ -489,11 +494,6 @@ ncdirect_canbraille(const struct ncdirect* nc){
|
|||||||
API bool ncdirect_canget_cursor(const struct ncdirect* nc)
|
API bool ncdirect_canget_cursor(const struct ncdirect* nc)
|
||||||
__attribute__ ((nonnull (1)));
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Deprecated, to be removed for ABI3. Use ncdirect_get() in new code.
|
|
||||||
API uint32_t ncdirect_getc(struct ncdirect* n, const struct timespec* ts,
|
|
||||||
const void* unused, ncinput* ni)
|
|
||||||
__attribute__ ((deprecated)) __attribute__ ((nonnull (1)));
|
|
||||||
|
|
||||||
#undef ALLOC
|
#undef ALLOC
|
||||||
#undef API
|
#undef API
|
||||||
|
|
||||||
|
@ -900,6 +900,11 @@ typedef enum {
|
|||||||
// anything but the virtual console/terminal in which Notcurses is running.
|
// anything but the virtual console/terminal in which Notcurses is running.
|
||||||
#define NCOPTION_NO_FONT_CHANGES 0x0080ull
|
#define NCOPTION_NO_FONT_CHANGES 0x0080ull
|
||||||
|
|
||||||
|
// Input may be freely dropped. This ought be provided when the program does not
|
||||||
|
// intend to handle input. Otherwise, input can accumulate in internal buffers,
|
||||||
|
// eventually preventing Notcurses from processing terminal messages.
|
||||||
|
#define NCOPTION_DRAIN_INPUT 0x0100ull
|
||||||
|
|
||||||
// Configuration for notcurses_init().
|
// Configuration for notcurses_init().
|
||||||
typedef struct notcurses_options {
|
typedef struct notcurses_options {
|
||||||
// The name of the terminfo database entry describing this terminal. If NULL,
|
// The name of the terminfo database entry describing this terminal. If NULL,
|
||||||
@ -1066,6 +1071,12 @@ API uint32_t notcurses_get(struct notcurses* n, const struct timespec* ts,
|
|||||||
ncinput* ni)
|
ncinput* ni)
|
||||||
__attribute__ ((nonnull (1)));
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
|
// Acquire up to 'vcount' ncinputs at the vector 'ni'. The number read will be
|
||||||
|
// returned, or -1 on error without any reads, 0 on timeout.
|
||||||
|
API int notcurses_getvec(struct notcurses* n, const struct timespec* ts,
|
||||||
|
ncinput* ni, int vcount)
|
||||||
|
__attribute__ ((nonnull (1, 3)));
|
||||||
|
|
||||||
// Get a file descriptor suitable for input event poll()ing. When this
|
// Get a file descriptor suitable for input event poll()ing. When this
|
||||||
// descriptor becomes available, you can call notcurses_getc_nblock(),
|
// descriptor becomes available, you can call notcurses_getc_nblock(),
|
||||||
// and input ought be ready. This file descriptor is *not* necessarily
|
// and input ought be ready. This file descriptor is *not* necessarily
|
||||||
@ -4244,233 +4255,6 @@ palette256_get_rgb8(const ncpalette* p, int idx, unsigned* RESTRICT r, unsigned*
|
|||||||
|
|
||||||
API void palette256_free(ncpalette* p) __attribute__ ((deprecated));
|
API void palette256_free(ncpalette* p) __attribute__ ((deprecated));
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channel_r(uint32_t channel){
|
|
||||||
return ncchannel_r(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract the 8-bit green component from a 32-bit channel.
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channel_g(uint32_t channel){
|
|
||||||
return ncchannel_g(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract the 8-bit blue component from a 32-bit channel.
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channel_b(uint32_t channel){
|
|
||||||
return ncchannel_b(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract the three 8-bit R/G/B components from a 32-bit channel.
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channel_rgb8(uint32_t channel, unsigned* RESTRICT r, unsigned* RESTRICT g,
|
|
||||||
unsigned* RESTRICT b){
|
|
||||||
return ncchannel_rgb8(channel, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the three 8-bit components of a 32-bit channel, and mark it as not using
|
|
||||||
// the default color. Retain the other bits unchanged.
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channel_set_rgb8(uint32_t* channel, int r, int g, int b){
|
|
||||||
return ncchannel_set_rgb8(channel, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the three 8-bit components of a 32-bit channel, and mark it as not using
|
|
||||||
// the default color. Retain the other bits unchanged. r, g, and b will be
|
|
||||||
// clipped to the range [0..255].
|
|
||||||
__attribute__ ((deprecated)) static inline void
|
|
||||||
channel_set_rgb8_clipped(unsigned* channel, int r, int g, int b){
|
|
||||||
return ncchannel_set_rgb8_clipped(channel, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same, but provide an assembled, packed 24 bits of rgb.
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channel_set(unsigned* channel, unsigned rgb){
|
|
||||||
return ncchannel_set(channel, rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract the 2-bit alpha component from a 32-bit channel.
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channel_alpha(unsigned channel){
|
|
||||||
return ncchannel_alpha(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channel_palindex(uint32_t channel){
|
|
||||||
return ncchannel_palindex(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the 2-bit alpha component of the 32-bit channel.
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channel_set_alpha(unsigned* channel, unsigned alpha){
|
|
||||||
return ncchannel_set_alpha(channel, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channel_set_palindex(uint32_t* channel, int idx){
|
|
||||||
return ncchannel_set_palindex(channel, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline bool
|
|
||||||
channel_default_p(unsigned channel){
|
|
||||||
return ncchannel_default_p(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline bool
|
|
||||||
channel_palindex_p(unsigned channel){
|
|
||||||
return ncchannel_palindex_p(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channel_set_default(unsigned* channel){
|
|
||||||
return ncchannel_set_default(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline uint32_t
|
|
||||||
channels_bchannel(uint64_t channels){
|
|
||||||
return ncchannels_bchannel(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline uint32_t
|
|
||||||
channels_fchannel(uint64_t channels){
|
|
||||||
return ncchannels_fchannel(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline uint64_t
|
|
||||||
channels_set_bchannel(uint64_t* channels, uint32_t channel){
|
|
||||||
return ncchannels_set_bchannel(channels, channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline uint64_t
|
|
||||||
channels_set_fchannel(uint64_t* channels, uint32_t channel){
|
|
||||||
return ncchannels_set_fchannel(channels, channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline uint64_t
|
|
||||||
channels_combine(uint32_t fchan, uint32_t bchan){
|
|
||||||
return ncchannels_combine(fchan, bchan);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channels_fg_palindex(uint64_t channels){
|
|
||||||
return ncchannels_fg_palindex(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channels_bg_palindex(uint64_t channels){
|
|
||||||
return ncchannels_bg_palindex(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channels_fg_rgb(uint64_t channels){
|
|
||||||
return ncchannels_fg_rgb(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channels_bg_rgb(uint64_t channels){
|
|
||||||
return ncchannels_bg_rgb(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channels_fg_alpha(uint64_t channels){
|
|
||||||
return ncchannels_fg_alpha(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channels_bg_alpha(uint64_t channels){
|
|
||||||
return ncchannels_bg_alpha(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channels_fg_rgb8(uint64_t channels, unsigned* r, unsigned* g, unsigned* b){
|
|
||||||
return ncchannels_fg_rgb8(channels, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline unsigned
|
|
||||||
channels_bg_rgb8(uint64_t channels, unsigned* r, unsigned* g, unsigned* b){
|
|
||||||
return ncchannels_bg_rgb8(channels, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channels_set_fg_rgb8(uint64_t* channels, int r, int g, int b){
|
|
||||||
return ncchannels_set_fg_rgb8(channels, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline void
|
|
||||||
channels_set_fg_rgb8_clipped(uint64_t* channels, int r, int g, int b){
|
|
||||||
ncchannels_set_fg_rgb8_clipped(channels, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channels_set_fg_alpha(uint64_t* channels, unsigned alpha){
|
|
||||||
return ncchannels_set_fg_alpha(channels, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channels_set_fg_palindex(uint64_t* channels, int idx){
|
|
||||||
return ncchannels_set_bg_palindex(channels, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channels_set_fg_rgb(uint64_t* channels, unsigned rgb){
|
|
||||||
return ncchannels_set_fg_rgb(channels, rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channels_set_bg_rgb8(uint64_t* channels, int r, int g, int b){
|
|
||||||
return ncchannels_set_bg_rgb8(channels, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline void
|
|
||||||
channels_set_bg_rgb8_clipped(uint64_t* channels, int r, int g, int b){
|
|
||||||
ncchannels_set_bg_rgb8_clipped(channels, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channels_set_bg_alpha(uint64_t* channels, unsigned alpha){
|
|
||||||
return ncchannels_set_bg_alpha(channels, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channels_set_bg_palindex(uint64_t* channels, int idx){
|
|
||||||
return ncchannels_set_bg_palindex(channels, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline int
|
|
||||||
channels_set_bg_rgb(uint64_t* channels, unsigned rgb){
|
|
||||||
return ncchannels_set_bg_rgb(channels, rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline bool
|
|
||||||
channels_fg_default_p(uint64_t channels){
|
|
||||||
return ncchannels_fg_default_p(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline bool
|
|
||||||
channels_fg_palindex_p(uint64_t channels){
|
|
||||||
return ncchannels_fg_palindex_p(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline bool
|
|
||||||
channels_bg_default_p(uint64_t channels){
|
|
||||||
return ncchannels_bg_default_p(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline bool
|
|
||||||
channels_bg_palindex_p(uint64_t channels){
|
|
||||||
return ncchannels_bg_palindex_p(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline uint64_t
|
|
||||||
channels_set_fg_default(uint64_t* channels){
|
|
||||||
return ncchannels_set_fg_default(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) static inline uint64_t
|
|
||||||
channels_set_bg_default(uint64_t* channels){
|
|
||||||
return ncchannels_set_bg_default(channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inflate each pixel in the image to 'scale'x'scale' pixels. It is an error
|
// 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.
|
// if 'scale' is less than 1. The original color is retained.
|
||||||
// Deprecated; use ncvisual_resize_noninterpolative(), which this now wraps.
|
// Deprecated; use ncvisual_resize_noninterpolative(), which this now wraps.
|
||||||
@ -4488,12 +4272,6 @@ typedef nccell cell; // FIXME backwards-compat, remove in ABI3
|
|||||||
API void notcurses_debug_caps(const struct notcurses* nc, FILE* debugfp)
|
API void notcurses_debug_caps(const struct notcurses* nc, FILE* debugfp)
|
||||||
__attribute__ ((deprecated)) __attribute__ ((nonnull (1, 2)));
|
__attribute__ ((deprecated)) __attribute__ ((nonnull (1, 2)));
|
||||||
|
|
||||||
// Backwards-compatibility wrapper; this will be removed for ABI3.
|
|
||||||
// Use notcurses_get() in new code.
|
|
||||||
API uint32_t notcurses_getc(struct notcurses* n, const struct timespec* ts,
|
|
||||||
const void* unused, ncinput* ni)
|
|
||||||
__attribute__ ((deprecated)) __attribute__ ((nonnull (1)));
|
|
||||||
|
|
||||||
__attribute__ ((deprecated)) API int nccell_width(const struct ncplane* n, const nccell* c);
|
__attribute__ ((deprecated)) API int nccell_width(const struct ncplane* n, const nccell* c);
|
||||||
|
|
||||||
API ALLOC char* ncvisual_subtitle(const struct ncvisual* ncv)
|
API ALLOC char* ncvisual_subtitle(const struct ncvisual* ncv)
|
||||||
|
@ -864,9 +864,7 @@ ncdirect_stop_minimal(void* vnc){
|
|||||||
ret |= fbuf_finalize(&f, stdout);
|
ret |= fbuf_finalize(&f, stdout);
|
||||||
}
|
}
|
||||||
if(nc->tcache.ttyfd >= 0){
|
if(nc->tcache.ttyfd >= 0){
|
||||||
if(nc->tcache.kittykbd){
|
ret |= tty_emit("\x1b[<u", nc->tcache.ttyfd);
|
||||||
ret |= tty_emit("\x1b[<u", nc->tcache.ttyfd);
|
|
||||||
}
|
|
||||||
const char* cnorm = get_escape(&nc->tcache, ESCAPE_CNORM);
|
const char* cnorm = get_escape(&nc->tcache, ESCAPE_CNORM);
|
||||||
if(cnorm && tty_emit(cnorm, nc->tcache.ttyfd)){
|
if(cnorm && tty_emit(cnorm, nc->tcache.ttyfd)){
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@ -883,7 +881,7 @@ ncdirect* ncdirect_core_init(const char* termtype, FILE* outfp, uint64_t flags){
|
|||||||
if(outfp == NULL){
|
if(outfp == NULL){
|
||||||
outfp = stdout;
|
outfp = stdout;
|
||||||
}
|
}
|
||||||
if(flags > (NCDIRECT_OPTION_VERY_VERBOSE << 1)){ // allow them through with warning
|
if(flags > (NCDIRECT_OPTION_DRAIN_INPUT << 1)){ // allow them through with warning
|
||||||
logwarn("Passed unsupported flags 0x%016jx\n", (uintmax_t)flags);
|
logwarn("Passed unsupported flags 0x%016jx\n", (uintmax_t)flags);
|
||||||
}
|
}
|
||||||
ncdirect* ret = malloc(sizeof(ncdirect));
|
ncdirect* ret = malloc(sizeof(ncdirect));
|
||||||
|
@ -32,7 +32,7 @@ gpmwatcher(void* vti){
|
|||||||
logwarn("input overflowed %hd %hd\n", gev.x, gev.y);
|
logwarn("input overflowed %hd %hd\n", gev.x, gev.y);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ncinput_shovel(&ti->input, cmdbuf, strlen(cmdbuf));
|
ncinput_shovel(ti->ictx, cmdbuf, strlen(cmdbuf));
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
1182
src/lib/in.c
1182
src/lib/in.c
File diff suppressed because it is too large
Load Diff
82
src/lib/in.h
Normal file
82
src/lib/in.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#ifndef NOTCURSES_IN
|
||||||
|
#define NOTCURSES_IN
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// internal header, not installed
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct tinfo;
|
||||||
|
struct inputctx;
|
||||||
|
|
||||||
|
int init_inputlayer(struct tinfo* ti, FILE* infp)
|
||||||
|
__attribute__ ((nonnull (1, 2)));
|
||||||
|
|
||||||
|
int stop_inputlayer(struct tinfo* ti);
|
||||||
|
|
||||||
|
int inputready_fd(const struct inputctx* ictx)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
|
// allow another source provide raw input for distribution to client code.
|
||||||
|
// drops input if there is no room in appropriate output queue.
|
||||||
|
int ncinput_shovel(struct inputctx* ictx, const void* buf, int len)
|
||||||
|
__attribute__ ((nonnull (1, 2)));
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TERMINAL_UNKNOWN, // no useful information from queries; use termname
|
||||||
|
// the very limited linux VGA/serial console, or possibly the (deprecated,
|
||||||
|
// pixel-drawable, RGBA8888) linux framebuffer console. *not* fbterm.
|
||||||
|
TERMINAL_LINUX, // ioctl()s
|
||||||
|
// the linux KMS/DRM console, *not* kmscon, but DRM direct dumb buffers
|
||||||
|
TERMINAL_LINUXDRM, // ioctl()s
|
||||||
|
TERMINAL_XTERM, // XTVERSION == 'XTerm(ver)'
|
||||||
|
TERMINAL_VTE, // TDA: "~VTE"
|
||||||
|
TERMINAL_KITTY, // XTGETTCAP['TN'] == 'xterm-kitty'
|
||||||
|
TERMINAL_FOOT, // TDA: "\EP!|464f4f54\E\\"
|
||||||
|
TERMINAL_MLTERM, // XTGETTCAP['TN'] == 'mlterm'
|
||||||
|
TERMINAL_TMUX, // XTVERSION == "tmux ver"
|
||||||
|
TERMINAL_WEZTERM, // XTVERSION == 'WezTerm *'
|
||||||
|
TERMINAL_ALACRITTY, // can't be detected; match TERM+DA2
|
||||||
|
TERMINAL_CONTOUR, // XTVERSION == 'contour ver'
|
||||||
|
TERMINAL_ITERM, // XTVERSION == 'iTerm2 [ver]'
|
||||||
|
TERMINAL_TERMINOLOGY, // TDA: "~~TY"
|
||||||
|
TERMINAL_APPLE, // Terminal.App, determined by TERM_PROGRAM + macOS
|
||||||
|
TERMINAL_MSTERMINAL, // Microsoft Windows Terminal
|
||||||
|
TERMINAL_MINTTY, // XTVERSION == 'mintty ver' MinTTY (Cygwin, MSYS2)
|
||||||
|
} queried_terminals_e;
|
||||||
|
|
||||||
|
// after spawning the input layer, send initial queries to the terminal. its
|
||||||
|
// responses will be built up herein. it's dangerous to go alone! take this!
|
||||||
|
struct initial_responses {
|
||||||
|
int cursory; // cursor location
|
||||||
|
int cursorx; // cursor location
|
||||||
|
unsigned appsync_supported; // is application-synchronized mode supported?
|
||||||
|
queried_terminals_e qterm; // determined terminal
|
||||||
|
unsigned kitty_graphics; // kitty graphics supported
|
||||||
|
uint32_t bg; // default background
|
||||||
|
int pixx; // screen geometry in pixels
|
||||||
|
int pixy; // screen geometry in pixels
|
||||||
|
int dimx; // screen geometry in cells
|
||||||
|
int dimy; // screen geometry in cells
|
||||||
|
int color_registers; // sixel color registers
|
||||||
|
int sixely; // maximum sixel height
|
||||||
|
int sixelx; // maximum sixel width
|
||||||
|
char* version; // version string, heap-allocated
|
||||||
|
};
|
||||||
|
|
||||||
|
// Blocking call. Waits until the input thread has processed all responses to
|
||||||
|
// our initial queries, and returns them.
|
||||||
|
struct initial_responses* inputlayer_get_responses(struct inputctx* ictx)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
|
int get_cursor_location(struct inputctx* ictx, int* y, int* x)
|
||||||
|
__attribute__ ((nonnull (1, 2, 3)));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -1,69 +0,0 @@
|
|||||||
#ifndef NOTCURSES_INPUT
|
|
||||||
#define NOTCURSES_INPUT
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// internal header, not installed
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct tinfo;
|
|
||||||
struct termios;
|
|
||||||
struct ncinputlayer;
|
|
||||||
struct ncsharedstats;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
TERMINAL_UNKNOWN, // no useful information from queries; use termname
|
|
||||||
// the very limited linux VGA/serial console, or possibly the (deprecated,
|
|
||||||
// pixel-drawable, RGBA8888) linux framebuffer console. *not* fbterm.
|
|
||||||
TERMINAL_LINUX, // ioctl()s
|
|
||||||
// the linux KMS/DRM console, *not* kmscon, but DRM direct dumb buffers
|
|
||||||
TERMINAL_LINUXDRM, // ioctl()s
|
|
||||||
TERMINAL_XTERM, // XTVERSION == 'XTerm(ver)'
|
|
||||||
TERMINAL_VTE, // TDA: "~VTE"
|
|
||||||
TERMINAL_KITTY, // XTGETTCAP['TN'] == 'xterm-kitty'
|
|
||||||
TERMINAL_FOOT, // TDA: "\EP!|464f4f54\E\\"
|
|
||||||
TERMINAL_MLTERM, // XTGETTCAP['TN'] == 'mlterm'
|
|
||||||
TERMINAL_TMUX, // XTVERSION == "tmux ver"
|
|
||||||
TERMINAL_WEZTERM, // XTVERSION == 'WezTerm *'
|
|
||||||
TERMINAL_ALACRITTY, // can't be detected; match TERM+DA2
|
|
||||||
TERMINAL_CONTOUR, // XTVERSION == 'contour ver'
|
|
||||||
TERMINAL_ITERM, // XTVERSION == 'iTerm2 [ver]'
|
|
||||||
TERMINAL_TERMINOLOGY, // TDA: "~~TY"
|
|
||||||
TERMINAL_APPLE, // Terminal.App, determined by TERM_PROGRAM + macOS
|
|
||||||
TERMINAL_MSTERMINAL, // Microsoft Windows Terminal
|
|
||||||
TERMINAL_MINTTY, // XTVERSION == 'mintty ver' MinTTY (Cygwin, MSYS2)
|
|
||||||
} queried_terminals_e;
|
|
||||||
|
|
||||||
// sets up the input layer, building a trie of escape sequences and their
|
|
||||||
// nckey equivalents. if we are connected to a tty, this also completes the
|
|
||||||
// terminal detection sequence (we ought have already written our initial
|
|
||||||
// queries, ideally as early as possible). if we are able to determine the
|
|
||||||
// terminal conclusively, it will be written to |detected|. if the terminal
|
|
||||||
// advertised support for application-sychronized updates, |appsync| will be
|
|
||||||
// non-zero.
|
|
||||||
int ncinputlayer_init(struct tinfo* tcache, FILE* infp,
|
|
||||||
queried_terminals_e* detected, unsigned* appsync,
|
|
||||||
int* cursor_y, int* cursor_x,
|
|
||||||
struct ncsharedstats* stats,
|
|
||||||
unsigned* kittygraphs);
|
|
||||||
|
|
||||||
void ncinputlayer_stop(struct ncinputlayer* nilayer);
|
|
||||||
|
|
||||||
// FIXME absorb into ncinputlayer_init()
|
|
||||||
int cbreak_mode(struct tinfo* ti);
|
|
||||||
|
|
||||||
// assuming the user context is not active, go through current data looking
|
|
||||||
// for a cursor location report. if we find none, block on input, and read if
|
|
||||||
// appropriate. we can be interrupted by a new user context.
|
|
||||||
void ncinput_extract_clrs(struct tinfo* ti);
|
|
||||||
|
|
||||||
int ncinput_shovel(struct ncinputlayer* ni, const char* buf, size_t len);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -9,6 +9,7 @@ extern "C" {
|
|||||||
#include "builddef.h"
|
#include "builddef.h"
|
||||||
#include "compat/compat.h"
|
#include "compat/compat.h"
|
||||||
#include "notcurses/notcurses.h"
|
#include "notcurses/notcurses.h"
|
||||||
|
#include "notcurses/direct.h"
|
||||||
|
|
||||||
// KEY_EVENT is defined by both ncurses.h and wincon.h. since we don't use
|
// KEY_EVENT is defined by both ncurses.h and wincon.h. since we don't use
|
||||||
// either definition, kill it before inclusion of ncurses.h.
|
// either definition, kill it before inclusion of ncurses.h.
|
||||||
|
@ -406,7 +406,7 @@ program_line_drawing_chars(int fd, struct unimapdesc* map){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(ioctl(fd, PIO_UNIMAP, map)){
|
if(ioctl(fd, PIO_UNIMAP, map)){
|
||||||
logwarn("Error setting kernel unicode map (%s)\n", strerror(errno));
|
logwarn("error setting kernel unicode map (%s)\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
loginfo("Successfully added %d kernel unicode mapping%s\n",
|
loginfo("Successfully added %d kernel unicode mapping%s\n",
|
||||||
@ -533,12 +533,12 @@ program_block_drawing_chars(tinfo* ti, int fd, struct console_font_op* cfo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(candidate == 0){
|
if(candidate == 0){
|
||||||
logwarn("Ran out of replaceable glyphs for U+%04lx\n", (long)half[s].w);
|
logwarn("ran out of replaceable glyphs for U+%04lx\n", (long)half[s].w);
|
||||||
// FIXME maybe don't want to error out here?
|
// FIXME maybe don't want to error out here?
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(shim_quad_block(cfo, candidate, half[s].qbits)){
|
if(shim_quad_block(cfo, candidate, half[s].qbits)){
|
||||||
logwarn("Error replacing glyph for U+%04lx at %u\n", (long)half[s].w, candidate);
|
logwarn("error replacing glyph for U+%04lx at %u\n", (long)half[s].w, candidate);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(add_to_map(map, half[s].w, candidate)){
|
if(add_to_map(map, half[s].w, candidate)){
|
||||||
@ -555,12 +555,12 @@ program_block_drawing_chars(tinfo* ti, int fd, struct console_font_op* cfo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(candidate == 0){
|
if(candidate == 0){
|
||||||
logwarn("Ran out of replaceable glyphs for U+%04lx\n", (long)quads[s].w);
|
logwarn("ran out of replaceable glyphs for U+%04lx\n", (long)quads[s].w);
|
||||||
// FIXME maybe don't want to error out here?
|
// FIXME maybe don't want to error out here?
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(shim_quad_block(cfo, candidate, quads[s].qbits)){
|
if(shim_quad_block(cfo, candidate, quads[s].qbits)){
|
||||||
logwarn("Error replacing glyph for U+%04lx at %u\n", (long)quads[s].w, candidate);
|
logwarn("error replacing glyph for U+%04lx at %u\n", (long)quads[s].w, candidate);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(add_to_map(map, quads[s].w, candidate)){
|
if(add_to_map(map, quads[s].w, candidate)){
|
||||||
@ -577,11 +577,11 @@ program_block_drawing_chars(tinfo* ti, int fd, struct console_font_op* cfo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(candidate == 0){
|
if(candidate == 0){
|
||||||
logwarn("Ran out of replaceable glyphs for U+%04lx\n", (long)eighths[s].w);
|
logwarn("ran out of replaceable glyphs for U+%04lx\n", (long)eighths[s].w);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(shim_lower_eighths(cfo, candidate, eighths[s].qbits)){
|
if(shim_lower_eighths(cfo, candidate, eighths[s].qbits)){
|
||||||
logwarn("Error replacing glyph for U+%04lx at %u\n", (long)eighths[s].w, candidate);
|
logwarn("error replacing glyph for U+%04lx at %u\n", (long)eighths[s].w, candidate);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(add_to_map(map, eighths[s].w, candidate)){
|
if(add_to_map(map, eighths[s].w, candidate)){
|
||||||
@ -600,12 +600,12 @@ program_block_drawing_chars(tinfo* ti, int fd, struct console_font_op* cfo,
|
|||||||
}
|
}
|
||||||
cfo->op = KD_FONT_OP_SET;
|
cfo->op = KD_FONT_OP_SET;
|
||||||
if(ioctl(fd, KDFONTOP, cfo)){
|
if(ioctl(fd, KDFONTOP, cfo)){
|
||||||
logwarn("Error programming kernel font (%s)\n", strerror(errno));
|
logwarn("error programming kernel font (%s)\n", strerror(errno));
|
||||||
kill_fbcopy(&fbdup);
|
kill_fbcopy(&fbdup);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(ioctl(fd, PIO_UNIMAP, map)){
|
if(ioctl(fd, PIO_UNIMAP, map)){
|
||||||
logwarn("Error setting kernel unicode map (%s)\n", strerror(errno));
|
logwarn("error setting kernel unicode map (%s)\n", strerror(errno));
|
||||||
kill_fbcopy(&fbdup);
|
kill_fbcopy(&fbdup);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -636,7 +636,7 @@ reprogram_linux_font(tinfo* ti, int fd, struct console_font_op* cfo,
|
|||||||
struct unimapdesc* map, unsigned no_font_changes,
|
struct unimapdesc* map, unsigned no_font_changes,
|
||||||
bool* halfblocks, bool* quadrants){
|
bool* halfblocks, bool* quadrants){
|
||||||
if(ioctl(fd, KDFONTOP, cfo)){
|
if(ioctl(fd, KDFONTOP, cfo)){
|
||||||
logwarn("Error reading Linux kernelfont (%s)\n", strerror(errno));
|
logwarn("error reading Linux kernelfont (%s)\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
loginfo("Kernel font size (glyphcount): %hu\n", cfo->charcount);
|
loginfo("Kernel font size (glyphcount): %hu\n", cfo->charcount);
|
||||||
@ -646,7 +646,7 @@ reprogram_linux_font(tinfo* ti, int fd, struct console_font_op* cfo,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(ioctl(fd, GIO_UNIMAP, map)){
|
if(ioctl(fd, GIO_UNIMAP, map)){
|
||||||
logwarn("Error reading Linux unimap (%s)\n", strerror(errno));
|
logwarn("error reading Linux unimap (%s)\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
loginfo("Kernel Unimap size: %hu/%hu\n", map->entry_ct, USHRT_MAX);
|
loginfo("Kernel Unimap size: %hu/%hu\n", map->entry_ct, USHRT_MAX);
|
||||||
@ -676,7 +676,7 @@ int reprogram_console_font(tinfo* ti, unsigned no_font_changes,
|
|||||||
size_t totsize = 128 * cfo.charcount; // FIXME enough?
|
size_t totsize = 128 * cfo.charcount; // FIXME enough?
|
||||||
cfo.data = malloc(totsize);
|
cfo.data = malloc(totsize);
|
||||||
if(cfo.data == NULL){
|
if(cfo.data == NULL){
|
||||||
logwarn("Error acquiring %zub for font descriptors (%s)\n", totsize, strerror(errno));
|
logwarn("error acquiring %zub for font descriptors (%s)\n", totsize, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct unimapdesc map = {};
|
struct unimapdesc map = {};
|
||||||
@ -684,7 +684,7 @@ int reprogram_console_font(tinfo* ti, unsigned no_font_changes,
|
|||||||
totsize = map.entry_ct * sizeof(struct unipair);
|
totsize = map.entry_ct * sizeof(struct unipair);
|
||||||
map.entries = malloc(totsize);
|
map.entries = malloc(totsize);
|
||||||
if(map.entries == NULL){
|
if(map.entries == NULL){
|
||||||
logwarn("Error acquiring %zub for Unicode font map (%s)\n", totsize, strerror(errno));
|
logwarn("error acquiring %zub for Unicode font map (%s)\n", totsize, strerror(errno));
|
||||||
free(cfo.data);
|
free(cfo.data);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -704,10 +704,10 @@ bool is_linux_console(int fd){
|
|||||||
}
|
}
|
||||||
int mode;
|
int mode;
|
||||||
if(ioctl(fd, KDGETMODE, &mode)){
|
if(ioctl(fd, KDGETMODE, &mode)){
|
||||||
logdebug("Not a Linux console, KDGETMODE failed\n");
|
logdebug("not a Linux console, KDGETMODE failed\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
loginfo("Verified Linux console, mode %d\n", mode);
|
loginfo("verified Linux console, mode %d\n", mode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,7 +721,7 @@ int get_linux_fb_pixelgeom(tinfo* ti, unsigned* ypix, unsigned *xpix){
|
|||||||
}
|
}
|
||||||
struct fb_var_screeninfo fbi = {};
|
struct fb_var_screeninfo fbi = {};
|
||||||
if(ioctl(ti->linux_fb_fd, FBIOGET_VSCREENINFO, &fbi)){
|
if(ioctl(ti->linux_fb_fd, FBIOGET_VSCREENINFO, &fbi)){
|
||||||
logwarn("No framebuffer info from %s (%s?)\n", ti->linux_fb_dev, strerror(errno));
|
logwarn("no framebuffer info from %s (%s?)\n", ti->linux_fb_dev, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
loginfo("Linux %s geometry: %dx%d\n", ti->linux_fb_dev, fbi.yres, fbi.xres);
|
loginfo("Linux %s geometry: %dx%d\n", ti->linux_fb_dev, fbi.yres, fbi.xres);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#include "input.h"
|
|
||||||
#include "linux.h"
|
#include "linux.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "egcpool.h"
|
#include "egcpool.h"
|
||||||
@ -107,10 +106,8 @@ notcurses_stop_minimal(void* vnc){
|
|||||||
if(nc->tcache.tpreserved){
|
if(nc->tcache.tpreserved){
|
||||||
ret |= tcsetattr(nc->tcache.ttyfd, TCSAFLUSH, nc->tcache.tpreserved);
|
ret |= tcsetattr(nc->tcache.ttyfd, TCSAFLUSH, nc->tcache.tpreserved);
|
||||||
}
|
}
|
||||||
if(nc->tcache.kittykbd){
|
if(tty_emit("\x1b[<u", nc->tcache.ttyfd)){
|
||||||
if(tty_emit("\x1b[<u", nc->tcache.ttyfd)){
|
ret = -1;
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if((esc = get_escape(&nc->tcache, ESCAPE_RMCUP))){
|
if((esc = get_escape(&nc->tcache, ESCAPE_RMCUP))){
|
||||||
if(sprite_clear_all(&nc->tcache, f)){ // send this to f
|
if(sprite_clear_all(&nc->tcache, f)){ // send this to f
|
||||||
@ -1001,7 +998,7 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){
|
|||||||
fprintf(stderr, "Provided an illegal negative margin, refusing to start\n");
|
fprintf(stderr, "Provided an illegal negative margin, refusing to start\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(opts->flags >= (NCOPTION_NO_FONT_CHANGES << 1u)){
|
if(opts->flags >= (NCOPTION_DRAIN_INPUT << 1u)){
|
||||||
fprintf(stderr, "Warning: unknown Notcurses options %016" PRIu64 "\n", opts->flags);
|
fprintf(stderr, "Warning: unknown Notcurses options %016" PRIu64 "\n", opts->flags);
|
||||||
}
|
}
|
||||||
notcurses* ret = malloc(sizeof(*ret));
|
notcurses* ret = malloc(sizeof(*ret));
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "input.h"
|
|
||||||
#include "linux.h"
|
#include "linux.h"
|
||||||
|
|
||||||
// there does not exist any true standard terminal size. with that said, we
|
// there does not exist any true standard terminal size. with that said, we
|
||||||
@ -780,6 +779,9 @@ int interrogate_terminfo(tinfo* ti, const char* termtype, FILE* out, unsigned ut
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(init_inputlayer(ti, stdin)){
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
#ifndef __MINGW64__
|
#ifndef __MINGW64__
|
||||||
// windows doesn't really have a concept of terminfo. you might ssh into other
|
// windows doesn't really have a concept of terminfo. you might ssh into other
|
||||||
// machines, but they'll use the terminfo installed thereon (putty, etc.).
|
// machines, but they'll use the terminfo installed thereon (putty, etc.).
|
||||||
@ -916,19 +918,51 @@ int interrogate_terminfo(tinfo* ti, const char* termtype, FILE* out, unsigned ut
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsigned appsync_advertised = 0;
|
unsigned kitty_graphics = 0;
|
||||||
unsigned kittygraphs = 0;
|
if(ti->ttyfd >= 0){
|
||||||
if(init_inputlayer(ti, stdin)){
|
struct initial_responses* iresp;
|
||||||
goto err;
|
if((iresp = inputlayer_get_responses(ti->ictx)) == NULL){
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if(iresp->appsync_supported){
|
||||||
|
if(add_appsync_escapes_sm(ti, &tablelen, &tableused)){
|
||||||
|
free(iresp->version);
|
||||||
|
free(iresp);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(iresp->qterm != TERMINAL_UNKNOWN){
|
||||||
|
ti->qterm = iresp->qterm;
|
||||||
|
}
|
||||||
|
*cursor_y = iresp->cursory;
|
||||||
|
*cursor_x = iresp->cursorx;
|
||||||
|
ti->termversion = iresp->version;
|
||||||
|
if(iresp->dimy && iresp->dimx){
|
||||||
|
// FIXME probably oughtn't be setting the defaults, as this is just some
|
||||||
|
// random transient measurement?
|
||||||
|
ti->default_rows = iresp->dimy;
|
||||||
|
ti->default_cols = iresp->dimx;
|
||||||
|
}
|
||||||
|
if(iresp->pixy && iresp->pixx){
|
||||||
|
ti->pixy = iresp->pixy;
|
||||||
|
ti->pixx = iresp->pixx;
|
||||||
|
}
|
||||||
|
if(ti->default_rows && ti->default_cols){
|
||||||
|
ti->cellpixy = ti->pixy / ti->default_rows;
|
||||||
|
ti->cellpixx = ti->pixx / ti->default_cols;
|
||||||
|
}
|
||||||
|
ti->bg_collides_default = iresp->bg;
|
||||||
|
// kitty trumps sixel, when both are available
|
||||||
|
if((kitty_graphics = iresp->kitty_graphics) == 0){
|
||||||
|
ti->color_registers = iresp->color_registers;
|
||||||
|
ti->sixel_maxy = iresp->sixely;
|
||||||
|
ti->sixel_maxx = iresp->sixelx;
|
||||||
|
}
|
||||||
|
free(iresp);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if(ncinputlayer_init(ti, stdin, &ti->qterm, &appsync_advertised,
|
|
||||||
cursor_y, cursor_x, stats, &kittygraphs)){
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if(nocbreak){
|
if(nocbreak){
|
||||||
if(ti->ttyfd >= 0){
|
if(ti->ttyfd >= 0){
|
||||||
|
// FIXME do this in input later, upon signaling completion?
|
||||||
if(tcsetattr(ti->ttyfd, TCSANOW, ti->tpreserved)){
|
if(tcsetattr(ti->ttyfd, TCSANOW, ti->tpreserved)){
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -939,11 +973,6 @@ int interrogate_terminfo(tinfo* ti, const char* termtype, FILE* out, unsigned ut
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(appsync_advertised){
|
|
||||||
if(add_appsync_escapes_sm(ti, &tablelen, &tableused)){
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool invertsixel = false;
|
bool invertsixel = false;
|
||||||
if(apply_term_heuristics(ti, tname, ti->qterm, &tablelen, &tableused,
|
if(apply_term_heuristics(ti, tname, ti->qterm, &tablelen, &tableused,
|
||||||
&invertsixel, nonewfonts)){
|
&invertsixel, nonewfonts)){
|
||||||
@ -951,8 +980,8 @@ int interrogate_terminfo(tinfo* ti, const char* termtype, FILE* out, unsigned ut
|
|||||||
}
|
}
|
||||||
build_supported_styles(ti);
|
build_supported_styles(ti);
|
||||||
if(ti->pixel_draw == NULL && ti->pixel_draw_late == NULL){
|
if(ti->pixel_draw == NULL && ti->pixel_draw_late == NULL){
|
||||||
if(kittygraphs){
|
if(kitty_graphics){
|
||||||
setup_kitty_bitmaps(ti, ti->ttyfd, KITTY_SELFREF);
|
setup_kitty_bitmaps(ti, ti->ttyfd, KITTY_ANIMATION);
|
||||||
}
|
}
|
||||||
// our current sixel quantization algorithm requires at least 64 color
|
// our current sixel quantization algorithm requires at least 64 color
|
||||||
// registers. we make use of no more than 256. this needs to happen
|
// registers. we make use of no more than 256. this needs to happen
|
||||||
@ -1028,18 +1057,13 @@ int locate_cursor(tinfo* ti, int* cursor_y, int* cursor_x){
|
|||||||
if(tty_emit(u7, fd)){
|
if(tty_emit(u7, fd)){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// FIXME get that report
|
get_cursor_location(ti->ictx, cursor_y, cursor_x);
|
||||||
/*
|
loginfo("got a report from %d %d/%d\n", fd, *cursor_y, *cursor_x);
|
||||||
loginfo("Got a report from %d %d/%d\n", fd, clr->y, clr->x);
|
|
||||||
*cursor_y = clr->y;
|
|
||||||
*cursor_x = clr->x;
|
|
||||||
if(ti->inverted_cursor){
|
if(ti->inverted_cursor){
|
||||||
int tmp = *cursor_y;
|
int tmp = *cursor_y;
|
||||||
*cursor_y = *cursor_x;
|
*cursor_y = *cursor_x;
|
||||||
*cursor_x = tmp;
|
*cursor_x = tmp;
|
||||||
}
|
}
|
||||||
free(clr);
|
|
||||||
*/
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ extern "C" {
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <notcurses/notcurses.h>
|
#include <notcurses/notcurses.h>
|
||||||
#include "input.h"
|
|
||||||
#include "fbuf.h"
|
#include "fbuf.h"
|
||||||
#include "in.h"
|
#include "in.h"
|
||||||
|
|
||||||
@ -89,43 +88,6 @@ typedef struct cursorreport {
|
|||||||
struct cursorreport* next;
|
struct cursorreport* next;
|
||||||
} cursorreport;
|
} cursorreport;
|
||||||
|
|
||||||
// we read input from one or two places. if stdin is connected to our
|
|
||||||
// controlling tty, we read only from that file descriptor. if it is
|
|
||||||
// connected to something else, and we have a controlling tty, we will
|
|
||||||
// read data only from stdin and control only from the tty. if we have
|
|
||||||
// no connected tty, only data is available.
|
|
||||||
typedef struct ncinputlayer {
|
|
||||||
// only allow one reader at a time, whether it's the user trying to do so,
|
|
||||||
// or our desire for a cursor report competing with the user.
|
|
||||||
pthread_mutex_t lock;
|
|
||||||
// must be held to operate on the cursor report queue shared between pure
|
|
||||||
// input and the control layer.
|
|
||||||
pthread_cond_t creport_cond;
|
|
||||||
// ttyfd is only valid if we are connected to a tty, *and* stdin is not
|
|
||||||
// connected to that tty (this usually means stdin was redirected). in that
|
|
||||||
// case, we read control sequences only from ttyfd.
|
|
||||||
int ttyfd; // file descriptor for connected tty
|
|
||||||
int infd; // file descriptor for processing input, from stdin
|
|
||||||
unsigned char inputbuf[BUFSIZ];
|
|
||||||
unsigned char csibuf[BUFSIZ]; // running buffer while parsing CSIs
|
|
||||||
// we keep a wee ringbuffer of input queued up for delivery. if
|
|
||||||
// inputbuf_occupied == sizeof(inputbuf), there is no room. otherwise, data
|
|
||||||
// can be read to inputbuf_write_at until we fill up. the first datum
|
|
||||||
// available for the app is at inputbuf_valid_starts iff inputbuf_occupied is
|
|
||||||
// not 0. the main purpose is working around bad predictions of escapes.
|
|
||||||
unsigned inputbuf_occupied;
|
|
||||||
unsigned inputbuf_valid_starts;
|
|
||||||
unsigned inputbuf_write_at;
|
|
||||||
// number of input events seen. does not belong in ncstats, since it must not
|
|
||||||
// be reset (semantics are relied upon by widgets for mouse click detection).
|
|
||||||
uint64_t input_events;
|
|
||||||
struct esctrie* inputescapes; // trie of input escapes -> ncspecial_keys
|
|
||||||
cursorreport* creport_queue; // queue of cursor reports
|
|
||||||
bool user_wants_data; // a user context is active
|
|
||||||
bool inner_wants_data; // if we're blocking on input
|
|
||||||
struct ncsharedstats* stats; // notcurses sharedstats object
|
|
||||||
} ncinputlayer;
|
|
||||||
|
|
||||||
// terminal interface description. most of these are acquired from terminfo(5)
|
// terminal interface description. most of these are acquired from terminfo(5)
|
||||||
// (using a database entry specified by TERM). some are determined via
|
// (using a database entry specified by TERM). some are determined via
|
||||||
// heuristics based off terminal interrogation or the TERM environment
|
// heuristics based off terminal interrogation or the TERM environment
|
||||||
@ -208,8 +170,6 @@ typedef struct tinfo {
|
|||||||
int default_rows; // LINES environment var / lines terminfo / 24
|
int default_rows; // LINES environment var / lines terminfo / 24
|
||||||
int default_cols; // COLUMNS environment var / cols terminfo / 80
|
int default_cols; // COLUMNS environment var / cols terminfo / 80
|
||||||
|
|
||||||
unsigned kittykbd; // kitty keyboard support level
|
|
||||||
|
|
||||||
int gpmfd; // connection to GPM daemon
|
int gpmfd; // connection to GPM daemon
|
||||||
pthread_t gpmthread; // thread handle for GPM watcher
|
pthread_t gpmthread; // thread handle for GPM watcher
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -384,6 +344,8 @@ leave_alternate_screen(FILE* fp, tinfo* ti){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cbreak_mode(tinfo* ti);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user