1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
|
#pragma once
#include <u.h>
#include <libn.h>
#include <termios.h>
#include <unibilium.h>
#define iota(x) 1 << (x)
typedef struct RGB8 RGB8;
typedef struct Pen Pen;
typedef struct Dot Dot;
typedef struct Cell Cell;
typedef struct Row Row;
typedef struct Buffer Buffer;
typedef struct Window Window;
typedef struct Node Node;
typedef struct Key Key;
typedef struct Input Input;
typedef struct Term Term;
struct RGB8
{
uint8 r, g, b;
};
enum
{
PenNormal = 0,
PenBold = iota(0),
PenDim = iota(1),
PenInvis = iota(2),
PenItalic = iota(3),
PenReverse = iota(4),
PenStrike = iota(5),
PenUnderline = iota(6),
PenBlink = iota(7),
/* ... */
PenRGB = iota(15),
};
struct Pen
{
ushort state;
union {
/* 256 color (legacy) */
struct {
sshort fg : 8, bg : 8; /* 0 - 255 or COLOUR_DEFAULT */
} col;
/* true color (modern) */
struct {
RGB8 fg, bg;
} rgb;
};
};
/* outputs */
struct Cell
{
rune txt;
Pen pen;
};
struct Row
{
Cell *cells;
uint dirty : 1;
};
struct Dot
{
int row, col;
};
/*
* scroll.top & scroll.bot are pointers into the viewport.
*
* scroll back buffer
*
* scroll.buf->+----------------+-----+
* | | | ^ \
* | before | | | |
* current terminal content | viewport | | | |
* | | | |
* +----------------+-----+\ | | | s > scroll.above
* ^ | | i | \ | | i | c |
* | | | n | \ | | n | r |
* | | v | \ | | v | o |
* | | i | \ | | i | l /
* | buffer | s | >|<- scroll.index | s | l \
* h | | i | / | | i | |
* | | b | / | after | b | s > scroll.below
* | | l | / | viewport | l | i |
* v | | e | / | | e | z /
* +----------------+-----+/ | unused | | e
* <- maxw -> | scroll back | |
* <- w -> | buffer | | |
* | | | |
* | | | v
* scroll.buf + scroll.size->+----------------+-----+
* <- maxw ->
* <- w ->
*/
struct Buffer
{
int w, h; /* dimension of buffer */
Pen pen; /* default attributes */
int maxw; /* allocated cells (maximal cols over time) */
Row *row; /* array of row pointers of size 'h' */
struct {
Row *buf;
Row *top;
Row *bot;
int size;
int index;
int above;
int below;
} scroll;
Dot cur, save; /* cursor position within buffer */
};
struct Window
{
struct Buffer;
int top, left;
uchar curvis : 1;
uchar blink : 2;
Window *parent, *child, *link;
};
/* input */
struct Key
{
int type;
int mods;
uchar utf8[UTFmax+1];
union {
rune pt;
int num;
int sym;
char mouse[4];
} code;
};
struct KeyInfo
{
int type;
int sym;
int modmask;
int modset;
};
struct Input
{
int fd;
int flags;
int wait; /* in ms */
/* modifiers */
uchar closed : 1;
uchar started : 1;
uchar hasold : 1;
struct termios oldterm;
/* buffer */
struct {
long off;
uchar *b, *c, *e, bytes[256];
} rbuf;
struct {
uchar *s, bytes[256];
} ebuf;
/* key data */
Node *keys;
struct KeyInfo c0[32];
};
struct Term
{
/* meta data */
char *name;
unibi_term *info;
struct {
uchar altscreen : 1;
uchar cursorvis : 1;
uchar mouse : 1;
} mode;
struct {
uchar bce : 1;
int colors;
} cap;
/* input capture */
Input input;
/* output display */
Window *root;
Pen pen;
/* raw text to pty */
int fd;
struct {
char *c, b[512];
} buf;
struct {
int len;
char *b;
} tmp;
/* info */
struct {
/* Positioning */
char *cup; // cursor_address
char *vpa; // row_address == vertical position absolute
char *hpa; // column_address = horizontal position absolute
/* Moving */
char *cuu; char *cuu1; // Cursor Up
char *cud; char *cud1; // Cursor Down
char *cuf; char *cuf1; // Cursor Forward == Right
char *cub; char *cub1; // Cursor Backward == Left
/* Editing */
char *ich; char *ich1; // Insert Character
char *dch; char *dch1; // Delete Character
char *il; char *il1; // Insert Line
char *dl; char *dl1; // Delete Line
char *ech; // Erase Character
char *ed2; // Erase Data 2 == Clear screen
char *stbm; // Set Top/Bottom Margins
/* formatting */
char *sgr; // Select Graphic Rendition
char *sgr0; // Exit Attribute Mode
char *sgr_i0, *sgr_i1; // SGR italic off/on
char *sgr_fg; // SGR foreground colour
char *sgr_bg; // SGR background colour
/* Mode setting/clearing */
char *sm_csr; char *rm_csr; // Set/reset mode: Cursor visible
/* augmentations to terminfo */
struct {
char *rgbf; // rgb foreground
char *rgbb; // rgb background
char *smxx; // strikethrough
char *smulx; // curly underline
} ext;
} esc;
Term *link;
};
/* functions */
void tresize(Term *t);
Window *wmake(Window *root, int top, int left, int w, int h, int scroll);
void wresize(Window *root, int w, int h);
void wputrune(Window *win, rune r);
void wscroll(Window *win, int s);
|