aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/dvtm/term.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/dvtm/term.h')
-rw-r--r--sys/cmd/dvtm/term.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/sys/cmd/dvtm/term.h b/sys/cmd/dvtm/term.h
new file mode 100644
index 0000000..3102458
--- /dev/null
+++ b/sys/cmd/dvtm/term.h
@@ -0,0 +1,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);