aboutsummaryrefslogtreecommitdiff
path: root/sys/libterm/term.h
blob: 6bd2f6b26a4dc71256937f73d49bef22fe99251b (plain)
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);