aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/dvtm/term.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/dvtm/term.c')
-rw-r--r--sys/cmd/dvtm/term.c395
1 files changed, 0 insertions, 395 deletions
diff --git a/sys/cmd/dvtm/term.c b/sys/cmd/dvtm/term.c
deleted file mode 100644
index cda2bbe..0000000
--- a/sys/cmd/dvtm/term.c
+++ /dev/null
@@ -1,395 +0,0 @@
-#include "term.h"
-
-struct ExtraInfo
-{
- char *enteralt;
- char *exitalt;
-
- char *entermouse;
- char *exitmouse;
-};
-
-static
-struct ExtraInfo vt200 =
-{
- .enteralt = "\e[?1049h",
- .exitalt = "\e[?1049l",
-
- .entermouse = "\e[?1049h\e[?1006l",
- .exitmouse = "\e[?1002l\e[?1006l",
-};
-
-// -----------------------------------------------------------------------
-// database lookup
-
-static
-char*
-tryinfostr(Term *t, enum unibi_string s)
-{
- char *val = (char*)unibi_get_str(t->info, s);
- /* TODO: provide fallbacks */
- return val;
-}
-
-static
-char*
-guessinfostr(Term *t, enum unibi_string s, char *guess)
-{
- char *val = (char*)unibi_get_str(t->info, s);
- if (!val)
- return guess;
- return val;
-}
-
-static
-char*
-getinfostr(Term *t, enum unibi_string s)
-{
- char *val = tryinfostr(t, s);
- if (!val)
- panicf("required term info string '%s' missing", unibi_name_str(s));
-
- return val;
-}
-
-static
-char *
-tryextrastr(Term *t, char *name)
-{
- const char *nm;
- size_t max = unibi_count_ext_str(t->info);
- for (size_t i = 0; i < max; i++) {
- nm = unibi_get_ext_str_name(t->info, i);
- if (nm && !strcmp(nm, name)) {
- return (char *)nm;
- }
- }
- return nil;
-}
-
-static
-char *
-guessextrastr(Term *t, char *name, char *guess)
-{
- char *s;
- if ((s = tryextrastr(t, name)))
- return s;
-
- return guess;
-}
-
-static
-int
-tryextrabool(Term *t, char *name)
-{
- const char *nm;
- size_t max = unibi_count_ext_bool(t->info);
- for (size_t i = 0; i < max; i++) {
- nm = unibi_get_ext_bool_name(t->info, i);
- if (nm && !strcmp(nm, name)) {
- return (int)i;
- }
- }
- return -1;
-}
-
-/* formats escape strings and writes to output */
-static void tfmt(Term *t, char *esc, int n, ...);
-
-// -----------------------------------------------------------------------
-// exported pen methods
-
-// -----------------------------------------------------------------------
-// exported term methods
-
-static
-char *
-ttmpbuf(Term *t, int len)
-{
- if (t->tmp.len >= len)
- return t->tmp.b;
-
- /* TODO: error handling */
- return (t->tmp.b = realloc(t->tmp.b, len));
-}
-
-void
-tinit(Term *t)
-{
- t->name = getenv("TERM");
- t->info = unibi_from_term(t->name);
- if (!t->info)
- panicf("could not identify terminal");
-
- t->mode.mouse = 0;
- t->mode.cursorvis = 1;
- t->mode.altscreen = 0;
-
- t->cap.colors = unibi_get_num(t->info, unibi_max_colors);
- t->cap.bce = unibi_get_bool(t->info, unibi_back_color_erase);
-
- /* TODO */
- t->input = nil;
- t->root = nil;
- t->pen = (Pen){0};
-
- /* fill in buffers */
- t->buf.c = t->buf.b;
- t->tmp.b = nil;
- t->tmp.len = 0;
-
- /* get all term info format strings */
- t->esc.cup = getinfostr(t, unibi_cursor_address);
- t->esc.vpa = tryinfostr(t, unibi_row_address);
- t->esc.hpa = tryinfostr(t, unibi_column_address);
- t->esc.cuu = getinfostr(t, unibi_parm_up_cursor);
- t->esc.cuu1 = tryinfostr(t, unibi_cursor_up);
- t->esc.cud = getinfostr(t, unibi_parm_down_cursor);
- t->esc.cud1 = tryinfostr(t, unibi_cursor_down);
- t->esc.cuf = getinfostr(t, unibi_parm_right_cursor);
- t->esc.cuf1 = tryinfostr(t, unibi_cursor_right);
- t->esc.cub = getinfostr(t, unibi_parm_left_cursor);
- t->esc.cub1 = tryinfostr(t, unibi_cursor_left);
- t->esc.ich = getinfostr(t, unibi_parm_ich);
- t->esc.ich1 = tryinfostr(t, unibi_insert_character);
- t->esc.dch = getinfostr(t, unibi_parm_dch);
- t->esc.dch1 = tryinfostr(t, unibi_delete_character);
- t->esc.il = getinfostr(t, unibi_parm_insert_line);
- t->esc.il1 = tryinfostr(t, unibi_insert_line);
- t->esc.dl = getinfostr(t, unibi_parm_delete_line);
- t->esc.dl1 = tryinfostr(t, unibi_delete_line);
- t->esc.ech = getinfostr(t, unibi_erase_chars);
- t->esc.ed2 = getinfostr(t, unibi_clear_screen);
- t->esc.stbm = getinfostr(t, unibi_change_scroll_region);
- t->esc.sgr = getinfostr(t, unibi_set_attributes);
- t->esc.sgr0 = getinfostr(t, unibi_exit_attribute_mode);
- t->esc.sgr_i0 = tryinfostr(t, unibi_exit_italics_mode);
- t->esc.sgr_i1 = tryinfostr(t, unibi_enter_italics_mode);
- t->esc.sgr_fg = getinfostr(t, unibi_set_a_foreground);
- t->esc.sgr_bg = getinfostr(t, unibi_set_a_background);
- t->esc.sm_csr = getinfostr(t, unibi_cursor_normal);
- t->esc.rm_csr = getinfostr(t, unibi_cursor_invisible);
-
- /* extensions to terminfo */
- t->esc.ext.rgbf = guessextrastr(t, "setrgbf", "\x1b[38;2;%p1%d;%p2%d;%p3%dm");
- t->esc.ext.rgbb = guessextrastr(t, "setrgbb", "\x1b[48;2;%p1%d;%p2%d;%p3%dm");
-
- /* acs characters */
- t->acs.vline = tryinfostr(t, unibi_acs_vline);
- t->acs.hline = tryinfostr(t, unibi_acs_hline);
- t->acs.plus = tryinfostr(t, unibi_acs_plus);
- t->acs.ltee = tryinfostr(t, unibi_acs_ltee);
- t->acs.rtee = tryinfostr(t, unibi_acs_rtee);
- t->acs.ttee = tryinfostr(t, unibi_acs_ttee);
- t->acs.btee = tryinfostr(t, unibi_acs_btee);
- t->acs.ulcorner = tryinfostr(t, unibi_acs_ulcorner);
- t->acs.urcorner = tryinfostr(t, unibi_acs_urcorner);
- t->acs.llcorner = tryinfostr(t, unibi_acs_llcorner);
- t->acs.lrcorner = tryinfostr(t, unibi_acs_lrcorner);
-}
-
-void
-tfini(Term *t)
-{
- if (t->mode.mouse)
- twrite(t, 0, vt200.exitmouse);
- if (!t->mode.cursorvis)
- tfmt(t, t->esc.rm_csr, 0);
- if (t->mode.altscreen)
- twrite(t, 0, vt200.exitalt);
-
- tfmt(t, t->esc.sgr0, 0);
-}
-
-void
-tflush(Term *t)
-{
- if (t->fd != -1)
- write(t->fd, t->buf.b, t->buf.c - t->buf.b);
-
- t->buf.c = t->buf.b;
-}
-
-void
-twrite(Term *t, long len, char *s)
-{
- int n;
- if (!len)
- len = strlen(s);
-
- while (len > 0) {
- n = MIN(len, arrend(t->buf.b) - t->buf.c);
- memcpy(t->buf.c, s, n);
- t->buf.c += n;
- len -= n;
- tflush(t);
- }
-}
-
-void
-tsetpen(Term *t, Pen new)
-{
- int c;
- ushort ic, in;
- Pen cur = t->pen;
- if (!memcmp(&new, &cur, sizeof(new)))
- return;
-
- /* attributes */
- tfmt(t, t->esc.sgr, 9,
- 0, /* standout */
- new.state & PenUnderline,
- new.state & PenReverse,
- new.state & PenBlink,
- new.state & PenDim,
- new.state & PenBold,
- new.state & PenInvis,
- 0, /* protect */
- 0); /* alt */
-
- ic = cur.state & PenItalic;
- in = new.state & PenItalic;
- if (ic & ~in)
- tfmt(t, t->esc.sgr_i0, 0);
- else if (~ic & in)
- tfmt(t, t->esc.sgr_i1, 0);
-
- /* fg/bg color */
- /* TODO: add a check for if the terminal supports true color */
- /* TODO: add a check for negative indices */
- if (new.state & PenTrueClr) {
- tfmt(t, t->esc.ext.rgbf, 3, new.rgb.fg.r, new.rgb.fg.g, new.rgb.fg.b);
- tfmt(t, t->esc.ext.rgbb, 3, new.rgb.bg.r, new.rgb.bg.g, new.rgb.bg.b);
- } else {
- tfmt(t, t->esc.sgr_fg, 1, new.col.fg);
- tfmt(t, t->esc.sgr_bg, 1, new.col.bg);
- }
-
- t->pen = new;
-}
-
-static
-void
-tfmt(Term *t, char *esc, int n, ...)
-{
- int i;
- long len;
- va_list args;
- unibi_var_t param[9];
- char buf[64], *c = buf;
-
- if (!esc)
- panicf("no terminfo escape string given");
-
- va_start(args, n);
- for (i = 0; i < arrlen(param) && i < n; i++)
- param[i] = unibi_var_from_num(va_arg(args, int));
- va_end(args);
-
- len = unibi_run(esc, param, c, sizeof(buf));
- if (len < arrlen(buf)) {
- c = ttmpbuf(t, len);
- unibi_run(esc, param, c, len);
- }
-
- twrite(t, len, c);
-}
-
-/* absolute move */
-int
-tgoto(Term *t, int row, int col)
-{
- if (row != -1 && col != -1)
- tfmt(t, t->esc.cup, 2, row, col);
- else if (row != -1) {
- if (!t->esc.vpa)
- return 0;
- tfmt(t, t->esc.vpa, 1, row);
- } else if (col != -1) {
- if (col == 0) {
- twrite(t, 1, "\r");
- return 1;
- }
- if (t->esc.hpa)
- tfmt(t, t->esc.hpa, 1, col);
- else if (t->esc.cuf) {
- twrite(t, 1, "\r");
- tfmt(t, t->esc.cuf, 1, col);
- } else
- return 0;
- } else
- return 0; /* unreachable */
-
- return 1;
-}
-
-/* relative move */
-void
-tjump(Term *t, int down, int right)
-{
- if (down == 1 && t->esc.cud1)
- tfmt(t, t->esc.cud1, 0);
- else if (down == -1 && t->esc.cuu1)
- tfmt(t, t->esc.cuu1, 0);
- else if (down > 0)
- tfmt(t, t->esc.cud, 1, down);
- else if (down < 0)
- tfmt(t, t->esc.cuu, 1, -down);
-
- if (right == 1 && t->esc.cuf1)
- tfmt(t, t->esc.cuf1, 0);
- else if (right == -1 && t->esc.cub1)
- tfmt (t, t->esc.cub1, 0);
- else if (right > 0)
- tfmt(t, t->esc.cuf, 1, right);
- else if( right < 0)
- tfmt(t, t->esc.cub, 1, -right);
-}
-
-void
-tdel(Term *t, int num)
-{
- char *c, buf[64];
- if (num < 1)
- return;
-
- /* TODO: allow for not moving */
- if (t->cap.bce) {
- tfmt(t, t->esc.ech, 1, num);
- tjump(t, 0, num);
- } else {
- c = buf;
- memset(c, ' ', arrlen(buf));
- while(num > 64) {
- twrite(t, arrlen(buf), c);
- num -= arrlen(buf);
- }
- twrite(t, num, c);
- }
-}
-
-void
-tclear(Term *t)
-{
- tfmt(t, t->esc.ed2, 0);
-}
-
-// -----------------------------------------------------------------------
-// testing entry
-
-int
-main()
-{
- Term t;
- tinit(&t);
-
- printf("%s: %s\n", unibi_short_name_str(unibi_set_a_foreground), t.esc.sgr_fg);
- printf("%s: %s\n", unibi_short_name_str(unibi_set_a_background), t.esc.sgr_bg);
- tfmt(&t, t.esc.ext.rgbf, 3, 10, 10, 100);
- tfmt(&t, t.esc.ext.rgbb, 3, 100, 0, 100);
- twrite(&t, 0, "hello world\n");
- twrite(&t, 0, "hello world\n");
- twrite(&t, 0, t.acs.hline);
-
- tfini(&t);
-}