mirror of
				https://github.com/xcat2/confluent.git
				synced 2025-11-04 05:12:32 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			208 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			6.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;
 | 
						|
    bool bold = false;
 | 
						|
    bool dim = false;
 | 
						|
    bool underline = false;
 | 
						|
    bool blink = false;
 | 
						|
    bool reverse = false;
 | 
						|
    bool invisible = false;
 | 
						|
    bool intensitychg = false;
 | 
						|
    tmt_color_t fg = TMT_COLOR_DEFAULT;
 | 
						|
    tmt_color_t bg = TMT_COLOR_DEFAULT;
 | 
						|
    wchar_t sgrline[30];
 | 
						|
    size_t srgidx = 0;
 | 
						|
    char colorcode = 0;
 | 
						|
    wprintf(L"\033c");
 | 
						|
    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++) {
 | 
						|
            sgrline[0] = L'\x00';
 | 
						|
            intensitychg = false;
 | 
						|
            if (out->lines[line]->chars[idx].a.bold != bold) {
 | 
						|
                bold = out->lines[line]->chars[idx].a.bold;
 | 
						|
                intensitychg = true; // Can't unbold without changing dim
 | 
						|
            }
 | 
						|
            if (out->lines[line]->chars[idx].a.dim != dim) {
 | 
						|
                dim = out->lines[line]->chars[idx].a.dim;
 | 
						|
                intensitychg = true; // Can't undim without changing bold
 | 
						|
            }
 | 
						|
            if (intensitychg) {
 | 
						|
                intensitychg = false;
 | 
						|
                wcscat(sgrline, L"22;");
 | 
						|
                if (bold)
 | 
						|
                    wcscat(sgrline, L"1;");
 | 
						|
                if (dim)
 | 
						|
                    wcscat(sgrline, L"2;");
 | 
						|
            }
 | 
						|
            if (out->lines[line]->chars[idx].a.underline != underline) {
 | 
						|
                underline = out->lines[line]->chars[idx].a.underline;
 | 
						|
                if (underline)
 | 
						|
                    wcscat(sgrline, L"4;");
 | 
						|
                else
 | 
						|
                    wcscat(sgrline, L"24;");
 | 
						|
            }
 | 
						|
            if (out->lines[line]->chars[idx].a.blink != blink) {
 | 
						|
                blink = out->lines[line]->chars[idx].a.blink;
 | 
						|
                if (blink)
 | 
						|
                    wcscat(sgrline, L"5;");
 | 
						|
                else
 | 
						|
                    wcscat(sgrline, L"25;");
 | 
						|
            }
 | 
						|
            if (out->lines[line]->chars[idx].a.reverse != reverse) {
 | 
						|
                reverse = out->lines[line]->chars[idx].a.reverse;
 | 
						|
                if (reverse)
 | 
						|
                    wcscat(sgrline, L"7;");
 | 
						|
                else
 | 
						|
                    wcscat(sgrline, L"27;");
 | 
						|
            }
 | 
						|
            if (out->lines[line]->chars[idx].a.invisible != invisible) {
 | 
						|
                invisible = out->lines[line]->chars[idx].a.invisible;
 | 
						|
                if (invisible)
 | 
						|
                    wcscat(sgrline, L"8;");
 | 
						|
                else
 | 
						|
                    wcscat(sgrline, L"28;");
 | 
						|
            }
 | 
						|
            if (out->lines[line]->chars[idx].a.fg != fg) {
 | 
						|
                fg = out->lines[line]->chars[idx].a.fg;
 | 
						|
                if (fg == TMT_COLOR_DEFAULT)
 | 
						|
                    colorcode = 39;
 | 
						|
                else
 | 
						|
                    colorcode = 29 + fg;
 | 
						|
                swprintf(sgrline + wcslen(sgrline), 4, L"%d;", colorcode);
 | 
						|
            }
 | 
						|
            if (out->lines[line]->chars[idx].a.bg != bg) {
 | 
						|
                bg = out->lines[line]->chars[idx].a.bg;
 | 
						|
                if (bg == TMT_COLOR_DEFAULT)
 | 
						|
                    colorcode = 49;
 | 
						|
                else
 | 
						|
                    colorcode = 39 + bg;
 | 
						|
                swprintf(sgrline + wcslen(sgrline), 4, L"%d;", colorcode);
 | 
						|
            }
 | 
						|
            if (sgrline[0] != 0) {
 | 
						|
                sgrline[wcslen(sgrline) - 1] = 0;  // Trim last ;
 | 
						|
                wprintf(L"\033[%lsm", sgrline);
 | 
						|
            }
 | 
						|
            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);
 | 
						|
}
 | 
						|
 | 
						|
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);
 | 
						|
            length = write(1, "\x00", 1);
 | 
						|
            if (length < 0)
 | 
						|
                continue;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |