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