From 7590f4424917e34c01caac722bd97ac28587bcbc Mon Sep 17 00:00:00 2001 From: Zach Potter Date: Thu, 24 Aug 2023 22:33:57 -0700 Subject: cleanup and todos --- lib/terminal.tcl | 144 ++++++++++++++++++++++++++----------------------------- 1 file changed, 67 insertions(+), 77 deletions(-) (limited to 'lib') diff --git a/lib/terminal.tcl b/lib/terminal.tcl index fc5f8b87..6276d149 100644 --- a/lib/terminal.tcl +++ b/lib/terminal.tcl @@ -3,27 +3,78 @@ # Implements a virtual terminal with basic read/write procs. # +namespace eval Terminal { + # From `man console_codes` + variable keymap [dict create \ + BACKSPACE "\x08" \ + TAB "\x09" \ + ENTER "\x0d" \ + DELETE "\x7f" \ + ESC "\x1b" \ + UP "\x1b\[A" \ + DOWN "\x1b\[B" \ + RIGHT "\x1b\[C" \ + LEFT "\x1b\[D" \ + ] + + proc _remap {key ctrlPressed} { + variable keymap + if {[string length $key] == 1} { + # Convert ctrl-A through ctrl-Z and others to terminal control characters + if {$ctrlPressed} { + set charCode [scan [string toupper $key] %c] + if {$charCode >= 64 && $charCode <= 95} { + set charCode [expr {$charCode - 64}] + return [format %c $charCode] + } + } + # All other single char keys can be passed through + return $key + } + if {[dict exists $keymap $key]} { + return [dict get $keymap $key] + } + return "" + } + + proc create {} { + return [termCreate] + } + + # Writes a keyboard key to the terminal, handling control codes + proc write {term key ctrlPressed} { + set key [_remap $key $ctrlPressed] + if {[string length $key] > 0} { + termWrite $term $key + } + } + + # Returns a newline separated string of terminal lines + proc read {term} { + return [termRead $term] + } +} + set cc [c create] $cc cflags -I./vendor/libtmt ./vendor/libtmt/tmt.c -# TODO: find the right libutil.so for the system -c loadlib /lib/aarch64-linux-gnu/libutil.so +c loadlib [lindex [exec /usr/sbin/ldconfig -p | grep libutil.so] end] $cc cflags -lutil $cc include -$cc include $cc include $cc include $cc include $cc include $cc include -$cc include ;# For gettimeofday() +$cc include $cc include "tmt.h" $cc struct VTerminal { TMT* tmt; int pty_fd; + // Note the screen has 1 more column than the terminal, for newlines char* screen; int curs_r; int curs_c; @@ -36,12 +87,12 @@ $cc code { #define PTYBUF 4096 char iobuf[PTYBUF]; - char* char_at(VTerminal *vt, int r, int c) { + char* charAt(VTerminal *vt, int r, int c) { int i = r * (COLS + 1) + c; return &vt->screen[i]; } - void tmt_callback(tmt_msg_t m, TMT *tmt, const void *a, void *p) { + void tmtEvent(tmt_msg_t m, TMT *tmt, const void *a, void *p) { VTerminal *vt = (VTerminal*)p; const TMTSCREEN *s = tmt_screen(tmt); @@ -49,7 +100,7 @@ $cc code { for (size_t r = 0; r < s->nline; r++){ if (s->lines[r]->dirty){ for (size_t c = 0; c < s->ncol; c++){ - *char_at(vt, r, c) = s->lines[r]->chars[c].c; + *charAt(vt, r, c) = s->lines[r]->chars[c].c; } } } @@ -57,10 +108,10 @@ $cc code { } } - void updateCursor(VTerminal *vt) { + void blinkCursor(VTerminal *vt) { // Restore char under old cursor const TMTSCREEN *s = tmt_screen(vt->tmt); - *char_at(vt, vt->curs_r, vt->curs_c) = s->lines[vt->curs_r]->chars[vt->curs_c].c; + *charAt(vt, vt->curs_r, vt->curs_c) = s->lines[vt->curs_r]->chars[vt->curs_c].c; // Update new cursor const TMTPOINT *c = tmt_cursor(vt->tmt); @@ -71,7 +122,7 @@ $cc code { struct timeval tv; gettimeofday(&tv, NULL); if (tv.tv_sec % 2 == 0) { - *char_at(vt, vt->curs_r, vt->curs_c) = 0xDB; // block char: █ + *charAt(vt, vt->curs_r, vt->curs_c) = 0xDB; // block char: █ } } } @@ -82,10 +133,12 @@ $cc proc termCreate {} VTerminal* { vt->curs_c = 0; vt->screen = malloc(sizeof(char[ROWS][COLS + 1])); - for (int r = 0; r < ROWS - 1; r++) *char_at(vt, r, COLS) = '\n'; - *char_at(vt, ROWS - 1, COLS) = '\0'; + for (int r = 0; r < ROWS - 1; r++) { + *charAt(vt, r, COLS) = '\n'; + } + *charAt(vt, ROWS - 1, COLS) = '\0'; - vt->tmt = tmt_open(ROWS, COLS, tmt_callback, vt, NULL); + vt->tmt = tmt_open(ROWS, COLS, tmtEvent, vt, NULL); struct winsize ws = {.ws_row = ROWS, .ws_col = COLS}; pid_t pid = forkpty(&vt->pty_fd, NULL, NULL, &ws); @@ -101,17 +154,13 @@ $cc proc termCreate {} VTerminal* { return vt; } -$cc proc termDestory {VTerminal* vt} void { - // TODO... -} - $cc proc termRead {VTerminal* vt} char* { ssize_t r = read(vt->pty_fd, iobuf, PTYBUF); if (r > 0) { tmt_write(vt->tmt, iobuf, r); } - updateCursor(vt); + blinkCursor(vt); return vt->screen; } @@ -120,62 +169,3 @@ $cc proc termWrite {VTerminal* vt char* key} void { } $cc compile - -# Folk stuff... - -namespace eval Terminal { - # From `man console_codes` - variable keymap [dict create \ - ENTER "\x0d" \ - TAB "\x09" \ - BACKSPACE "\x08" \ - DELETE "\x7f" \ - ESC "\x1b" \ - UP "\x1b\[A" \ - DOWN "\x1b\[B" \ - RIGHT "\x1b\[C" \ - LEFT "\x1b\[D" \ - ] - - proc remap {key ctrlPressed} { - variable keymap - if {[string length $key] == 1} { - # Convert ctrl-A through ctrl-Z and others to terminal control characters - if {$ctrlPressed} { - set charCode [scan [string toupper $key] %c] - if {$charCode >= 64 && $charCode <= 95} { - set charCode [expr {$charCode - 64}] - return [format %c $charCode] - } - } - # All other single char keys can be passed through - return $key - } - if {[dict exists $keymap $key]} { - return [dict get $keymap $key] - } - return "" - } - - # Creates a new virtual terminal and returns its ID - proc create {} { - return [termCreate] - } - - proc destroy {term} { - termDestroy $term - } - - # Writes a keyboard key to the terminal, handling control codes - proc write {term key ctrlPressed} { - set key [remap $key $ctrlPressed] - if {[string length $key] > 0} { - termWrite $term $key - } - } - - # Returns a newline separated string of terminal lines - proc read {term} { - return [termRead $term] - } -} -- cgit v1.2.3