aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/dvtm/term.h
blob: 31024584a83327b2543fd84b48e907a1d84f4ae1 (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
#pragma once

#include <u.h>
#include <libn.h>

#define iota(x) 1 << (x)

typedef struct RGB8   RGB8;
typedef struct Pen    Pen;
typedef struct Cell   Cell;
typedef struct Row    Row;
typedef struct Buffer Buffer;

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),
    /* ... */
    PenTC        = iota(15),
};

struct Pen
{
    ushort state;
    ushort color;
    union {
        /* 256 color (legacy) */
        struct {
            sshort fg : 8, bg : 8; /* 0 - 255 or COLOUR_DEFAULT */
        } col;
        /* true color (modern) */
        struct {
            RGB8 fg, bg;
        } rgb;
    };
};

struct Cell {
    rune r;
    Pen  pen;
}; 

struct Row {
	Cell *cells;
	uint dirty:1;
};

/* Buffer holding the current window content (as an array) as well
 * as the scroll back buffer content (as a circular/ring buffer).
 *
 * If new content is added to terminal the view port slides down and the
 * previously top most line is moved into the scroll back buffer at postion
 * scroll.index. This index will eventually wrap around and thus overwrite
 * the oldest lines.
 *
 * In the scenerio below a scroll up has been performed. That is 'scroll.above'
 * lines still lie above the current view port. Further scrolling up will show
 * them. Similarly 'scroll.below' is the amount of lines below the current
 * viewport.
 *
 * The function buffer_boundary sets the row pointers to the start/end range
 * of the section delimiting the region before/after the viewport. The functions
 * buffer_row_{first,last} return the first/last logical row. And
 * buffer_row_{next,prev} allows to iterate over the logical lines in either
 * direction.
 *
 *                                     scroll back buffer
 *
 *                      scroll_buf->+----------------+-----+
 *                                  |                |     | ^  \
 *                                  |     before     |     | |  |
 *    current terminal content      |    viewport    |     | |  |
 *                                  |                |     |    |
 *    +----------------+-----+\     |                |     | s   > scroll.above
 *  ^ |                |  i  | \    |                |  i  | c  |
 *  | |                |  n  |  \   |                |  n  | r  |
 *    |                |  v  |   \  |                |  v  | o  |
 *  r |                |  i  |    \ |                |  i  | l  /
 *  o |    viewport    |  s  |     >|<- scroll.index |  s  | l  \
 *  w |                |  i  |    / |                |  i  |    |
 *  s |                |  b  |   /  |     after      |  b  | s   > scroll.below
 *    |                |  l  |  /   |    viewport    |  l  | i  |
 *  v |                |  e  | /    |                |  e  | z  /
 *    +----------------+-----+/     |     unused     |     | e
 *     <-    maxcols      ->        |   scroll back  |     |
 *     <-    cols    ->             |     buffer     |     | |
 *                                  |                |     | |
 *                                  |                |     | v
 *          roll_buf + scroll.size->+----------------+-----+
 *                                   <-    maxcols       ->
 *                                   <-    cols    ->
 */

struct Buffer {
	Row  *lines;                /* array of Row pointers of size 'rows' */
	Row  *crow;                 /* row on which the cursor currently resides */
	bool *tabs;                /* a boolean flag for each column whether it is a tab */
    struct {
        Row *buf;              /* a ring buffer holding the scroll back content */
        Row *top;              /* row in lines where scrolling region starts */
        Row *bot;              /* row in lines where scrolling region ends */
        int size;              /* maximal capacity of scroll back buffer (in lines) */
        int index;             /* current index into the ring buffer */
        int above;             /* number of lines above current viewport */
        int below;             /* number of lines below current viewport */
    } scroll;
	int rows, cols;            /* current dimension of buffer */
	int maxcols;               /* allocated cells (maximal cols over time) */
};

/* exported functions */

void zero(Row *row, int start, int len);
void roll(Row *start, Row *end, int count);

void bclear(Buffer *b);
void bfree(Buffer *b);
void bscroll(Buffer *b, int s);
void bresize(Buffer *b, int rows, int cols);
bool binit(Buffer *b, int rows, int cols, int size);
void bboundary(Buffer *b, Row **bs, Row **be, Row **as, Row **ae) ;
Row *browfirst(Buffer *b);
Row *browlast(Buffer *b); 
Row *brownext(Buffer *b, Row *row);
Row *bprevrow(Buffer *b, Row *row);