1 #ifndef __VTERM_INTERNAL_H__
2 #define __VTERM_INTERNAL_H__
3 
4 #include "vterm.h"
5 
6 #include <stdarg.h>
7 
8 #if defined(__GNUC__) && !defined(__MINGW32__)
9 # define INTERNAL __attribute__((visibility("internal")))
10 # define UNUSED __attribute__((unused))
11 #else
12 # define INTERNAL
13 # define UNUSED
14 #endif
15 
16 #ifdef DEBUG
17 # define DEBUG_LOG(s) fprintf(stderr, s)
18 # define DEBUG_LOG1(s, a) fprintf(stderr, s, a)
19 # define DEBUG_LOG2(s, a, b) fprintf(stderr, s, a, b)
20 # define DEBUG_LOG3(s, a, b, c) fprintf(stderr, s, a, b, c)
21 #else
22 # define DEBUG_LOG(s)
23 # define DEBUG_LOG1(s, a)
24 # define DEBUG_LOG2(s, a, b)
25 # define DEBUG_LOG3(s, a, b, c)
26 #endif
27 
28 #define ESC_S "\x1b"
29 
30 #define INTERMED_MAX 16
31 
32 #define CSI_ARGS_MAX 16
33 #define CSI_LEADER_MAX 16
34 
35 #define BUFIDX_PRIMARY   0
36 #define BUFIDX_ALTSCREEN 1
37 
38 typedef struct VTermEncoding VTermEncoding;
39 
40 typedef struct {
41   VTermEncoding *enc;
42 
43   // This size should be increased if required by other stateful encodings
44   char           data[4*sizeof(uint32_t)];
45 } VTermEncodingInstance;
46 
47 struct VTermPen
48 {
49   VTermColor fg;
50   VTermColor bg;
51   unsigned int bold:1;
52   unsigned int underline:2;
53   unsigned int italic:1;
54   unsigned int blink:1;
55   unsigned int reverse:1;
56   unsigned int conceal:1;
57   unsigned int strike:1;
58   unsigned int font:4; /* To store 0-9 */
59 };
60 
61 struct VTermState
62 {
63   VTerm *vt;
64 
65   const VTermStateCallbacks *callbacks;
66   void *cbdata;
67 
68   const VTermStateFallbacks *fallbacks;
69   void *fbdata;
70 
71   int rows;
72   int cols;
73 
74   /* Current cursor position */
75   VTermPos pos;
76 
77   int at_phantom; /* True if we're on the "81st" phantom column to defer a wraparound */
78 
79   int scrollregion_top;
80   int scrollregion_bottom; /* -1 means unbounded */
81 #define SCROLLREGION_BOTTOM(state) ((state)->scrollregion_bottom > -1 ? (state)->scrollregion_bottom : (state)->rows)
82   int scrollregion_left;
83 #define SCROLLREGION_LEFT(state)  ((state)->mode.leftrightmargin ? (state)->scrollregion_left : 0)
84   int scrollregion_right; /* -1 means unbounded */
85 #define SCROLLREGION_RIGHT(state) ((state)->mode.leftrightmargin && (state)->scrollregion_right > -1 ? (state)->scrollregion_right : (state)->cols)
86 
87   /* Bitvector of tab stops */
88   unsigned char *tabstops;
89 
90   /* Primary and Altscreen; lineinfos[1] is lazily allocated as needed */
91   VTermLineInfo *lineinfos[2];
92 
93   /* lineinfo will == lineinfos[0] or lineinfos[1], depending on altscreen */
94   VTermLineInfo *lineinfo;
95 #define ROWWIDTH(state,row) ((state)->lineinfo[(row)].doublewidth ? ((state)->cols / 2) : (state)->cols)
96 #define THISROWWIDTH(state) ROWWIDTH(state, (state)->pos.row)
97 
98   /* Mouse state */
99   int mouse_col, mouse_row;
100   int mouse_buttons;
101   int mouse_flags;
102 
103   enum { MOUSE_X10, MOUSE_UTF8, MOUSE_SGR, MOUSE_RXVT } mouse_protocol;
104 
105   /* Last glyph output, for Unicode recombining purposes */
106   uint32_t *combine_chars;
107   size_t combine_chars_size; // Number of ELEMENTS in the above
108   int combine_width; // The width of the glyph above
109   VTermPos combine_pos;   // Position before movement
110 
111   struct {
112     unsigned int keypad:1;
113     unsigned int cursor:1;
114     unsigned int autowrap:1;
115     unsigned int insert:1;
116     unsigned int newline:1;
117     unsigned int cursor_visible:1;
118     unsigned int cursor_blink:1;
119     unsigned int cursor_shape:2;
120     unsigned int alt_screen:1;
121     unsigned int origin:1;
122     unsigned int screen:1;
123     unsigned int leftrightmargin:1;
124     unsigned int bracketpaste:1;
125     unsigned int report_focus:1;
126     unsigned int modify_other_keys:1;
127   } mode;
128 
129   VTermEncodingInstance encoding[4], encoding_utf8;
130   int gl_set, gr_set, gsingle_set;
131 
132   struct VTermPen pen;
133 
134   VTermColor default_fg;
135   VTermColor default_bg;
136   VTermColor colors[16]; // Store the 8 ANSI and the 8 ANSI high-brights only
137 
138   int bold_is_highbright;
139 
140   unsigned int protected_cell : 1;
141 
142   /* Saved state under DEC mode 1048/1049 */
143   struct {
144     VTermPos pos;
145     struct VTermPen pen;
146 
147     struct {
148       unsigned int cursor_visible:1;
149       unsigned int cursor_blink:1;
150       unsigned int cursor_shape:2;
151     } mode;
152   } saved;
153 
154   /* Temporary state for DECRQSS parsing */
155   union {
156     char decrqss[4];
157   } tmp;
158 };
159 
160 struct VTerm
161 {
162   VTermAllocatorFunctions *allocator;
163   void *allocdata;
164 
165   int rows;
166   int cols;
167 
168   struct {
169     unsigned int utf8:1;
170     unsigned int ctrl8bit:1;
171   } mode;
172 
173   struct {
174     enum VTermParserState {
175       NORMAL,
176       CSI_LEADER,
177       CSI_ARGS,
178       CSI_INTERMED,
179       DCS_COMMAND,
180       /* below here are the "string states" */
181       OSC_COMMAND,
182       OSC,
183       DCS,
184     } state;
185 
186     unsigned int in_esc : 1;
187 
188     int intermedlen;
189     char intermed[INTERMED_MAX];
190 
191     union {
192       struct {
193         int leaderlen;
194         char leader[CSI_LEADER_MAX];
195 
196         int argi;
197         long args[CSI_ARGS_MAX];
198       } csi;
199       struct {
200         int command;
201       } osc;
202       struct {
203         int commandlen;
204         char command[CSI_LEADER_MAX];
205       } dcs;
206     } v;
207 
208     const VTermParserCallbacks *callbacks;
209     void *cbdata;
210 
211     int string_initial;
212   } parser;
213 
214   /* len == malloc()ed size; cur == number of valid bytes */
215 
216   VTermOutputCallback *outfunc;
217   void                *outdata;
218 
219   char  *outbuffer;
220   size_t outbuffer_len;
221   size_t outbuffer_cur;
222 
223   char  *tmpbuffer;
224   size_t tmpbuffer_len;
225 
226   VTermState *state;
227   VTermScreen *screen;
228 
229   int in_backspace;
230 };
231 
232 struct VTermEncoding {
233   void (*init) (VTermEncoding *enc, void *data);
234   void (*decode)(VTermEncoding *enc, void *data,
235                  uint32_t cp[], int *cpi, int cplen,
236                  const char bytes[], size_t *pos, size_t len);
237 };
238 
239 typedef enum {
240   ENC_UTF8,
241   ENC_SINGLE_94
242 } VTermEncodingType;
243 
244 void *vterm_allocator_malloc(VTerm *vt, size_t size);
245 void  vterm_allocator_free(VTerm *vt, void *ptr);
246 
247 void vterm_push_output_bytes(VTerm *vt, const char *bytes, size_t len);
248 void vterm_push_output_vsprintf(VTerm *vt, const char *format, va_list args);
249 void vterm_push_output_sprintf(VTerm *vt, const char *format, ...);
250 void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, const char *fmt, ...);
251 void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...);
252 
253 void vterm_state_free(VTermState *state);
254 
255 void vterm_state_newpen(VTermState *state);
256 void vterm_state_resetpen(VTermState *state);
257 void vterm_state_setpen(VTermState *state, const long args[], int argcount);
258 int  vterm_state_getpen(VTermState *state, long args[], int argcount);
259 void vterm_state_savepen(VTermState *state, int save);
260 
261 enum {
262   C1_SS3 = 0x8f,
263   C1_DCS = 0x90,
264   C1_CSI = 0x9b,
265   C1_ST  = 0x9c,
266   C1_OSC = 0x9d,
267 };
268 
269 void vterm_state_push_output_sprintf_CSI(VTermState *vts, const char *format, ...);
270 
271 void vterm_screen_free(VTermScreen *screen);
272 
273 VTermEncoding *vterm_lookup_encoding(VTermEncodingType type, char designation);
274 
275 int vterm_unicode_width(uint32_t codepoint);
276 int vterm_unicode_is_combining(uint32_t codepoint);
277 int vterm_unicode_is_ambiguous(uint32_t codepoint);
278 int vterm_get_special_pty_type(void);
279 
280 #if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) \
281 	|| defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE)
282 # undef VSNPRINTF
283 # define VSNPRINTF vsnprintf
284 # undef SNPRINTF
285 #else
286 # ifdef VSNPRINTF
287 // Use a provided vsnprintf() function.
288 int VSNPRINTF(char *str, size_t str_m, const char *fmt, va_list ap);
289 # endif
290 # ifdef SNPRINTF
291 // Use a provided snprintf() function.
292 int SNPRINTF(char *str, size_t str_m, const char *fmt, ...);
293 # endif
294 #endif
295 #ifndef SNPRINTF
296 # define SNPRINTF snprintf
297 #endif
298 
299 
300 #endif
301