xref: /vim-8.2.3635/src/libvterm/include/vterm.h (revision 6fc3b59e)
1 /*
2  * NOTE: This is a MODIFIED version of libvterm, see the README file.
3  */
4 #ifndef __VTERM_H__
5 #define __VTERM_H__
6 
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
11 #include <stdlib.h>
12 
13 #include "vterm_keycodes.h"
14 
15 #define TRUE 1
16 #define FALSE 0
17 
18 // from stdint.h
19 typedef unsigned char		uint8_t;
20 typedef unsigned int		uint32_t;
21 
22 #define VTERM_VERSION_MAJOR 0
23 #define VTERM_VERSION_MINOR 1
24 
25 #define VTERM_CHECK_VERSION \
26         vterm_check_version(VTERM_VERSION_MAJOR, VTERM_VERSION_MINOR)
27 
28 typedef struct VTerm VTerm;
29 typedef struct VTermState VTermState;
30 typedef struct VTermScreen VTermScreen;
31 
32 // Specifies a screen point.
33 typedef struct {
34   int row;
35   int col;
36 } VTermPos;
37 
38 /*
39  * Some small utility functions; we can just keep these static here.
40  */
41 
42 /*
43  * Order points by on-screen flow order:
44  * Return < 0 if "a" is before "b"
45  * Return  0  if "a" and "b" are equal
46  * Return > 0 if "a" is after "b".
47  */
48 int vterm_pos_cmp(VTermPos a, VTermPos b);
49 
50 #if defined(DEFINE_INLINES) || USE_INLINE
51 INLINE int vterm_pos_cmp(VTermPos a, VTermPos b)
52 {
53   return (a.row == b.row) ? a.col - b.col : a.row - b.row;
54 }
55 #endif
56 
57 // Specifies a rectangular screen area.
58 typedef struct {
59   int start_row;
60   int end_row;
61   int start_col;
62   int end_col;
63 } VTermRect;
64 
65 // Return true if the rect "r" contains the point "p".
66 int vterm_rect_contains(VTermRect r, VTermPos p);
67 
68 #if defined(DEFINE_INLINES) || USE_INLINE
69 INLINE int vterm_rect_contains(VTermRect r, VTermPos p)
70 {
71   return p.row >= r.start_row && p.row < r.end_row &&
72          p.col >= r.start_col && p.col < r.end_col;
73 }
74 #endif
75 
76 // Move "rect" "row_delta" down and "col_delta" right.
77 // Does not check boundaries.
78 void vterm_rect_move(VTermRect *rect, int row_delta, int col_delta);
79 
80 #if defined(DEFINE_INLINES) || USE_INLINE
81 INLINE void vterm_rect_move(VTermRect *rect, int row_delta, int col_delta)
82 {
83   rect->start_row += row_delta; rect->end_row += row_delta;
84   rect->start_col += col_delta; rect->end_col += col_delta;
85 }
86 #endif
87 
88 // The ansi_index is used for the lower 16 colors, which can be set to any
89 // color.
90 #define VTERM_ANSI_INDEX_DEFAULT 0	// color cleared
91 #define VTERM_ANSI_INDEX_MIN 1
92 #define VTERM_ANSI_INDEX_MAX 16
93 #define VTERM_ANSI_INDEX_NONE 255	// non-ANSI color, use red/green/blue
94 
95 typedef struct {
96   uint8_t red, green, blue;
97   uint8_t ansi_index;
98 } VTermColor;
99 
100 typedef enum {
101   // VTERM_VALUETYPE_NONE = 0
102   VTERM_VALUETYPE_BOOL = 1,
103   VTERM_VALUETYPE_INT,
104   VTERM_VALUETYPE_STRING,
105   VTERM_VALUETYPE_COLOR,
106 
107   VTERM_N_VALUETYPES
108 } VTermValueType;
109 
110 typedef union {
111   int boolean;
112   int number;
113   char *string;
114   VTermColor color;
115 } VTermValue;
116 
117 typedef enum {
118   // VTERM_ATTR_NONE = 0
119   VTERM_ATTR_BOLD = 1,   // bool:   1, 22
120   VTERM_ATTR_UNDERLINE,  // number: 4, 21, 24
121   VTERM_ATTR_ITALIC,     // bool:   3, 23
122   VTERM_ATTR_BLINK,      // bool:   5, 25
123   VTERM_ATTR_REVERSE,    // bool:   7, 27
124   VTERM_ATTR_STRIKE,     // bool:   9, 29
125   VTERM_ATTR_FONT,       // number: 10-19
126   VTERM_ATTR_FOREGROUND, // color:  30-39 90-97
127   VTERM_ATTR_BACKGROUND, // color:  40-49 100-107
128 
129   VTERM_N_ATTRS
130 } VTermAttr;
131 
132 typedef enum {
133   // VTERM_PROP_NONE = 0
134   VTERM_PROP_CURSORVISIBLE = 1, // bool
135   VTERM_PROP_CURSORBLINK,       // bool
136   VTERM_PROP_ALTSCREEN,         // bool
137   VTERM_PROP_TITLE,             // string
138   VTERM_PROP_ICONNAME,          // string
139   VTERM_PROP_REVERSE,           // bool
140   VTERM_PROP_CURSORSHAPE,       // number
141   VTERM_PROP_MOUSE,             // number
142   VTERM_PROP_CURSORCOLOR,       // string
143 
144   VTERM_N_PROPS
145 } VTermProp;
146 
147 enum {
148   VTERM_PROP_CURSORSHAPE_BLOCK = 1,
149   VTERM_PROP_CURSORSHAPE_UNDERLINE,
150   VTERM_PROP_CURSORSHAPE_BAR_LEFT,
151 
152   VTERM_N_PROP_CURSORSHAPES
153 };
154 
155 enum {
156   VTERM_PROP_MOUSE_NONE = 0,
157   VTERM_PROP_MOUSE_CLICK,
158   VTERM_PROP_MOUSE_DRAG,
159   VTERM_PROP_MOUSE_MOVE,
160 
161   VTERM_N_PROP_MOUSES
162 };
163 
164 typedef struct {
165   const uint32_t *chars;
166   int             width;
167   unsigned int    protected_cell:1;  // DECSCA-protected against DECSEL/DECSED
168   unsigned int    dwl:1;             // DECDWL or DECDHL double-width line
169   unsigned int    dhl:2;             // DECDHL double-height line (1=top 2=bottom)
170 } VTermGlyphInfo;
171 
172 typedef struct {
173   unsigned int    doublewidth:1;     // DECDWL or DECDHL line
174   unsigned int    doubleheight:2;    // DECDHL line (1=top 2=bottom)
175 } VTermLineInfo;
176 
177 typedef struct {
178   // libvterm relies on the allocated memory to be zeroed out before it is
179   // returned by the allocator.
180   void *(*malloc)(size_t size, void *allocdata);
181   void  (*free)(void *ptr, void *allocdata);
182 } VTermAllocatorFunctions;
183 
184 void vterm_check_version(int major, int minor);
185 
186 // Allocate and initialize a new terminal with default allocators.
187 VTerm *vterm_new(int rows, int cols);
188 
189 // Allocate and initialize a new terminal with specified allocators.
190 VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions *funcs, void *allocdata);
191 
192 // Free and cleanup a terminal and all its data.
193 void   vterm_free(VTerm* vt);
194 
195 // Get the current size of the terminal and store in "rowsp" and "colsp".
196 void vterm_get_size(const VTerm *vt, int *rowsp, int *colsp);
197 
198 void vterm_set_size(VTerm *vt, int rows, int cols);
199 
200 int  vterm_get_utf8(const VTerm *vt);
201 void vterm_set_utf8(VTerm *vt, int is_utf8);
202 
203 size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len);
204 
205 /* Setting output callback will override the buffer logic */
206 typedef void VTermOutputCallback(const char *s, size_t len, void *user);
207 void vterm_output_set_callback(VTerm *vt, VTermOutputCallback *func, void *user);
208 
209 /* These buffer functions only work if output callback is NOT set
210  * These are deprecated and will be removed in a later version */
211 size_t vterm_output_get_buffer_size(const VTerm *vt);
212 size_t vterm_output_get_buffer_current(const VTerm *vt);
213 size_t vterm_output_get_buffer_remaining(const VTerm *vt);
214 
215 /* This too */
216 size_t vterm_output_read(VTerm *vt, char *buffer, size_t len);
217 
218 int vterm_is_modify_other_keys(VTerm *vt);
219 void vterm_keyboard_unichar(VTerm *vt, uint32_t c, VTermModifier mod);
220 void vterm_keyboard_key(VTerm *vt, VTermKey key, VTermModifier mod);
221 
222 void vterm_keyboard_start_paste(VTerm *vt);
223 void vterm_keyboard_end_paste(VTerm *vt);
224 
225 void vterm_mouse_move(VTerm *vt, int row, int col, VTermModifier mod);
226 // "button" is 1 for left, 2 for middle, 3 for right.
227 // Button 4 is scroll wheel down, button 5 is scroll wheel up.
228 void vterm_mouse_button(VTerm *vt, int button, int pressed, VTermModifier mod);
229 
230 // ------------
231 // Parser layer
232 // ------------
233 
234 // Flag to indicate non-final subparameters in a single CSI parameter.
235 // Consider
236 //   CSI 1;2:3:4;5a
237 // 1 4 and 5 are final.
238 // 2 and 3 are non-final and will have this bit set
239 //
240 // Don't confuse this with the final byte of the CSI escape; 'a' in this case.
241 #define CSI_ARG_FLAG_MORE (1U<<31)
242 #define CSI_ARG_MASK      (~(1U<<31))
243 
244 #define CSI_ARG_HAS_MORE(a) ((a) & CSI_ARG_FLAG_MORE)
245 #define CSI_ARG(a)          ((a) & CSI_ARG_MASK)
246 
247 // Can't use -1 to indicate a missing argument; use this instead
248 #define CSI_ARG_MISSING ((1<<30)-1)
249 
250 #define CSI_ARG_IS_MISSING(a) (CSI_ARG(a) == CSI_ARG_MISSING)
251 #define CSI_ARG_OR(a,def)     (CSI_ARG(a) == CSI_ARG_MISSING ? (def) : CSI_ARG(a))
252 #define CSI_ARG_COUNT(a)      (CSI_ARG(a) == CSI_ARG_MISSING || CSI_ARG(a) == 0 ? 1 : CSI_ARG(a))
253 
254 typedef struct {
255   int (*text)(const char *bytes, size_t len, void *user);
256   int (*control)(unsigned char control, void *user);
257   int (*escape)(const char *bytes, size_t len, void *user);
258   int (*csi)(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user);
259   int (*osc)(const char *command, size_t cmdlen, void *user);
260   int (*dcs)(const char *command, size_t cmdlen, void *user);
261   int (*resize)(int rows, int cols, void *user);
262 } VTermParserCallbacks;
263 
264 void  vterm_parser_set_callbacks(VTerm *vt, const VTermParserCallbacks *callbacks, void *user);
265 void *vterm_parser_get_cbdata(VTerm *vt);
266 
267 // -----------
268 // State layer
269 // -----------
270 
271 typedef struct {
272   int (*putglyph)(VTermGlyphInfo *info, VTermPos pos, void *user);
273   int (*movecursor)(VTermPos pos, VTermPos oldpos, int visible, void *user);
274   int (*scrollrect)(VTermRect rect, int downward, int rightward, void *user);
275   int (*moverect)(VTermRect dest, VTermRect src, void *user);
276   int (*erase)(VTermRect rect, int selective, void *user);
277   int (*initpen)(void *user);
278   int (*setpenattr)(VTermAttr attr, VTermValue *val, void *user);
279   // Callback for setting various properties.  Must return 1 if the property
280   // was accepted, 0 otherwise.
281   int (*settermprop)(VTermProp prop, VTermValue *val, void *user);
282   int (*bell)(void *user);
283   int (*resize)(int rows, int cols, VTermPos *delta, void *user);
284   int (*setlineinfo)(int row, const VTermLineInfo *newinfo, const VTermLineInfo *oldinfo, void *user);
285 } VTermStateCallbacks;
286 
287 typedef struct {
288   VTermPos pos;
289   int	   buttons;
290 #define MOUSE_BUTTON_LEFT 0x01
291 #define MOUSE_BUTTON_MIDDLE 0x02
292 #define MOUSE_BUTTON_RIGHT 0x04
293   int      flags;
294 #define MOUSE_WANT_CLICK 0x01
295 #define MOUSE_WANT_DRAG  0x02
296 #define MOUSE_WANT_MOVE  0x04
297   // useful to add protocol?
298 } VTermMouseState;
299 
300 VTermState *vterm_obtain_state(VTerm *vt);
301 
302 void  vterm_state_set_callbacks(VTermState *state, const VTermStateCallbacks *callbacks, void *user);
303 void *vterm_state_get_cbdata(VTermState *state);
304 
305 // Only invokes control, csi, osc, dcs
306 void  vterm_state_set_unrecognised_fallbacks(VTermState *state, const VTermParserCallbacks *fallbacks, void *user);
307 void *vterm_state_get_unrecognised_fbdata(VTermState *state);
308 
309 // Initialize the state.
310 void vterm_state_reset(VTermState *state, int hard);
311 
312 void vterm_state_get_cursorpos(const VTermState *state, VTermPos *cursorpos);
313 void vterm_state_get_mousestate(const VTermState *state, VTermMouseState *mousestate);
314 void vterm_state_get_default_colors(const VTermState *state, VTermColor *default_fg, VTermColor *default_bg);
315 void vterm_state_get_palette_color(const VTermState *state, int index, VTermColor *col);
316 void vterm_state_set_default_colors(VTermState *state, const VTermColor *default_fg, const VTermColor *default_bg);
317 void vterm_state_set_palette_color(VTermState *state, int index, const VTermColor *col);
318 void vterm_state_set_bold_highbright(VTermState *state, int bold_is_highbright);
319 int  vterm_state_get_penattr(const VTermState *state, VTermAttr attr, VTermValue *val);
320 int  vterm_state_set_termprop(VTermState *state, VTermProp prop, VTermValue *val);
321 void vterm_state_focus_in(VTermState *state);
322 void vterm_state_focus_out(VTermState *state);
323 const VTermLineInfo *vterm_state_get_lineinfo(const VTermState *state, int row);
324 
325 // ------------
326 // Screen layer
327 // ------------
328 
329 typedef struct {
330     unsigned int bold      : 1;
331     unsigned int underline : 2;
332     unsigned int italic    : 1;
333     unsigned int blink     : 1;
334     unsigned int reverse   : 1;
335     unsigned int strike    : 1;
336     unsigned int font      : 4; // 0 to 9
337     unsigned int dwl       : 1; // On a DECDWL or DECDHL line
338     unsigned int dhl       : 2; // On a DECDHL line (1=top 2=bottom)
339 } VTermScreenCellAttrs;
340 
341 enum {
342   VTERM_UNDERLINE_OFF,
343   VTERM_UNDERLINE_SINGLE,
344   VTERM_UNDERLINE_DOUBLE,
345   VTERM_UNDERLINE_CURLY,
346 };
347 
348 typedef struct {
349 #define VTERM_MAX_CHARS_PER_CELL 6
350   uint32_t chars[VTERM_MAX_CHARS_PER_CELL];
351   char     width;
352   VTermScreenCellAttrs attrs;
353   VTermColor fg, bg;
354 } VTermScreenCell;
355 
356 // All fields are optional, NULL when not used.
357 typedef struct {
358   int (*damage)(VTermRect rect, void *user);
359   int (*moverect)(VTermRect dest, VTermRect src, void *user);
360   int (*movecursor)(VTermPos pos, VTermPos oldpos, int visible, void *user);
361   int (*settermprop)(VTermProp prop, VTermValue *val, void *user);
362   int (*bell)(void *user);
363   int (*resize)(int rows, int cols, void *user);
364   // A line was pushed off the top of the window.
365   // "cells[cols]" contains the cells of that line.
366   // Return value is unused.
367   int (*sb_pushline)(int cols, const VTermScreenCell *cells, void *user);
368   int (*sb_popline)(int cols, VTermScreenCell *cells, void *user);
369 } VTermScreenCallbacks;
370 
371 // Return the screen of the vterm.
372 VTermScreen *vterm_obtain_screen(VTerm *vt);
373 
374 /*
375  * Install screen callbacks.  These are invoked when the screen contents is
376  * changed.  "user" is passed into to the callback.
377  */
378 void  vterm_screen_set_callbacks(VTermScreen *screen, const VTermScreenCallbacks *callbacks, void *user);
379 void *vterm_screen_get_cbdata(VTermScreen *screen);
380 
381 // Only invokes control, csi, osc, dcs
382 void  vterm_screen_set_unrecognised_fallbacks(VTermScreen *screen, const VTermParserCallbacks *fallbacks, void *user);
383 void *vterm_screen_get_unrecognised_fbdata(VTermScreen *screen);
384 
385 // Enable support for using the alternate screen if "altscreen" is non-zero.
386 // Before that switching to the alternate screen won't work.
387 // Calling with "altscreen" zero has no effect.
388 void vterm_screen_enable_altscreen(VTermScreen *screen, int altscreen);
389 
390 typedef enum {
391   VTERM_DAMAGE_CELL,    // every cell
392   VTERM_DAMAGE_ROW,     // entire rows
393   VTERM_DAMAGE_SCREEN,  // entire screen
394   VTERM_DAMAGE_SCROLL,  // entire screen + scrollrect
395 
396   VTERM_N_DAMAGES
397 } VTermDamageSize;
398 
399 // Invoke the relevant callbacks to update the screen.
400 void vterm_screen_flush_damage(VTermScreen *screen);
401 
402 void vterm_screen_set_damage_merge(VTermScreen *screen, VTermDamageSize size);
403 
404 /*
405  * Reset the screen.  Also invokes vterm_state_reset().
406  * Must be called before the terminal can be used.
407  */
408 void   vterm_screen_reset(VTermScreen *screen, int hard);
409 
410 // Neither of these functions NUL-terminate the buffer
411 size_t vterm_screen_get_chars(const VTermScreen *screen, uint32_t *chars, size_t len, const VTermRect rect);
412 size_t vterm_screen_get_text(const VTermScreen *screen, char *str, size_t len, const VTermRect rect);
413 
414 typedef enum {
415   VTERM_ATTR_BOLD_MASK       = 1 << 0,
416   VTERM_ATTR_UNDERLINE_MASK  = 1 << 1,
417   VTERM_ATTR_ITALIC_MASK     = 1 << 2,
418   VTERM_ATTR_BLINK_MASK      = 1 << 3,
419   VTERM_ATTR_REVERSE_MASK    = 1 << 4,
420   VTERM_ATTR_STRIKE_MASK     = 1 << 5,
421   VTERM_ATTR_FONT_MASK       = 1 << 6,
422   VTERM_ATTR_FOREGROUND_MASK = 1 << 7,
423   VTERM_ATTR_BACKGROUND_MASK = 1 << 8,
424 
425   VTERM_ALL_ATTRS_MASK = (1 << 9) - 1
426 } VTermAttrMask;
427 
428 int vterm_screen_get_attrs_extent(const VTermScreen *screen, VTermRect *extent, VTermPos pos, VTermAttrMask attrs);
429 
430 int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCell *cell);
431 
432 int vterm_screen_is_eol(const VTermScreen *screen, VTermPos pos);
433 
434 // ---------
435 // Utilities
436 // ---------
437 
438 VTermValueType vterm_get_attr_type(VTermAttr attr);
439 VTermValueType vterm_get_prop_type(VTermProp prop);
440 
441 void vterm_scroll_rect(VTermRect rect,
442                        int downward,
443                        int rightward,
444                        int (*moverect)(VTermRect src, VTermRect dest, void *user),
445                        int (*eraserect)(VTermRect rect, int selective, void *user),
446                        void *user);
447 
448 void vterm_copy_cells(VTermRect dest,
449                       VTermRect src,
450                       void (*copycell)(VTermPos dest, VTermPos src, void *user),
451                       void *user);
452 
453 #ifdef __cplusplus
454 }
455 #endif
456 
457 #endif
458