#pragma once #include #include #include #include #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);