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 typedef struct VTermEncoding VTermEncoding;
15 
16 typedef struct {
17   VTermEncoding *enc;
18 
19   // This size should be increased if required by other stateful encodings
20   char           data[4*sizeof(uint32_t)];
21 } VTermEncodingInstance;
22 
23 struct VTermPen
24 {
25   VTermColor fg;
26   VTermColor bg;
27   unsigned int bold:1;
28   unsigned int underline:2;
29   unsigned int italic:1;
30   unsigned int blink:1;
31   unsigned int reverse:1;
32   unsigned int strike:1;
33   unsigned int font:4; /* To store 0-9 */
34 };
35 
vterm_color_equal(VTermColor a,VTermColor b)36 static inline int vterm_color_equal(VTermColor a, VTermColor b)
37 {
38   return a.red == b.red && a.green == b.green && a.blue == b.blue;
39 }
40 
41 struct VTermState
42 {
43   VTerm *vt;
44 
45   const VTermStateCallbacks *callbacks;
46   void *cbdata;
47 
48   int rows;
49   int cols;
50 
51   /* Current cursor position */
52   VTermPos pos;
53 
54   int at_phantom; /* True if we're on the "81st" phantom column to defer a wraparound */
55 
56   int scrollregion_top;
57   int scrollregion_bottom; /* -1 means unbounded */
58 #define SCROLLREGION_BOTTOM(state) ((state)->scrollregion_bottom > -1 ? (state)->scrollregion_bottom : (state)->rows)
59   int scrollregion_left;
60 #define SCROLLREGION_LEFT(state)  ((state)->mode.leftrightmargin ? (state)->scrollregion_left : 0)
61   int scrollregion_right; /* -1 means unbounded */
62 #define SCROLLREGION_RIGHT(state) ((state)->mode.leftrightmargin && (state)->scrollregion_right > -1 ? (state)->scrollregion_right : (state)->cols)
63 
64   /* Bitvector of tab stops */
65   unsigned char *tabstops;
66 
67   VTermLineInfo *lineinfo;
68 #define ROWWIDTH(state,row) ((state)->lineinfo[(row)].doublewidth ? ((state)->cols / 2) : (state)->cols)
69 #define THISROWWIDTH(state) ROWWIDTH(state, (state)->pos.row)
70 
71   /* Mouse state */
72   int mouse_col, mouse_row;
73   int mouse_buttons;
74   int mouse_flags;
75   enum { MOUSE_X10, MOUSE_UTF8, MOUSE_SGR, MOUSE_RXVT } mouse_protocol;
76 
77   /* Last glyph output, for Unicode recombining purposes */
78   uint32_t *combine_chars;
79   size_t combine_chars_size; // Number of ELEMENTS in the above
80   int combine_width; // The width of the glyph above
81   VTermPos combine_pos;   // Position before movement
82 
83   struct {
84     int keypad:1;
85     int cursor:1;
86     int autowrap:1;
87     int insert:1;
88     int newline:1;
89     int cursor_visible:1;
90     int cursor_blink:1;
91     unsigned int cursor_shape:2;
92     int alt_screen:1;
93     int origin:1;
94     int screen:1;
95     int leftrightmargin:1;
96   } mode;
97 
98   VTermEncodingInstance encoding[4], encoding_utf8;
99   int gl_set, gr_set, gsingle_set;
100 
101   struct VTermPen pen;
102 
103   VTermColor default_fg;
104   VTermColor default_bg;
105   VTermColor colors[16]; // Store the 8 ANSI and the 8 ANSI high-brights only
106 
107   int fg_index;
108   int bg_index;
109   int bold_is_highbright;
110 
111   unsigned int protected_cell : 1;
112 
113   /* Saved state under DEC mode 1048/1049 */
114   struct {
115     VTermPos pos;
116     struct VTermPen pen;
117 
118     struct {
119       int cursor_visible:1;
120       int cursor_blink:1;
121       unsigned int cursor_shape:2;
122     } mode;
123   } saved;
124 };
125 
126 struct VTerm
127 {
128   VTermAllocatorFunctions *allocator;
129   void *allocdata;
130 
131   int rows;
132   int cols;
133 
134   struct {
135     int utf8:1;
136     int ctrl8bit:1;
137   } mode;
138 
139   enum VTermParserState {
140     NORMAL,
141     CSI,
142     OSC,
143     DCS,
144     ESC,
145     ESC_IN_OSC,
146     ESC_IN_DCS,
147   } parser_state;
148   const VTermParserCallbacks *parser_callbacks;
149   void *cbdata;
150 
151   /* len == malloc()ed size; cur == number of valid bytes */
152   char  *strbuffer;
153   size_t strbuffer_len;
154   size_t strbuffer_cur;
155 
156   char  *outbuffer;
157   size_t outbuffer_len;
158   size_t outbuffer_cur;
159 
160   VTermState *state;
161   VTermScreen *screen;
162 };
163 
164 struct VTermEncoding {
165   void (*init) (VTermEncoding *enc, void *data);
166   void (*decode)(VTermEncoding *enc, void *data,
167                  uint32_t cp[], int *cpi, int cplen,
168                  const char bytes[], size_t *pos, size_t len);
169 };
170 
171 typedef enum {
172   ENC_UTF8,
173   ENC_SINGLE_94
174 } VTermEncodingType;
175 
176 void *vterm_allocator_malloc(VTerm *vt, size_t size);
177 void  vterm_allocator_free(VTerm *vt, void *ptr);
178 
179 void vterm_push_output_bytes(VTerm *vt, const char *bytes, size_t len);
180 void vterm_push_output_vsprintf(VTerm *vt, const char *format, va_list args);
181 void vterm_push_output_sprintf(VTerm *vt, const char *format, ...);
182 void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, const char *fmt, ...);
183 void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...);
184 
185 void vterm_state_free(VTermState *state);
186 
187 void vterm_state_newpen(VTermState *state);
188 void vterm_state_resetpen(VTermState *state);
189 void vterm_state_setpen(VTermState *state, const long args[], int argcount);
190 int  vterm_state_getpen(VTermState *state, long args[], int argcount);
191 void vterm_state_savepen(VTermState *state, int save);
192 
193 enum {
194   C1_SS3 = 0x8f,
195   C1_DCS = 0x90,
196   C1_CSI = 0x9b,
197   C1_ST  = 0x9c,
198 };
199 
200 void vterm_state_push_output_sprintf_CSI(VTermState *vts, const char *format, ...);
201 
202 void vterm_screen_free(VTermScreen *screen);
203 
204 VTermEncoding *vterm_lookup_encoding(VTermEncodingType type, char designation);
205 
206 int vterm_unicode_width(int codepoint);
207 int vterm_unicode_is_combining(int codepoint);
208 
209 #endif
210