2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-11-22 17:43:14 +00:00
confluent/confluent_vtbufferd/vtbufferd.c
Jarrod Johnson 03eb026b61 Improve VT dump behavior
Ensure the resultant dump has consistently long lines.  This
will matter when we start rendering attributes on blanks.

Additionally, simplify the code
significantly taking advantage
of first loop.
2021-04-01 12:51:32 -04:00

132 lines
3.4 KiB
C

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>
#include "tmt.h"
#define HASHSIZE 2053
#define MAXNAMELEN 256
#define MAXDATALEN 8192
struct terment {
struct terment *next;
char *name;
TMT *vt;
};
#define SETNODE 1
#define WRITE 2
#define READBUFF 0
static struct terment *buffers[HASHSIZE];
unsigned long hash(char *str)
/* djb2a */
{
unsigned long idx = 5381;
int c;
while ((c = *str++))
idx = ((idx << 5) + idx) + c;
return idx % HASHSIZE;
}
TMT *get_termentbyname(char *name) {
struct terment *ret;
for (ret = buffers[hash(name)]; ret != NULL; ret = ret->next)
if (strcmp(name, ret->name) == 0)
return ret->vt;
return NULL;
}
TMT *set_termentbyname(char *name) {
struct terment *ret;
int idx;
idx = hash(name);
for (ret = buffers[idx]; ret != NULL; ret = ret->next)
if (strcmp(name, ret->name) == 0)
return ret->vt;
ret = (struct terment *)malloc(sizeof(*ret));
ret->next = buffers[idx];
ret->name = strdup(name);
ret->vt = tmt_open(31, 100, NULL, NULL, L"→←↑↓■◆▒°±▒┘┐┌└┼⎺───⎽├┤┴┬│≤≥π≠£•");
buffers[idx] = ret;
return ret->vt;
}
void dump_vt(TMT* outvt) {
const TMTSCREEN *out = tmt_screen(outvt);
const TMTPOINT *curs = tmt_cursor(outvt);
int line, idx, maxcol, maxrow;
wprintf(L"\033[H\033[J");
maxcol = 0;
maxrow = 0;
for (line = out->nline - 1; line >= 0; --line) {
for (idx = out->ncol - 1; idx > maxcol; --idx) {
if (out->lines[line]->chars[idx].c != L' ') {
if (maxrow < line)
maxrow = line;
maxcol = idx;
break;
}
}
}
for (line = 0; line <= maxrow; line++) {
for (idx = 0; idx <= maxcol; idx++) {
wprintf(L"%lc", out->lines[line]->chars[idx].c);
}
if (line < maxrow)
wprintf(L"\r\n");
}
fflush(stdout);
wprintf(L"\x1b[%ld;%ldH", curs->r + 1, curs->c + 1);
fflush(stdout);
idx = write(1, "\x00", 1);
if (idx < 0) {
return;
}
}
int main(int argc, char* argv[]) {
int cmd, length;
setlocale(LC_ALL, "");
char cmdbuf[MAXDATALEN];
char currnode[MAXNAMELEN];
TMT *currvt = NULL;
TMT *outvt = NULL;
stdin = freopen(NULL, "rb", stdin);
if (stdin == NULL) {
exit(1);
}
while (1) {
length = fread(&cmd, 4, 1, stdin);
if (length < 0)
continue;
length = cmd & 536870911;
cmd = cmd >> 29;
if (cmd == SETNODE) {
currnode[length] = 0;
cmd = fread(currnode, 1, length, stdin);
if (cmd < 0)
continue;
currvt = set_termentbyname(currnode);
} else if (cmd == WRITE) {
if (currvt == NULL)
currvt = set_termentbyname("");
cmdbuf[length] = 0;
cmd = fread(cmdbuf, 1, length, stdin);
if (cmd < 0)
continue;
tmt_write(currvt, cmdbuf, length);
} else if (cmd == READBUFF) {
cmdbuf[length] = 0;
cmd = fread(cmdbuf, 1, length, stdin);
if (cmd < 0)
continue;
outvt = get_termentbyname(cmdbuf);
if (outvt != NULL) {
dump_vt(outvt);
}
}
}
}