1notcurses_input(3) notcurses_input(3)
2
3
4
6 notcurses_input - input via notcurses
7
9 #include <notcurses/notcurses.h>
10
11 struct timespec;
12 struct notcurses;
13
14 typedef enum {
15 NCTYPE_UNKNOWN,
16 NCTYPE_PRESS,
17 NCTYPE_REPEAT,
18 NCTYPE_RELEASE,
19 } ncintype_e;
20
21 // An input event. Cell coordinates are currently defined only for mouse
22 // events. It is not guaranteed that we can set the modifiers for a given
23 // ncinput. We encompass single Unicode codepoints, not complete EGCs.
24 // FIXME for abi4, combine the bools into |modifiers|
25 typedef struct ncinput {
26 uint32_t id; // Unicode codepoint or synthesized NCKEY event
27 int y, x; // y/x cell coordinate of event, -1 for undefined
28 char utf8[5]; // utf8 representation, if one exists
29 // DEPRECATED do not use! going away in 4.0
30 bool alt; // was alt held?
31 bool shift; // was shift held?
32 bool ctrl; // was ctrl held?
33 // END DEPRECATION
34 ncintype_e evtype;
35 unsigned modifiers;// bitmask over NCKEY_MOD_*
36 int ypx, xpx; // pixel offsets within cell, -1 for undefined
37 } ncinput;
38
39
40 #define NCMICE_NO_EVENTS 0
41 #define NCMICE_MOVE_EVENT 0x1
42 #define NCMICE_BUTTON_EVENT 0x2
43 #define NCMICE_DRAG_EVENT 0x4
44 #define NCMICE_ALL_EVENTS 0x7
45
46 bool nckey_mouse_p(uint32_t r);
47
48 bool ncinput_nomod_p(const ncinput* ni);
49
50 uint32_t notcurses_get(struct notcurses* n, const struct timespec* ts,
51 ncinput* ni);
52
53 int notcurses_getvec(struct notcurses* n, const struct timespec* ts,
54 ncinput* ni, int vcount);
55
56 uint32_t notcurses_get_nblock(struct notcurses* n, ncinput* ni);
57
58 uint32_t notcurses_get_blocking(struct notcurses* n, ncinput* ni);
59
60 int notcurses_mice_enable(struct notcurses* n, unsigned eventmask);
61
62 int notcurses_mice_disable(struct notcurses* n);
63
64 int notcurses_inputready_fd(struct notcurses* n);
65
66 static inline bool ncinput_equal_p(const ncinput* n1, const ncinput*
67 n2);
68
69 int notcurses_linesigs_disable(struct notcurses* n);
70
71 int notcurses_linesigs_enable(struct notcurses* n);
72
73 bool ncinput_shift_p(const struct ncinput* n);
74
75 bool ncinput_ctrl_p(const struct ncinput* n);
76
77 bool ncinput_alt_p(const struct ncinput* n);
78
79 bool ncinput_meta_p(const struct ncinput* n);
80
81 bool ncinput_super_p(const struct ncinput* n);
82
83 bool ncinput_hyper_p(const struct ncinput* n);
84
86 notcurses supports input from keyboards and mice, and any device that
87 looks like them. Mouse support requires a broker such as GPM, Wayland,
88 or Xorg, and must be explicitly enabled via notcurses_mice_enable. The
89 full 32-bit range of Unicode is supported (see unicode(7)), with syn‐
90 thesized events mapped above the 1,114,112 codepoints of Unicode 14.0's
91 seventeen Planes. Unicode characters are returned directly as UCS-32,
92 one codepoint at a time. When the input has a UTF8 representation, it
93 is written to utf8; this field is always NUL-terminated.
94
95 notcurses takes its keyboard input from stdin, which will be placed in‐
96 to non-blocking mode for the duration of operation. The terminal is
97 put into non-canonical mode (see termios(3)), and thus keys are re‐
98 ceived without line-buffering. notcurses maintains its own buffer of
99 input characters, which it will attempt to fill whenever it reads.
100
101 notcurses_get allows a struct timespec to be specified as a timeout.
102 If ts is NULL, notcurses_get will block until it reads input, or is in‐
103 terrupted by a signal. If its values are zeroes, there will be no
104 blocking. Otherwise, ts specifies an absolute deadline (taken against
105 CLOCK_MONOTONIC; see clock_gettime(2)). On timeout, 0 is returned.
106 Event details will be reported in ni, unless ni is NULL.
107
108 notcurses_inputready_fd provides a file descriptor suitable for use
109 with I/O multiplexors such as poll(2). This file descriptor might or
110 might not be the actual input file descriptor. If it readable,
111 notcurses_get can be called without the possibility of blocking.
112
113 ncinput_equal_p compares two ncinput structs for data equality (i.e.
114 not considering padding), returning true if they represent the same in‐
115 put (though not necessarily the same input event). Note that NC‐
116 TYPE_UNKNOWN and NCTYPE_PRESS are considered equivalent for the purpos‐
117 es of ncinput_equal_p.
118
119 notcurses_linesigs_disable disables conversion of inputs INTR, QUIT,
120 SUSP, and DSUSP into SIGINT, SIGQUIT, and SIGTSTP. These conversions
121 are enabled by default. notcurses_linesigs_enable undoes this action,
122 but signals in the interim are permanently lost.
123
124 ncinput_shift_p, ncinput_ctrl_p, ncinput_alt_p, and ncinput_meta_p test
125 n to see if the relevant modifier is set. This is preferably to di‐
126 rectly accessing the struct members.
127
128 Mice
129 For mouse events, the additional fields y, x, ypx, and xpx are set.
130 These fields are not meaningful for keypress events. Mouse events can
131 be distinguished using the nckey_mouse_p predicate. NCMICE_MOVE_EVENT
132 requests events whenever the mouse moves when no buttons are held down.
133 NCMICE_DRAG_EVENT requests events when the mouse is moving with buttons
134 held down. NCMICE_BUTTON_EVENT requests events then the button state
135 changes. NCMICE_ALL_EVENTS is provided for convenience and future-
136 proofing against API (though not ABI) changes.
137
138 Synthesized keypresses
139 Many keys do not have a Unicode representation, let alone ASCII. Exam‐
140 ples include the modifier keys (Alt, Meta, etc.), the "function" keys,
141 and the arrow keys on the numeric keypad. The special keys available
142 to the terminal are defined in the terminfo(5) entry, which notcurses
143 loads on startup. Upon receiving an escape code matching a terminfo
144 input capability, notcurses synthesizes a special value. An escape se‐
145 quence must arrive in its entirety to notcurses; running out of input
146 in the middle of an escape sequence will see it rejected. Likewise,
147 any error while handling an escape sequence will see the lex aborted,
148 and the sequence thus far played back as independent literal key‐
149 strokes.
150
151 The full list of synthesized keys (there are well over one hundred) can
152 be found in <notcurses/notcurses.h>. For more details, consult termin‐
153 fo(5).
154
155 NCKEY_RESIZE
156 Unless the SIGWINCH handler has been inhibited (see notcurses_init),
157 Notcurses will automatically catch screen resizes, and synthesize an
158 NCKEY_RESIZE event. Upon receiving this event, the user may call
159 notcurses_refresh to force an immediate reflow, or just wait until the
160 next call to notcurses_render, when notcurses will pick up the resize
161 itself. If the SIGWINCH handler is inhibited, NCKEY_RESIZE is never
162 generated.
163
164 NCKEY_SIGNAL
165 Unless the SIGWINCH handler has been inhibited (see notcurses_init),
166 Notcurses will catch SIGCONT, and synthesize an NCKEY_SIGNAL event.
167 This typically indicates that the program has been restarted after be‐
168 ing paused or placed in the background. The next rasterization will be
169 a full rebuild of the screen, as if notcurses_refresh had been called;
170 the user might wish to immediately call notcurses_refresh themselves.
171
172 NCKEY_EOF
173 Upon reaching the end of input, NCKEY_EOF will be returned. At this
174 point, any further calls will immediately return NCKEY_EOF. Note that
175 this does not necessarily result from pressing e.g. Ctrl+D.
176
178 On error, the get family of functions return (uint32_t)-1. The cause
179 of the error may be determined using errno(3). Unless the error was a
180 temporary one (especially e.g. EINTR), notcurses_get probably cannot
181 be usefully called forthwith. On a timeout, 0 is returned. Otherwise,
182 the UCS-32 value of a Unicode codepoint, or a synthesized event, is re‐
183 turned.
184
185 If an error is encountered before notcurses_getvec has read any input,
186 it will return -1. If it times out before reading any input, it will
187 return 0. Otherwise, it returns the number of ncinput objects written
188 back.
189
190 notcurses_mice_enable returns 0 on success, and non-zero on failure, as
191 does notcurses_mice_disable. Success does not necessarily mean that a
192 mouse is available nor that all requested events will be generated.
193
194 ncinput_equal_p returns true if the two ncinput structs represent the
195 same input (though not necessarily the same input event), and false
196 otherwise.
197
199 Like any other notcurses function, it is an error to call notcurses_get
200 during or after a call to notcurses_stop. If a thread is always sit‐
201 ting on blocking input, it can be tricky to guarantee that this doesn't
202 happen.
203
204 Only one thread may call into the input stack at once, but unlike al‐
205 most every other function in notcurses, notcurses_get and friends can
206 be called concurrently with notcurses_render.
207
208 Do not simply poll the file descriptor associated with stdin to test
209 for input readiness. Instead, use the file descriptor returned by
210 notcurses_inputready_fd to ensure compatibility with future versions of
211 Notcurses (it is possible that future versions will process input in
212 their own contexts).
213
214 The full list of synthesized events is available in <notcurses/nck‐
215 eys.h>.
216
217 In API4, the various bool modifier fields will go away, and these sta‐
218 tuses will be merged into the modifiers bitmask. You are encouraged to
219 use ncinput_shift_p and friends to future-proof your code.
220
222 Notcurses attempts to use the XTMODKEYS and Kitty keyboard disambigua‐
223 tion protocols. When supported, they eliminate most of these issues.
224
225 The Shift key is traditionally not indicated in conjunction with typi‐
226 cal Unicode text. If e.g. Shift is used to generate a capital letter
227 'A', id will equal 'A', and shift will be false. Similarly, when Ctrl
228 is pressed along with a letter, the letter will currently always be re‐
229 ported in its uppercase form. E.g., if Shift, Ctrl, and 'a' are all
230 pressed, this is indistinguishable from Ctrl and 'A'.
231
232 Ctrl pressed along with 'J' or 'M', whether Shift is pressed or not,
233 currently registers as NCKEY_ENTER. This will likely change in the fu‐
234 ture.
235
236 When the Kitty keyboard disambiguation protocol is used, most of these
237 issues are resolved. You can determine whether the protocol is in use
238 by examining the output of notcurses-info(1). If the kbd property is
239 indicated, you're using the Kitty protocol.
240
241 Mouse events in the left margins will never be delivered to the appli‐
242 cation (as is intended), but mouse events in the bottom and right mar‐
243 gins sometimes can be if the event occurs prior to a window resize.
244
245 The ypx and xpx fields are never currently valid (i.e. they are always
246 -1). This ought be fixed in the future using the SGR PixelMode mouse
247 protocol.
248
249 On some operating systems, CLOCK_REALTIME is used as the basis for
250 timeouts instead of CLOCK_MONOTONIC. This ought be fixed.
251
253 notcurses-info(1), clock_gettime(2), poll(2), notcurses(3), notcurs‐
254 es_refresh(3), notcurses_render(3), termios(3), terminfo(5), ascii(7),
255 signal(7), unicode(7)
256
258 nick black <nickblack@linux.com>.
259
260
261
262 v3.0.8 notcurses_input(3)