mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
33
dsp/tty/altbuf.c
Normal file
33
dsp/tty/altbuf.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
|
||||
/**
|
||||
* Asks teletypewriter to flip to alternate display page.
|
||||
*
|
||||
* The alternate buffer trick lets one restore the console exactly as it
|
||||
* was, once the program is done running.
|
||||
*/
|
||||
int ttyenablealtbuf(int ttyfd) { return ttysend(ttyfd, "\e[?1049h"); }
|
||||
|
||||
/**
|
||||
* Asks teletypewriter to restore blinking box thing.
|
||||
*/
|
||||
int ttydisablealtbuf(int ttyfd) { return ttysend(ttyfd, "\e[?1049l"); }
|
46
dsp/tty/config.c
Normal file
46
dsp/tty/config.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
* Applies configuration to teletypewriter.
|
||||
*
|
||||
* @param opt_out_oldconf is only modified if successful
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see ttyconfig(), ttyrestore()
|
||||
*/
|
||||
int ttyconfig(int ttyfd, ttyconf_f fn, int64_t arg,
|
||||
const struct termios *opt_out_oldconf) {
|
||||
struct termios conf[2];
|
||||
if (tcgetattr(ttyfd, &conf[0]) != -1 &&
|
||||
fn(memcpy(&conf[1], &conf[0], sizeof(conf[0])), arg) != -1 &&
|
||||
tcsetattr(ttyfd, TCSAFLUSH, &conf[1]) != -1) {
|
||||
if (opt_out_oldconf) {
|
||||
memcpy(opt_out_oldconf, &conf[0], sizeof(conf[0]));
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
77
dsp/tty/describe.c
Normal file
77
dsp/tty/describe.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
#define BUFFY 48
|
||||
|
||||
static char *ttydescriber(char *b, const struct TtyIdent *ti) {
|
||||
switch (ti->id) {
|
||||
case 0:
|
||||
snprintf(b, BUFFY, "%s %d", "putty", ti->version);
|
||||
break;
|
||||
case 1:
|
||||
if (ti->version > 1000) {
|
||||
snprintf(b, BUFFY, "%s %d", "gnome terminal", ti->version);
|
||||
} else {
|
||||
snprintf(b, BUFFY, "%s %d", "mlterm", ti->version);
|
||||
}
|
||||
break;
|
||||
case kTtyIdScreen:
|
||||
snprintf(b, BUFFY, "%s %d", "gnu screen", ti->version);
|
||||
break;
|
||||
case 77:
|
||||
snprintf(b, BUFFY, "%s %d", "redhat mintty", ti->version);
|
||||
break;
|
||||
case 41:
|
||||
snprintf(b, BUFFY, "%s %d", "xterm", ti->version);
|
||||
break;
|
||||
case 82:
|
||||
snprintf(b, BUFFY, "%s %d", "rxvt", ti->version);
|
||||
break;
|
||||
default:
|
||||
snprintf(b, BUFFY, "%s %d %d", "unknown teletypewriter no.", ti->id,
|
||||
ti->version);
|
||||
break;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes educated guess about name of teletypewriter.
|
||||
*/
|
||||
char *ttydescribe(char *out, size_t size, const struct TtyIdent *ti) {
|
||||
char b1[BUFFY], b2[BUFFY];
|
||||
if (ti) {
|
||||
ttydescriber(b1, ti);
|
||||
if (ti->next) {
|
||||
snprintf(out, size, "%s%s%s", ttydescriber(b2, ti->next), " inside ", b1);
|
||||
} else {
|
||||
snprintf(out, size, "%s", b1);
|
||||
}
|
||||
} else {
|
||||
snprintf(out, size, "%s", "no tty");
|
||||
}
|
||||
return out;
|
||||
}
|
53
dsp/tty/hidecursor.c
Normal file
53
dsp/tty/hidecursor.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/consolecursorinfo.h"
|
||||
|
||||
static int ttysetcursor(int fd, bool visible) {
|
||||
struct NtConsoleCursorInfo ntcursor;
|
||||
char code[8] = "\e[?25l";
|
||||
if (isterminalinarticulate()) return 0;
|
||||
if (visible) code[5] = 'h';
|
||||
if (SupportsWindows()) {
|
||||
GetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor);
|
||||
ntcursor.bVisible = visible;
|
||||
SetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor);
|
||||
}
|
||||
return ttysend(fd, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks teletypewriter to hide blinking box.
|
||||
*/
|
||||
int ttyhidecursor(int fd) {
|
||||
return ttysetcursor(fd, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks teletypewriter to restore blinking box.
|
||||
*/
|
||||
int ttyshowcursor(int fd) {
|
||||
return ttysetcursor(fd, true);
|
||||
}
|
95
dsp/tty/ident.c
Normal file
95
dsp/tty/ident.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static int ttyident_probe(struct TtyIdent *ti, int ttyinfd, int ttyoutfd,
|
||||
const char *msg) {
|
||||
ssize_t rc;
|
||||
size_t got;
|
||||
char buf[64];
|
||||
int id, version;
|
||||
if ((rc = write(ttyoutfd, msg, strlen(msg))) != -1) {
|
||||
TryAgain:
|
||||
if ((rc = read(ttyinfd, buf, sizeof(buf))) != -1) {
|
||||
buf[min((got = (size_t)rc), sizeof(buf) - 1)] = '\0';
|
||||
if (sscanf(buf, "\e[>%d;%d", &id, &version) >= 1) {
|
||||
ti->id = id;
|
||||
ti->version = version;
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = eio();
|
||||
}
|
||||
} else if (errno == EINTR) {
|
||||
goto TryAgain;
|
||||
} else if (errno == EAGAIN) {
|
||||
if (poll((struct pollfd[]){{ttyinfd, POLLIN}}, 1, 100) != 0) {
|
||||
goto TryAgain;
|
||||
} else {
|
||||
rc = etimedout();
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies teletypewriter.
|
||||
*
|
||||
* For example, we can tell if process is running in a GNU Screen
|
||||
* session Gnome Terminal.
|
||||
*
|
||||
* @return object if TTY responds, or NULL w/ errno
|
||||
* @see ttyidentclear()
|
||||
*/
|
||||
int ttyident(struct TtyIdent *ti, int ttyinfd, int ttyoutfd) {
|
||||
int rc;
|
||||
struct termios old;
|
||||
struct TtyIdent outer;
|
||||
rc = -1;
|
||||
if (!IsWindows()) {
|
||||
if (ttyconfig(ttyinfd, ttysetrawdeadline, 3, &old) != -1) {
|
||||
if (ttyident_probe(ti, ttyinfd, ttyoutfd, "\e[>c") != -1) {
|
||||
rc = 0;
|
||||
memset(&outer, 0, sizeof(outer));
|
||||
if (ti->id == 83 /* GNU Screen */ && (ti->next || weaken(malloc)) &&
|
||||
ttyident_probe(&outer, ttyinfd, ttyoutfd, "\eP\e[>c\e\\") != -1 &&
|
||||
(ti->next = (ti->next ? ti->next
|
||||
: weaken(malloc)(sizeof(struct TtyIdent))))) {
|
||||
memcpy(ti->next, &outer, sizeof(outer));
|
||||
} else {
|
||||
free_s(&ti->next);
|
||||
}
|
||||
}
|
||||
ttyrestore(ttyinfd, &old);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
43
dsp/tty/identclear.c
Normal file
43
dsp/tty/identclear.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
static void ttyidentfree(struct TtyIdent *ti) {
|
||||
if (ti) {
|
||||
assert(ti != ti->next);
|
||||
ttyidentfree(ti->next);
|
||||
free_s(&ti);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys TtyIdent object.
|
||||
*
|
||||
* @see ttyident()
|
||||
*/
|
||||
void ttyidentclear(struct TtyIdent *ti) {
|
||||
assert(ti != ti->next);
|
||||
ttyidentfree(ti->next);
|
||||
memset(ti, 0, sizeof(*ti));
|
||||
}
|
33
dsp/tty/internal.h
Normal file
33
dsp/tty/internal.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef COSMOPOLITAN_DSP_TTY_INTERNAL_H_
|
||||
#define COSMOPOLITAN_DSP_TTY_INTERNAL_H_
|
||||
#include "dsp/tty/ttyrgb.h"
|
||||
#include "libc/bits/xmmintrin.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct TtyRgb rgb2tty24f_(__m128);
|
||||
struct TtyRgb rgb2ttyf2i_(__m128);
|
||||
struct TtyRgb rgb2ttyi2f_(int, int, int);
|
||||
struct TtyRgb rgb2ansi_(int, int, int);
|
||||
struct TtyRgb rgb2ansihash_(int, int, int);
|
||||
struct TtyRgb rgb2xterm24_(int, int, int);
|
||||
struct TtyRgb rgb2xterm256gray_(__m128);
|
||||
struct TtyRgb tty2rgb_(struct TtyRgb);
|
||||
struct TtyRgb tty2rgb24_(struct TtyRgb);
|
||||
__m128 tty2rgbf_(struct TtyRgb);
|
||||
__m128 tty2rgbf24_(struct TtyRgb);
|
||||
|
||||
char *setbg16_(char *, struct TtyRgb);
|
||||
char *setfg16_(char *, struct TtyRgb);
|
||||
char *setbgfg16_(char *, struct TtyRgb, struct TtyRgb);
|
||||
char *setbg256_(char *, struct TtyRgb);
|
||||
char *setfg256_(char *, struct TtyRgb);
|
||||
char *setbgfg256_(char *, struct TtyRgb, struct TtyRgb);
|
||||
char *setbg24_(char *, struct TtyRgb);
|
||||
char *setfg24_(char *, struct TtyRgb);
|
||||
char *setbgfg24_(char *, struct TtyRgb, struct TtyRgb);
|
||||
struct TtyRgb rgb2ansi8_(int, int, int);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_TTY_INTERNAL_H_ */
|
51
dsp/tty/itoa8.c
Normal file
51
dsp/tty/itoa8.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/itoa8.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
struct Itoa8 kItoa8;
|
||||
|
||||
static nooptimize textstartup void itoa8init(void) {
|
||||
size_t i;
|
||||
uint8_t z;
|
||||
char p[4];
|
||||
/*102*/
|
||||
for (i = 0; i < 256; ++i) {
|
||||
memset(p, 0, sizeof(p));
|
||||
if (i < 10) {
|
||||
z = 1;
|
||||
p[0] = '0' + i;
|
||||
} else if (i < 100) {
|
||||
z = 2;
|
||||
p[0] = '0' + i / 10;
|
||||
p[1] = '0' + i % 10;
|
||||
} else {
|
||||
z = 3;
|
||||
p[0] = '0' + i / 100;
|
||||
p[1] = '0' + i % 100 / 10;
|
||||
p[2] = '0' + i % 100 % 10;
|
||||
}
|
||||
kItoa8.size[i] = z;
|
||||
memcpy(&kItoa8.data[i], p, sizeof(p));
|
||||
}
|
||||
}
|
||||
|
||||
INITIALIZER(301, _init_itoa8, itoa8init());
|
21
dsp/tty/itoa8.h
Normal file
21
dsp/tty/itoa8.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef COSMOPOLITAN_DSP_TTY_ITOA8_H_
|
||||
#define COSMOPOLITAN_DSP_TTY_ITOA8_H_
|
||||
#include "libc/str/str.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct Itoa8 {
|
||||
uint8_t size[256];
|
||||
uint32_t data[256];
|
||||
};
|
||||
|
||||
extern struct Itoa8 kItoa8;
|
||||
|
||||
forceinline char *itoa8(char *p, uint8_t c) {
|
||||
memcpy(p, &kItoa8.data[c], 4);
|
||||
return p + kItoa8.size[c];
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_TTY_ITOA8_H_ */
|
29
dsp/tty/kcgapalette.c
Normal file
29
dsp/tty/kcgapalette.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "dsp/tty/quant.h"
|
||||
|
||||
const ttypalette_t kCgaPalette = {
|
||||
[0][0] = {0, 0, 0, 0}, /* normal black: \e[30m (or \e[38;5;0m) */
|
||||
[1][0] = {85, 85, 85, 8}, /* bright black: \e[90m (or \e[38;5;8m) */
|
||||
[0][1] = {170, 0, 0, 1}, /* normal red: \e[31m */
|
||||
[1][1] = {255, 85, 85, 9}, /* bright red: \e[91m (or \e[1;31m) */
|
||||
[0][2] = {0, 170, 0, 2}, /* normal green: \e[32m */
|
||||
[1][2] = {85, 255, 85, 10}, /* bright green: \e[92m */
|
||||
[0][3] = {170, 85, 0, 3}, /* normal yellow: \e[33m */
|
||||
[1][3] = {255, 255, 85, 11}, /* bright yellow: \e[93m */
|
||||
[0][4] = {0, 0, 170, 4}, /* normal blue: \e[34m */
|
||||
[1][4] = {85, 85, 255, 12}, /* bright blue: \e[94m */
|
||||
[0][5] = {170, 0, 170, 5}, /* normal magenta: \e[35m */
|
||||
[1][5] = {255, 85, 255, 13}, /* bright magenta: \e[95m */
|
||||
[0][6] = {0, 170, 170, 6}, /* normal cyan: \e[36m */
|
||||
[1][6] = {85, 255, 255, 14}, /* bright cyan: \e[96m */
|
||||
[0][7] = {170, 170, 170, 7}, /* normal white: \e[37m */
|
||||
[1][7] = {255, 255, 255, 15}, /* bright white: \e[97m */
|
||||
};
|
29
dsp/tty/ktangopalette.c
Normal file
29
dsp/tty/ktangopalette.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "dsp/tty/quant.h"
|
||||
|
||||
const ttypalette_t kTangoPalette = {
|
||||
[0][0] = {0x2E, 0x34, 0x36, 0}, /* aluminium1 */
|
||||
[1][0] = {0x55, 0x57, 0x53, 8},
|
||||
[0][1] = {0xCC, 0x00, 0x00, 1}, /* scarietred */
|
||||
[1][1] = {0xEF, 0x29, 0x29, 9},
|
||||
[0][2] = {0x4E, 0x9A, 0x06, 2}, /* chameleon */
|
||||
[1][2] = {0x8A, 0xE2, 0x34, 10},
|
||||
[0][3] = {0xC4, 0xA0, 0x00, 3}, /* butter */
|
||||
[1][3] = {0xFC, 0xE9, 0x4F, 11},
|
||||
[0][4] = {0x34, 0x65, 0xA4, 4}, /* skyblue */
|
||||
[1][4] = {0x72, 0x9F, 0xCF, 12},
|
||||
[0][5] = {0x75, 0x50, 0x7B, 5}, /* plum */
|
||||
[1][5] = {0xAD, 0x7F, 0xA8, 13},
|
||||
[0][6] = {0x06, 0x98, 0x9A, 6}, /* cyan */
|
||||
[1][6] = {0x34, 0xE2, 0xE2, 14},
|
||||
[0][7] = {0xD3, 0xD7, 0xCF, 7}, /* aluminium2 */
|
||||
[1][7] = {0xEE, 0xEE, 0xEC, 15},
|
||||
};
|
22
dsp/tty/kxtermcubesteps.c
Normal file
22
dsp/tty/kxtermcubesteps.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/quant.h"
|
||||
|
||||
const uint8_t kXtermCubeSteps[] = {0, 0137, 0207, 0257, 0327, 0377};
|
29
dsp/tty/kxtermpalette.c
Normal file
29
dsp/tty/kxtermpalette.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "dsp/tty/quant.h"
|
||||
|
||||
const ttypalette_t kXtermPalette = {
|
||||
[0][0] = {0, 0, 0, 0}, /* normal black: \e[30m (or \e[38;5;0m) */
|
||||
[1][0] = {127, 127, 127, 8}, /* bright black: \e[90m (or \e[38;5;8m) */
|
||||
[0][1] = {205, 0, 0, 1}, /* normal red: \e[31m */
|
||||
[1][1] = {255, 0, 0, 9}, /* bright red: \e[91m (or \e[1;31m) */
|
||||
[0][2] = {0, 205, 0, 2}, /* normal green: \e[32m */
|
||||
[1][2] = {0, 255, 0, 10}, /* bright green: \e[92m */
|
||||
[0][3] = {205, 205, 0, 3}, /* normal yellow: \e[33m */
|
||||
[1][3] = {255, 255, 0, 11}, /* bright yellow: \e[93m */
|
||||
[0][4] = {0, 0, 238, 4}, /* normal blue: \e[34m */
|
||||
[1][4] = {92, 92, 255, 12}, /* bright blue: \e[94m */
|
||||
[0][5] = {205, 0, 205, 5}, /* normal magenta: \e[35m */
|
||||
[1][5] = {255, 0, 255, 13}, /* bright magenta: \e[95m */
|
||||
[0][6] = {0, 205, 205, 6}, /* normal cyan: \e[36m */
|
||||
[1][6] = {0, 255, 255, 14}, /* bright cyan: \e[96m */
|
||||
[0][7] = {229, 229, 229, 7}, /* normal white: \e[37m */
|
||||
[1][7] = {255, 255, 255, 15}, /* bright white: \e[97m */
|
||||
};
|
29
dsp/tty/mpsadbw.S
Normal file
29
dsp/tty/mpsadbw.S
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
/ TODO(jart): write me
|
||||
|
||||
movdqa a,%xmm0
|
||||
mpsadbw $0,inv,%xmm0
|
||||
|
||||
.rodata.cst32
|
||||
a: .byte 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
inv: .byte 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
|
84
dsp/tty/quant.h
Normal file
84
dsp/tty/quant.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
#ifndef DSP_TTY_QUANT_H_
|
||||
#define DSP_TTY_QUANT_H_
|
||||
#include "dsp/tty/ttyrgb.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/xmmintrin.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/str/str.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define TL 0
|
||||
#define TR 1
|
||||
#define BL 2
|
||||
#define BR 3
|
||||
|
||||
typedef __m128 (*tty2rgbf_f)(struct TtyRgb);
|
||||
typedef char *(*setbg_f)(char *, struct TtyRgb);
|
||||
typedef char *(*setbgfg_f)(char *, struct TtyRgb, struct TtyRgb);
|
||||
typedef char *(*setfg_f)(char *, struct TtyRgb);
|
||||
typedef struct TtyRgb (*rgb2tty_f)(int, int, int);
|
||||
typedef struct TtyRgb (*rgb2ttyf_f)(__m128);
|
||||
typedef struct TtyRgb (*tty2rgb_f)(struct TtyRgb);
|
||||
typedef struct TtyRgb ttypalette_t[2][8];
|
||||
|
||||
struct TtyQuant {
|
||||
enum TtyQuantizationAlgorithm {
|
||||
kTtyQuantAnsi,
|
||||
kTtyQuantTrue,
|
||||
kTtyQuantXterm256,
|
||||
} alg;
|
||||
enum TtyBlocksSelection {
|
||||
kTtyBlocksUnicode,
|
||||
kTtyBlocksCp437,
|
||||
} blocks;
|
||||
enum TtyQuantizationChannels {
|
||||
kTtyQuantGrayscale = 1,
|
||||
kTtyQuantRgb = 3,
|
||||
} chans;
|
||||
unsigned min;
|
||||
unsigned max;
|
||||
setbg_f setbg;
|
||||
setfg_f setfg;
|
||||
setbgfg_f setbgfg;
|
||||
rgb2tty_f rgb2tty;
|
||||
rgb2ttyf_f rgb2ttyf;
|
||||
tty2rgb_f tty2rgb;
|
||||
tty2rgbf_f tty2rgbf;
|
||||
const ttypalette_t *palette;
|
||||
};
|
||||
|
||||
extern const ttypalette_t kCgaPalette;
|
||||
extern const ttypalette_t kXtermPalette;
|
||||
extern const ttypalette_t kTangoPalette;
|
||||
|
||||
extern const uint8_t kXtermCubeSteps[6];
|
||||
extern double g_xterm256_gamma;
|
||||
extern struct TtyRgb g_ansi2rgb_[256];
|
||||
extern struct TtyQuant g_ttyquant_;
|
||||
extern const uint8_t kXtermXlat[2][256];
|
||||
|
||||
void ttyquantinit(enum TtyQuantizationAlgorithm, enum TtyQuantizationChannels,
|
||||
enum TtyBlocksSelection);
|
||||
|
||||
extern char *ttyraster(char *, const struct TtyRgb *, size_t, size_t,
|
||||
struct TtyRgb, struct TtyRgb);
|
||||
|
||||
#define ttyquant() (&g_ttyquant_)
|
||||
#define TTYQUANT() VEIL("r", &g_ttyquant_)
|
||||
#define rgb2tty(...) (ttyquant()->rgb2tty(__VA_ARGS__))
|
||||
#define tty2rgb(...) (ttyquant()->tty2rgb(__VA_ARGS__))
|
||||
#define rgb2ttyf(...) (ttyquant()->rgb2ttyf(__VA_ARGS__))
|
||||
#define tty2rgbf(...) (ttyquant()->tty2rgbf(__VA_ARGS__))
|
||||
#define setbg(...) (ttyquant()->setbg(__VA_ARGS__))
|
||||
#define setfg(...) (ttyquant()->setfg(__VA_ARGS__))
|
||||
#define setbgfg(...) (ttyquant()->setbgfg(__VA_ARGS__))
|
||||
|
||||
forceinline bool ttyeq(struct TtyRgb x, struct TtyRgb y) {
|
||||
return x.r == y.r && x.g == y.g && x.b == y.b;
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* DSP_TTY_QUANT_H_ */
|
78
dsp/tty/quantinit.c
Normal file
78
dsp/tty/quantinit.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/internal.h"
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
struct TtyQuant g_ttyquant_;
|
||||
|
||||
/**
|
||||
* Chooses xterm quantization mode.
|
||||
*/
|
||||
optimizesize textstartup void ttyquantinit(enum TtyQuantizationAlgorithm alg,
|
||||
enum TtyQuantizationChannels chans,
|
||||
enum TtyBlocksSelection blocks) {
|
||||
switch (alg) {
|
||||
case kTtyQuantAnsi:
|
||||
TTYQUANT()->rgb2tty = rgb2ansi_;
|
||||
TTYQUANT()->rgb2ttyf = rgb2ttyf2i_;
|
||||
TTYQUANT()->tty2rgb = tty2rgb_;
|
||||
TTYQUANT()->tty2rgbf = tty2rgbf_;
|
||||
TTYQUANT()->setbg = setbg16_;
|
||||
TTYQUANT()->setfg = setfg16_;
|
||||
TTYQUANT()->setbgfg = setbgfg16_;
|
||||
TTYQUANT()->min = 0;
|
||||
TTYQUANT()->max = 16;
|
||||
break;
|
||||
case kTtyQuantTrue:
|
||||
TTYQUANT()->rgb2tty = rgb2xterm24_;
|
||||
TTYQUANT()->rgb2ttyf = rgb2tty24f_;
|
||||
TTYQUANT()->tty2rgb = tty2rgb24_;
|
||||
TTYQUANT()->tty2rgbf = tty2rgbf24_;
|
||||
TTYQUANT()->setbg = setbg24_;
|
||||
TTYQUANT()->setfg = setfg24_;
|
||||
TTYQUANT()->setbgfg = setbgfg24_;
|
||||
TTYQUANT()->min = 16;
|
||||
TTYQUANT()->max = 256;
|
||||
break;
|
||||
case kTtyQuantXterm256:
|
||||
TTYQUANT()->rgb2tty = rgb2ansi_;
|
||||
TTYQUANT()->rgb2ttyf = rgb2ttyf2i_;
|
||||
TTYQUANT()->tty2rgb = tty2rgb_;
|
||||
TTYQUANT()->tty2rgbf = tty2rgbf_;
|
||||
TTYQUANT()->setbg = setbg256_;
|
||||
TTYQUANT()->setfg = setfg256_;
|
||||
TTYQUANT()->setbgfg = setbgfg256_;
|
||||
TTYQUANT()->min = 16;
|
||||
TTYQUANT()->max = 256;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
TTYQUANT()->chans = chans;
|
||||
TTYQUANT()->alg = alg;
|
||||
TTYQUANT()->blocks = blocks;
|
||||
}
|
||||
|
||||
INITIALIZER(400, _init_ttyquant,
|
||||
ttyquantinit(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode));
|
29
dsp/tty/restore.c
Normal file
29
dsp/tty/restore.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
* Puts teletypewriter back into previous configuration.
|
||||
*/
|
||||
int ttyrestore(int ttyoutfd, const struct termios *conf) {
|
||||
return tcsetattr(ttyoutfd, TCSADRAIN, conf);
|
||||
}
|
129
dsp/tty/rgb2ansi.c
Normal file
129
dsp/tty/rgb2ansi.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/core.h"
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#define CUTOFF_VALUE 200
|
||||
|
||||
#define DIST(X, Y) ((X) - (Y))
|
||||
#define SQR(X) ((X) * (X))
|
||||
#define SUM(X, Y, Z) ((X) + (Y) + (Z))
|
||||
|
||||
static const uint8_t kXtermCube[] = {0, 0137, 0207, 0257, 0327, 0377};
|
||||
struct TtyRgb g_ansi2rgb_[256];
|
||||
static uint8_t g_quant[256];
|
||||
static uint8_t g_rindex[256];
|
||||
static uint8_t g_gindex[256];
|
||||
static uint8_t g_bindex[256];
|
||||
double g_xterm256_gamma;
|
||||
|
||||
struct TtyRgb tty2rgb_(struct TtyRgb rgbxt) {
|
||||
return g_ansi2rgb_[rgbxt.xt];
|
||||
}
|
||||
|
||||
__m128 tty2rgbf_(struct TtyRgb rgbxt) {
|
||||
rgbxt = g_ansi2rgb_[rgbxt.xt];
|
||||
return (__m128){(int)rgbxt.r, (int)rgbxt.g, (int)rgbxt.b} / 255;
|
||||
}
|
||||
|
||||
static int rgb2xterm256_(int r, int g, int b) {
|
||||
int cerr, gerr, ir, ig, ib, gray, grai, cr, cg, cb, gv;
|
||||
gray = round(r * .299 + g * .587 + b * .114);
|
||||
grai = gray > 238 ? 23 : (gray - 3) / 10;
|
||||
ir = r < 48 ? 0 : r < 115 ? 1 : (r - 35) / 40;
|
||||
ig = g < 48 ? 0 : g < 115 ? 1 : (g - 35) / 40;
|
||||
ib = b < 48 ? 0 : b < 115 ? 1 : (b - 35) / 40;
|
||||
cr = kXtermCube[ir];
|
||||
cg = kXtermCube[ig];
|
||||
cb = kXtermCube[ib];
|
||||
gv = 8 + 10 * grai;
|
||||
cerr = SQR(DIST(cr, r)) + SQR(DIST(cg, g)) + SQR(DIST(cb, b));
|
||||
gerr = SQR(DIST(gv, r)) + SQR(DIST(gv, g)) + SQR(DIST(gv, b));
|
||||
if (cerr <= gerr) {
|
||||
return 16 + 36 * ir + 6 * ig + ib;
|
||||
} else {
|
||||
return 232 + grai;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quantizes RGB to ANSI w/ euclidean distance in 3D color space.
|
||||
*/
|
||||
struct TtyRgb rgb2ansi_(int r, int g, int b) {
|
||||
uint32_t d, least;
|
||||
size_t c, best, min, max;
|
||||
r = MAX(MIN(r, 255), 0);
|
||||
g = MAX(MIN(g, 255), 0);
|
||||
b = MAX(MIN(b, 255), 0);
|
||||
min = ttyquant()->min;
|
||||
max = ttyquant()->max;
|
||||
if (min == 16 && max == 256) {
|
||||
return (struct TtyRgb){r, g, b, rgb2xterm256_(r, g, b)};
|
||||
} else {
|
||||
least = UINT32_MAX;
|
||||
best = 0;
|
||||
for (c = min; c < max; c++) {
|
||||
d = SUM(SQR(DIST(g_ansi2rgb_[c].r, r)), SQR(DIST(g_ansi2rgb_[c].g, g)),
|
||||
SQR(DIST(g_ansi2rgb_[c].b, b)));
|
||||
if (d < least) {
|
||||
least = d;
|
||||
best = c;
|
||||
}
|
||||
}
|
||||
return (struct TtyRgb){r, g, b, best};
|
||||
}
|
||||
}
|
||||
|
||||
static int uncube(int x) {
|
||||
return x < 48 ? 0 : x < 115 ? 1 : (x - 35) / 40;
|
||||
}
|
||||
|
||||
static optimizesize textstartup void xterm2rgbsetup_(void) {
|
||||
uint8_t c, y;
|
||||
uint32_t i, j;
|
||||
memcpy(g_ansi2rgb_, &kCgaPalette, sizeof(kCgaPalette));
|
||||
for (i = 0; i < 256; ++i) {
|
||||
j = uncube(i);
|
||||
g_quant[i] = kXtermCube[j];
|
||||
g_rindex[i] = j * 36;
|
||||
g_gindex[i] = j * 6;
|
||||
g_bindex[i] = j + 16;
|
||||
}
|
||||
for (i = 16; i < 232; ++i) {
|
||||
g_ansi2rgb_[i].r = kXtermCube[((i - 020) / 044) % 06];
|
||||
g_ansi2rgb_[i].g = kXtermCube[((i - 020) / 06) % 06];
|
||||
g_ansi2rgb_[i].b = kXtermCube[(i - 020) % 06];
|
||||
g_ansi2rgb_[i].xt = i;
|
||||
}
|
||||
for (i = 232, c = 8; i < 256; i++, c += 10) {
|
||||
g_ansi2rgb_[i].r = c;
|
||||
g_ansi2rgb_[i].g = c;
|
||||
g_ansi2rgb_[i].b = c;
|
||||
g_ansi2rgb_[i].xt = i;
|
||||
}
|
||||
}
|
||||
|
||||
INITIALIZER(301, _init_ansi2rgb, xterm2rgbsetup_());
|
29
dsp/tty/rgb2ttyf2i.c
Normal file
29
dsp/tty/rgb2ttyf2i.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/bits/xmmintrin.h"
|
||||
|
||||
struct TtyRgb rgb2ttyf2i_(__m128 rgb) {
|
||||
__v4si i4;
|
||||
rgb *= 255;
|
||||
/* i4 = __builtin_ia32_cvtps2dq(rgb); */
|
||||
asm("cvttps2dq\t%0,%1" : "+%x"(rgb), "=x"(i4));
|
||||
return rgb2tty(i4[0], i4[1], i4[2]);
|
||||
}
|
26
dsp/tty/rgb2ttyi2f.c
Normal file
26
dsp/tty/rgb2ttyi2f.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
struct TtyRgb rgb2ttyi2f_(int r, int g, int b) {
|
||||
return rgb2ttyf((__m128){r, g, b} / 255);
|
||||
}
|
26
dsp/tty/rgb2xterm24.c
Normal file
26
dsp/tty/rgb2xterm24.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
struct TtyRgb rgb2xterm24_(int r, int g, int b) {
|
||||
return (struct TtyRgb){MAX(MIN(r, 255), 0), MAX(MIN(g, 255), 0),
|
||||
MAX(MIN(b, 255), 0), 0};
|
||||
}
|
42
dsp/tty/rgb2xterm24f.c
Normal file
42
dsp/tty/rgb2xterm24f.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/math.h"
|
||||
|
||||
/*
|
||||
struct TtyRgb rgb2tty24f_(__m128 rgb) {
|
||||
const __v4si kMax = {255, 255, 255, 255};
|
||||
const __v4si kMin = {0, 0, 0, 0};
|
||||
struct TtyRgb res;
|
||||
__v4si rgb255;
|
||||
rgb255 = _mm_min_ps(_mm_max_ps(_mm_cvtps_epi32(rgb * 255), kMin), kMax);
|
||||
res = (struct TtyRgb){rgb255[0], rgb255[1], rgb255[2], rgb255[3]};
|
||||
return res;
|
||||
}
|
||||
*/
|
||||
|
||||
struct TtyRgb rgb2tty24f_(__m128 rgb) {
|
||||
const __m128 kMax = {1, 1, 1, 1};
|
||||
const __m128 kMin = {0, 0, 0, 0};
|
||||
struct TtyRgb res;
|
||||
rgb = _mm_min_ps(_mm_max_ps(rgb, kMin), kMax) * 255;
|
||||
res = (struct TtyRgb){rgb[0], rgb[1], rgb[2], rgb[3]};
|
||||
return res;
|
||||
}
|
71
dsp/tty/rgb2xterm256.c
Normal file
71
dsp/tty/rgb2xterm256.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/rgb2xterm256.h"
|
||||
|
||||
/* 1bc */
|
||||
forceinline int sqr(int x) { return x * x; }
|
||||
/* forceinline int dst6(int x) { return x * x; } */
|
||||
int rgb2xterm256v2(int r, int g, int b) {
|
||||
static const int i2cv[] = {0, 0137, 0207, 0257, 0327, 0377, 0377};
|
||||
#define v2ci(v) (v < 060 ? 0 : v < 0163 ? 01 : (v - 043) / 050)
|
||||
#define dst6(A, B, C, a, b, c) (sqr(A - a) + sqr(B - b) + sqr(C - c))
|
||||
int ir = v2ci(r);
|
||||
int ig = v2ci(g);
|
||||
int ib = v2ci(b);
|
||||
int avg = (r + g + b) / 3;
|
||||
int cr = i2cv[ir];
|
||||
int cg = i2cv[ig];
|
||||
int cb = i2cv[ib];
|
||||
int gidx = avg > 238 ? 23 : (avg - 3) / 10;
|
||||
int gv = 8 + 10 * gidx;
|
||||
int cerr = dst6(cr, cg, cb, r, g, b);
|
||||
int gerr = dst6(gv, gv, gv, r, g, b);
|
||||
return cerr <= gerr ? 16 + (36 * ir + 6 * ig + ib) : 232 + gidx;
|
||||
#undef dst6
|
||||
#undef cidx
|
||||
#undef v2ci
|
||||
}
|
||||
|
||||
/* 1e3 */
|
||||
// Convert RGB24 to xterm-256 8-bit value
|
||||
// For simplicity, assume RGB space is perceptually uniform.
|
||||
// There are 5 places where one of two outputs needs to be chosen when
|
||||
// input is the exact middle:
|
||||
// - The r/g/b channels and the gray value: choose higher value output
|
||||
// - If gray and color have same distance from input - choose color
|
||||
int rgb2xterm256(uint8_t r, uint8_t g, uint8_t b) {
|
||||
// Calculate the nearest 0-based color index at 16 .. 231
|
||||
#define v2ci(v) (v < 48 ? 0 : v < 115 ? 1 : (v - 35) / 40)
|
||||
int ir = v2ci(r), ig = v2ci(g), ib = v2ci(b); // 0..5 each
|
||||
#define color_index() (36 * ir + 6 * ig + ib) /* 0..215, lazy eval */
|
||||
// Calculate the nearest 0-based gray index at 232 .. 255
|
||||
int average = (r + g + b) / 3;
|
||||
int gray_index = average > 238 ? 23 : (average - 3) / 10; // 0..23
|
||||
// Calculate the represented colors back from the index
|
||||
static const int i2cv[6] = {0, 0x5f, 0x87, 0xaf, 0xd7, 0xff};
|
||||
int cr = i2cv[ir], cg = i2cv[ig], cb = i2cv[ib]; // r/g/b, 0..255 each
|
||||
int gv = 8 + 10 * gray_index; // same value for r/g/b, 0..255
|
||||
// Return the one which is nearer to the original input rgb value
|
||||
#define dist_square(A, B, C, a, b, c) \
|
||||
((A - a) * (A - a) + (B - b) * (B - b) + (C - c) * (C - c))
|
||||
int color_err = dist_square(cr, cg, cb, r, g, b);
|
||||
int gray_err = dist_square(gv, gv, gv, r, g, b);
|
||||
return color_err <= gray_err ? 16 + color_index() : 232 + gray_index;
|
||||
}
|
11
dsp/tty/rgb2xterm256.h
Normal file
11
dsp/tty/rgb2xterm256.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_DSP_TTY_RGB2XTERM256_H_
|
||||
#define COSMOPOLITAN_DSP_TTY_RGB2XTERM256_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int rgb2xterm256(uint8_t, uint8_t, uint8_t);
|
||||
int rgb2xterm256v2(int, int, int);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_TTY_RGB2XTERM256_H_ */
|
30
dsp/tty/savecursor.c
Normal file
30
dsp/tty/savecursor.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
|
||||
/**
|
||||
* Asks teletypewriter to push current position.
|
||||
*/
|
||||
int ttysavecursor(int ttyfd) { return ttysend(ttyfd, "\e[s"); }
|
||||
|
||||
/**
|
||||
* Asks teletypewriter to pop previous position.
|
||||
*/
|
||||
int ttyrestorecursor(int ttyfd) { return ttysend(ttyfd, "\e[u"); }
|
30
dsp/tty/send.c
Normal file
30
dsp/tty/send.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Sends data to teletypewriter.
|
||||
*
|
||||
* This function blocks until the full amount is transmitted.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int ttysend(int fd, const char *str) { return ttywrite(fd, str, strlen(str)); }
|
41
dsp/tty/sendtitle.c
Normal file
41
dsp/tty/sendtitle.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/alg/arraylist2.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/**
|
||||
* Changes text in title bar of pseudo-teletypewriter window.
|
||||
*
|
||||
* @param title is trustworthy text without any BEL characters
|
||||
* @param ti comes from ttyident() and null means no-op
|
||||
*/
|
||||
int ttysendtitle(int ttyfd, const char *title, const struct TtyIdent *ti) {
|
||||
if (ti) {
|
||||
if (ti->id == kTtyIdScreen) {
|
||||
return ttysend(ttyfd, gc(xstrcat("\eP\e]0;", title, "\a\e\\")));
|
||||
} else {
|
||||
return ttysend(ttyfd, gc(xstrcat("\e]0;", title, "\a")));
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
25
dsp/tty/setansipalette.c
Normal file
25
dsp/tty/setansipalette.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
void setansipalette(ttypalette_t palette) {
|
||||
memcpy(g_ansi2rgb_, palette, sizeof(struct TtyRgb) * 2 * 8);
|
||||
}
|
43
dsp/tty/setbgfg16.c
Normal file
43
dsp/tty/setbgfg16.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/itoa8.h"
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/limits.h"
|
||||
|
||||
static char *ansitoa(char *p, unsigned xt, unsigned base) {
|
||||
if (xt >= 8) xt -= 8, base += 60;
|
||||
return itoa8(p, xt + base);
|
||||
}
|
||||
|
||||
static char *setansibgfg(char *p, unsigned bg, unsigned fg) {
|
||||
*p++ = '\e';
|
||||
*p++ = '[';
|
||||
if (bg != -1u) p = ansitoa(p, bg, 40);
|
||||
if (bg != -1u && fg != -1u) *p++ = ';';
|
||||
if (fg != -1u) p = ansitoa(p, fg, 30);
|
||||
*p++ = 'm';
|
||||
return p;
|
||||
}
|
||||
|
||||
char *setbg16_(char *p, struct TtyRgb bg) { return setansibgfg(p, bg.xt, -1u); }
|
||||
char *setfg16_(char *p, struct TtyRgb fg) { return setansibgfg(p, -1u, fg.xt); }
|
||||
char *setbgfg16_(char *p, struct TtyRgb bg, struct TtyRgb fg) {
|
||||
return setansibgfg(p, bg.xt, fg.xt);
|
||||
}
|
54
dsp/tty/setbgfg24.c
Normal file
54
dsp/tty/setbgfg24.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/itoa8.h"
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
static char *rgbcpy(char *p, struct TtyRgb bg) {
|
||||
memcpy(p, ";2;\0", 4);
|
||||
p = itoa8(p + 3, bg.r);
|
||||
*p++ = ';';
|
||||
p = itoa8(p, bg.g);
|
||||
*p++ = ';';
|
||||
return itoa8(p, bg.b);
|
||||
}
|
||||
|
||||
char *setbg24_(char *p, struct TtyRgb bg) {
|
||||
memcpy(p, "\e[48", 4);
|
||||
p = rgbcpy(p + 4, bg);
|
||||
*p++ = 'm';
|
||||
return p;
|
||||
}
|
||||
|
||||
char *setfg24_(char *p, struct TtyRgb fg) {
|
||||
memcpy(p, "\e[38", 4);
|
||||
p = rgbcpy(p + 4, fg);
|
||||
*p++ = 'm';
|
||||
return p;
|
||||
}
|
||||
|
||||
char *setbgfg24_(char *p, struct TtyRgb bg, struct TtyRgb fg) {
|
||||
memcpy(p, "\e[48", 4);
|
||||
p = rgbcpy(p + 4, bg);
|
||||
memcpy(p, ";38\0", 4);
|
||||
p = rgbcpy(p + 3, fg);
|
||||
*p++ = 'm';
|
||||
return p;
|
||||
}
|
48
dsp/tty/setbgfg256.c
Normal file
48
dsp/tty/setbgfg256.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/itoa8.h"
|
||||
#include "dsp/tty/quant.h"
|
||||
|
||||
char *setbg256_(char *p, struct TtyRgb bg) {
|
||||
memcpy(p, "\e[48", 4);
|
||||
memcpy(p + 4, ";5;\0", 4);
|
||||
p = itoa8(p + 7, bg.xt);
|
||||
*p++ = 'm';
|
||||
return p;
|
||||
}
|
||||
|
||||
char *setfg256_(char *p, struct TtyRgb fg) {
|
||||
memcpy(p, "\e[38", 4);
|
||||
memcpy(p + 4, ";5;\0", 4);
|
||||
p = itoa8(p + 7, fg.xt);
|
||||
*p++ = 'm';
|
||||
return p;
|
||||
}
|
||||
|
||||
char *setbgfg256_(char *p, struct TtyRgb bg, struct TtyRgb fg) {
|
||||
memcpy(p, "\e[48", 4);
|
||||
memcpy(p + 4, ";5;\0", 4);
|
||||
p = itoa8(p + 7, bg.xt);
|
||||
memcpy(p, ";38;", 4);
|
||||
memcpy(p + 4, "5;\0", 4);
|
||||
p = itoa8(p + 6, fg.xt);
|
||||
*p++ = 'm';
|
||||
return p;
|
||||
}
|
52
dsp/tty/setraw.c
Normal file
52
dsp/tty/setraw.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
* Enables direct teletypewriter communication.
|
||||
*
|
||||
* @see ttyconfig(), ttyrestore()
|
||||
*/
|
||||
int ttysetraw(struct termios *conf, int64_t flags) {
|
||||
conf->c_iflag &= ~(INPCK | ISTRIP | PARMRK | INLCR | IGNCR | ICRNL | IXON);
|
||||
conf->c_lflag &= ~(IEXTEN | ICANON);
|
||||
conf->c_cflag &= ~(CSIZE | PARENB);
|
||||
conf->c_cflag |= CS8;
|
||||
conf->c_iflag |= IUTF8;
|
||||
/* if (flags & kTtyLfToCrLf) { */
|
||||
/* /\* conf->c_oflag &= ~(OLCUC | OCRNL | ONLRET | OFILL | OFDEL); *\/ */
|
||||
/* /\* conf->c_oflag |= ONLCR | ONOCR; *\/ */
|
||||
/* conf->c_oflag |= ONLCR; */
|
||||
/* } else { */
|
||||
/* conf->c_oflag &= ~OPOST; */
|
||||
/* } */
|
||||
if (!(flags & kTtySigs)) {
|
||||
conf->c_iflag &= ~(IGNBRK | BRKINT);
|
||||
conf->c_lflag &= ~(ISIG);
|
||||
}
|
||||
if (flags & kTtyEcho) {
|
||||
conf->c_lflag |= ECHO | ECHONL;
|
||||
} else {
|
||||
conf->c_lflag &= ~(ECHO | ECHONL);
|
||||
}
|
||||
return 0;
|
||||
}
|
34
dsp/tty/setrawdeadline.c
Normal file
34
dsp/tty/setrawdeadline.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
* Enables direct teletypewriter communication w/ read timeouts.
|
||||
* @see ttyconfig(), ttyrestore()
|
||||
*/
|
||||
int ttysetrawdeadline(struct termios *conf, int64_t deciseconds) {
|
||||
assert(0 < deciseconds && deciseconds < 256);
|
||||
conf->c_cc[VMIN] = 0;
|
||||
conf->c_cc[VTIME] = deciseconds;
|
||||
return ttysetraw(conf, 0);
|
||||
}
|
33
dsp/tty/setrawmode.c
Normal file
33
dsp/tty/setrawmode.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
* Enables blocking raw mode for teletypewriter w/ recommended settings.
|
||||
* @see ttyconfig(), ttyrestore()
|
||||
*/
|
||||
int ttysetrawmode(struct termios *conf, int64_t flags) {
|
||||
conf->c_cc[VMIN] = 1;
|
||||
conf->c_cc[VTIME] = 1;
|
||||
return ttysetraw(conf, flags);
|
||||
}
|
59
dsp/tty/tty.h
Normal file
59
dsp/tty/tty.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
#ifndef COSMOPOLITAN_DSP_TTY_TTY_H_
|
||||
#define COSMOPOLITAN_DSP_TTY_TTY_H_
|
||||
|
||||
#define kTtyIdScreen 83
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct FILE;
|
||||
struct termios;
|
||||
|
||||
struct TtyIdent {
|
||||
int id; /* first number sent back by \e[>c */
|
||||
int version; /* second number sent back by \e[>c */
|
||||
struct TtyIdent *next; /* yo dawg */
|
||||
};
|
||||
|
||||
struct TtyCursor {
|
||||
int y;
|
||||
int x;
|
||||
int bg;
|
||||
int fg;
|
||||
};
|
||||
|
||||
enum TtyRawFlags {
|
||||
kTtyEcho = 1 << 0, /* echo input */
|
||||
kTtyCursor = 1 << 1, /* show cursor */
|
||||
kTtySigs = 1 << 2, /* auto raise() on CTRL+C, CTRL+Z, and CTRL+\ */
|
||||
kTtyLfToCrLf = 1 << 3, /* enables unix newline magic */
|
||||
};
|
||||
|
||||
typedef int (*ttyconf_f)(struct termios *, int64_t);
|
||||
|
||||
int ttyraw(enum TtyRawFlags);
|
||||
int ttyhidecursor(int);
|
||||
int ttyshowcursor(int);
|
||||
int ttysavecursor(int);
|
||||
int ttyrestorecursor(int);
|
||||
int ttyenablealtbuf(int);
|
||||
int ttydisablealtbuf(int);
|
||||
int ttysend(int, const char *);
|
||||
int ttywrite(int, const void *, size_t);
|
||||
int ttysendtitle(int, const char *, const struct TtyIdent *);
|
||||
int ttyident(struct TtyIdent *, int, int);
|
||||
void ttyidentclear(struct TtyIdent *);
|
||||
char *ttydescribe(char *, size_t, const struct TtyIdent *);
|
||||
int ttyconfig(int, ttyconf_f, int64_t, const struct termios *);
|
||||
int ttyrestore(int, const struct termios *);
|
||||
int ttysetrawdeadline(struct termios *, int64_t);
|
||||
int ttysetrawmode(struct termios *, int64_t);
|
||||
int ttysetraw(struct termios *, int64_t);
|
||||
char *ttymove(struct TtyCursor *, char *, int, int)
|
||||
paramsnonnull() returnsnonnull;
|
||||
void ttyhisto(uint32_t[hasatleast 256], uint8_t[hasatleast 256],
|
||||
const uint8_t *, const uint8_t *, size_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_TTY_TTY_H_ */
|
70
dsp/tty/tty.mk
Normal file
70
dsp/tty/tty.mk
Normal file
|
@ -0,0 +1,70 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += DSP_TTY
|
||||
|
||||
DSP_TTY_ARTIFACTS += DSP_TTY_A
|
||||
DSP_TTY = $(DSP_TTY_A_DEPS) $(DSP_TTY_A)
|
||||
DSP_TTY_A = o/$(MODE)/dsp/tty/tty.a
|
||||
DSP_TTY_A_FILES := $(wildcard dsp/tty/*)
|
||||
DSP_TTY_A_HDRS = $(filter %.h,$(DSP_TTY_A_FILES))
|
||||
DSP_TTY_A_SRCS_S = $(filter %.S,$(DSP_TTY_A_FILES))
|
||||
DSP_TTY_A_SRCS_C = $(filter %.c,$(DSP_TTY_A_FILES))
|
||||
|
||||
DSP_TTY_A_SRCS = \
|
||||
$(DSP_TTY_A_SRCS_S) \
|
||||
$(DSP_TTY_A_SRCS_C)
|
||||
|
||||
DSP_TTY_A_OBJS = \
|
||||
$(DSP_TTY_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(DSP_TTY_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(DSP_TTY_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
DSP_TTY_A_CHECKS = \
|
||||
$(DSP_TTY_A).pkg \
|
||||
$(DSP_TTY_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
DSP_TTY_A_DIRECTDEPS = \
|
||||
DSP_CORE \
|
||||
LIBC_ALG \
|
||||
LIBC_CALLS \
|
||||
LIBC_FMT \
|
||||
LIBC_LOG \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_KERNELBASE \
|
||||
LIBC_STR \
|
||||
LIBC_STDIO \
|
||||
LIBC_STUBS \
|
||||
LIBC_SOCK \
|
||||
LIBC_SYSV \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_TIME \
|
||||
LIBC_X \
|
||||
LIBC_UNICODE
|
||||
|
||||
DSP_TTY_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(DSP_TTY_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(DSP_TTY_A): dsp/tty/ \
|
||||
$(DSP_TTY_A).pkg \
|
||||
$(DSP_TTY_A_OBJS)
|
||||
|
||||
$(DSP_TTY_A).pkg: \
|
||||
$(DSP_TTY_A_OBJS) \
|
||||
$(foreach x,$(DSP_TTY_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/dsp/tty/ttyraster.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
$(MATHEMATICAL)
|
||||
|
||||
DSP_TTY_LIBS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)))
|
||||
DSP_TTY_SRCS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_SRCS))
|
||||
DSP_TTY_HDRS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_HDRS))
|
||||
DSP_TTY_CHECKS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_CHECKS))
|
||||
DSP_TTY_OBJS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_OBJS))
|
||||
$(DSP_TTY_OBJS): $(BUILD_FILES) dsp/tty/tty.mk
|
||||
|
||||
.PHONY: o/$(MODE)/dsp/tty
|
||||
o/$(MODE)/dsp/tty: $(DSP_TTY_CHECKS)
|
24
dsp/tty/tty2rgb24.c
Normal file
24
dsp/tty/tty2rgb24.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/quant.h"
|
||||
|
||||
struct TtyRgb tty2rgb24_(struct TtyRgb rgbxt) {
|
||||
return rgbxt;
|
||||
}
|
24
dsp/tty/tty2rgbf24.c
Normal file
24
dsp/tty/tty2rgbf24.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/quant.h"
|
||||
|
||||
__m128 tty2rgbf24_(struct TtyRgb rgbxt) {
|
||||
return (__m128){(int)rgbxt.r, (int)rgbxt.g, (int)rgbxt.b} / 255;
|
||||
}
|
51
dsp/tty/ttyhisto.c
Normal file
51
dsp/tty/ttyhisto.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
static int histcmp(const uint8_t *i1p, const uint8_t *i2p,
|
||||
uint32_t histogram[hasatleast 256]) {
|
||||
if (histogram[*i1p] > histogram[*i2p]) {
|
||||
return -1;
|
||||
} else if (histogram[*i1p] < histogram[*i2p]) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ttyhisto(uint32_t histogram[hasatleast 256],
|
||||
uint8_t dominant[hasatleast 256], const uint8_t *xtcolors,
|
||||
const uint8_t *eqmask, size_t size) {
|
||||
size_t i;
|
||||
uint64_t q;
|
||||
memset(histogram, 0, sizeof(uint32_t) * 256);
|
||||
for (i = 0; i < size / 8; ++i) {
|
||||
memcpy(&q, &xtcolors[i * 8], 8);
|
||||
if (q == (xtcolors[i * 8] & 0xff) * 0x0101010101010101ul) {
|
||||
histogram[xtcolors[i * 8]]++;
|
||||
}
|
||||
}
|
||||
imapxlatab(dominant);
|
||||
qsort_r(dominant, 256, 1, (void *)histcmp, histogram);
|
||||
}
|
198
dsp/tty/ttymove.c
Normal file
198
dsp/tty/ttymove.c
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/itoa8.h"
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
|
||||
/**
|
||||
* Moves teletypewriter cursor to new coordinate.
|
||||
*
|
||||
* This uses codings defined by ANSI X3.4-1967 / X3.64-1979.
|
||||
*
|
||||
* @param c [in/out] tracks cursor coordinate
|
||||
* @param p [out] buffer receives ANSI/VT sequences
|
||||
* @param y is 0-indexed row
|
||||
* @param x is 0-indexed column
|
||||
* @return p + written, like mempcpy()
|
||||
*/
|
||||
char *ttymove(struct TtyCursor *c, char *p, int y, int x) {
|
||||
int d;
|
||||
DCHECK_GE(y, 0);
|
||||
DCHECK_GE(x, 0);
|
||||
DCHECK_LE(y, UINT16_MAX);
|
||||
DCHECK_LE(x, UINT16_MAX);
|
||||
if (y != c->y || x != c->x) {
|
||||
do {
|
||||
if (y != c->y && x != c->x) {
|
||||
if (y == c->y + 1 && x == 0) {
|
||||
p[0] = '\r';
|
||||
p[1] = '\n';
|
||||
p[2] = '\0';
|
||||
p[3] = '\0';
|
||||
p += 2;
|
||||
c->y++;
|
||||
c->x = 0;
|
||||
break;
|
||||
} else if (x < 256 && y < 256) {
|
||||
if (y == 0 && x == 0) {
|
||||
if (c->y == 0) {
|
||||
p[0] = '\r';
|
||||
p[1] = '\0';
|
||||
p += 1;
|
||||
c->x = 0;
|
||||
} else {
|
||||
p[0] = '\e'; /* CUP(1,1) */
|
||||
p[1] = '[';
|
||||
p[2] = 'H';
|
||||
p[3] = '\0';
|
||||
p += 3;
|
||||
c->y = 0;
|
||||
c->x = 0;
|
||||
}
|
||||
} else if (x == 0) {
|
||||
*p++ = '\e'; /* CUP(y,1) */
|
||||
*p++ = '[';
|
||||
p = itoa8(p, y + 1);
|
||||
*p++ = 'H';
|
||||
*p = '\0';
|
||||
c->y = y;
|
||||
c->x = 0;
|
||||
} else if (y == 0) {
|
||||
*p++ = '\e'; /* CUP(1,x) */
|
||||
*p++ = '[';
|
||||
*p++ = ';';
|
||||
*p = '\0';
|
||||
p = itoa8(p, x + 1);
|
||||
*p++ = 'H';
|
||||
*p = '\0';
|
||||
c->y = 0;
|
||||
c->x = x;
|
||||
} else {
|
||||
*p++ = '\e'; /* CUP(y,1) */
|
||||
*p++ = '[';
|
||||
p = itoa8(p, y + 1);
|
||||
*p++ = ';';
|
||||
p = itoa8(p, x + 1);
|
||||
*p++ = 'H';
|
||||
*p = '\0';
|
||||
c->y = y;
|
||||
c->x = x;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (x != c->x) {
|
||||
if (!x) {
|
||||
p[0] = '\r'; /* goto beginning of line */
|
||||
p[1] = '\0';
|
||||
p += 1;
|
||||
c->x = 0;
|
||||
} else if (x > c->x) {
|
||||
d = min(255, x - c->x);
|
||||
if (d == 1) {
|
||||
p[0] = '\e';
|
||||
p[1] = '[';
|
||||
p[2] = 'C'; /* cursor forward (CUF) */
|
||||
p[3] = '\0';
|
||||
p += 3;
|
||||
} else {
|
||||
p[0] = '\e';
|
||||
p[1] = '[';
|
||||
p = itoa8(p + 2, d);
|
||||
p[0] = 'C'; /* cursor forward (CUF) */
|
||||
p[1] = '\0';
|
||||
p[2] = '\0';
|
||||
p[3] = '\0';
|
||||
p += 1;
|
||||
}
|
||||
c->x += d;
|
||||
} else {
|
||||
d = min(255, c->x - x);
|
||||
if (d == 1) {
|
||||
p[0] = '\e';
|
||||
p[1] = '[';
|
||||
p[2] = 'D'; /* cursor backward (CUB) */
|
||||
p[3] = '\0';
|
||||
p += 3;
|
||||
} else {
|
||||
p[0] = '\e';
|
||||
p[1] = '[';
|
||||
p = itoa8(p + 2, d);
|
||||
p[0] = 'D'; /* cursor backward (CUB) */
|
||||
p[1] = '\0';
|
||||
p[2] = '\0';
|
||||
p[3] = '\0';
|
||||
p += 1;
|
||||
}
|
||||
c->x -= d;
|
||||
}
|
||||
}
|
||||
if (y != c->y) {
|
||||
if (y > c->y) {
|
||||
d = min(255, y - c->y);
|
||||
if (d == 1) {
|
||||
p[0] = '\e';
|
||||
p[1] = 'D'; /* index down (IND) */
|
||||
p[2] = '\0';
|
||||
p[3] = '\0';
|
||||
p += 2;
|
||||
} else {
|
||||
p[0] = '\e';
|
||||
p[1] = '[';
|
||||
p = itoa8(p + 2, d);
|
||||
p[0] = 'B'; /* cursor down (CUD) */
|
||||
p[1] = '\0';
|
||||
p[2] = '\0';
|
||||
p[3] = '\0';
|
||||
p += 1;
|
||||
}
|
||||
c->y += d;
|
||||
} else {
|
||||
d = min(255, c->y - y);
|
||||
if (d == 1) {
|
||||
p[0] = '\e';
|
||||
p[1] = 'M'; /* reverse index (RI) */
|
||||
p[2] = '\0';
|
||||
p[3] = '\0';
|
||||
p += 2;
|
||||
} else {
|
||||
p[0] = '\e';
|
||||
p[1] = '[';
|
||||
p = itoa8(p + 2, d);
|
||||
p[0] = 'A'; /* cursor up (CUU) */
|
||||
p[1] = '\0';
|
||||
p[2] = '\0';
|
||||
p[3] = '\0';
|
||||
p += 1;
|
||||
}
|
||||
c->y -= d;
|
||||
}
|
||||
}
|
||||
} while (x != c->x || y != c->y);
|
||||
} else {
|
||||
p[0] = '\0';
|
||||
}
|
||||
DCHECK_EQ(y, c->y);
|
||||
DCHECK_EQ(x, c->x);
|
||||
DCHECK_EQ(p[0], '\0');
|
||||
return p;
|
||||
}
|
799
dsp/tty/ttyraster.c
Normal file
799
dsp/tty/ttyraster.c
Normal file
|
@ -0,0 +1,799 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/core/twixt8.h"
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "dsp/tty/ttyrgb.h"
|
||||
#include "dsp/tty/windex.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#define SQR(X) ((X) * (X))
|
||||
#define DIST(X, Y) ((X) - (Y))
|
||||
#define QSUB(A, B, C) ABS(DIST(A##C, B##C))
|
||||
#define DIFF(A, B) (QSUB(A, B, r) + QSUB(A, B, g) + QSUB(A, B, b))
|
||||
#define JUDGE(M) (DIFF(ttl, M) + DIFF(ttr, M) + DIFF(tbl, M) + DIFF(tbr, M))
|
||||
|
||||
static const struct Glyph {
|
||||
char c1, c2, c3, len;
|
||||
} kGlyphs[2][11] = {
|
||||
{{0x20, 0x00, 0x00, 1}, /* */
|
||||
{0xE2, 0x96, 0x84, 3}, /* ▄ */
|
||||
{0xE2, 0x96, 0x8C, 3}, /* ▌ */
|
||||
{0xE2, 0x96, 0x9D, 3}, /* ▝ */
|
||||
{0xE2, 0x96, 0x97, 3}, /* ▗ */
|
||||
{0xE2, 0x96, 0x96, 3}, /* ▖ */
|
||||
{0xE2, 0x96, 0x9E, 3}, /* ▞ */
|
||||
{0xE2, 0x96, 0x98, 3}, /* ▘ */
|
||||
{0xE2, 0x96, 0x91, 3}, /* ░ */
|
||||
{0xE2, 0x96, 0x93, 3}, /* ▓ */
|
||||
{0xE2, 0x96, 0x92, 3}}, /* ▒ */
|
||||
{{0xE2, 0x96, 0x88, 3}, /* █ */
|
||||
{0xE2, 0x96, 0x80, 3}, /* ▀ */
|
||||
{0xE2, 0x96, 0x90, 3}, /* ▐ */
|
||||
{0xE2, 0x96, 0x99, 3}, /* ▙ */
|
||||
{0xE2, 0x96, 0x9B, 3}, /* ▛ */
|
||||
{0xE2, 0x96, 0x9C, 3}, /* ▜ */
|
||||
{0xE2, 0x96, 0x9A, 3}, /* ▚ */
|
||||
{0xE2, 0x96, 0x9F, 3}, /* ▟ */
|
||||
{0xE2, 0x96, 0x93, 3}, /* ▓ */
|
||||
{0xE2, 0x96, 0x91, 3}, /* ░ */
|
||||
{0xE2, 0x96, 0x92, 3}}, /* ▒ */
|
||||
};
|
||||
|
||||
static const struct Pick {
|
||||
unsigned char fg, bg, k;
|
||||
} kPicksUnicode[96] = {
|
||||
{-1, BL, 0}, /* */
|
||||
{BR, BL, 4}, /* ▗ */
|
||||
{TL, BL, 4}, /* ▗ */
|
||||
{TR, BL, 4}, /* ▗ */
|
||||
{BR, BL, 5}, /* ▖ */
|
||||
{BR, BL, 1}, /* ▄ */
|
||||
{TL, BL, 5}, /* ▖ */
|
||||
{TL, BL, 1}, /* ▄ */
|
||||
{TR, BL, 5}, /* ▖ */
|
||||
{TR, BL, 1}, /* ▄ */
|
||||
{BR, BL, 3}, /* ▝ */
|
||||
{BL, BR, 2}, /* ▌ */
|
||||
{BR, BL, 6}, /* ▞ */
|
||||
{BL, BR, 7}, /* ▘ */
|
||||
{TL, BL, 3}, /* ▝ */
|
||||
{BL, TL, 2}, /* ▌ */
|
||||
{TL, BL, 6}, /* ▞ */
|
||||
{BL, TL, 7}, /* ▘ */
|
||||
{TR, BL, 3}, /* ▝ */
|
||||
{BL, TR, 2}, /* ▌ */
|
||||
{TR, BL, 6}, /* ▞ */
|
||||
{BL, TR, 7}, /* ▘ */
|
||||
{BR, BL, 7}, /* ▘ */
|
||||
{BL, BR, 6}, /* ▞ */
|
||||
{BR, BL, 2}, /* ▌ */
|
||||
{BL, BR, 3}, /* ▝ */
|
||||
{BL, BR, 1}, /* ▄ */
|
||||
{BL, BR, 5}, /* ▖ */
|
||||
{BL, BR, 4}, /* ▗ */
|
||||
{-1, BR, 0}, /* */
|
||||
{TL, BR, 4}, /* ▗ */
|
||||
{TR, BR, 4}, /* ▗ */
|
||||
{TL, BR, 5}, /* ▖ */
|
||||
{TL, BR, 1}, /* ▄ */
|
||||
{TR, BR, 5}, /* ▖ */
|
||||
{TR, BR, 1}, /* ▄ */
|
||||
{TL, BR, 3}, /* ▝ */
|
||||
{BR, TL, 2}, /* ▌ */
|
||||
{TL, BR, 6}, /* ▞ */
|
||||
{BR, TL, 7}, /* ▘ */
|
||||
{TR, BR, 3}, /* ▝ */
|
||||
{BR, TR, 2}, /* ▌ */
|
||||
{TR, BR, 6}, /* ▞ */
|
||||
{BR, TR, 7}, /* ▘ */
|
||||
{TL, BL, 7}, /* ▘ */
|
||||
{BL, TL, 6}, /* ▞ */
|
||||
{TL, BL, 2}, /* ▌ */
|
||||
{BL, TL, 3}, /* ▝ */
|
||||
{TL, BR, 7}, /* ▘ */
|
||||
{BR, TL, 6}, /* ▞ */
|
||||
{TL, BR, 2}, /* ▌ */
|
||||
{BR, TL, 3}, /* ▝ */
|
||||
{BL, TL, 1}, /* ▄ */
|
||||
{BL, TL, 5}, /* ▖ */
|
||||
{BR, TL, 1}, /* ▄ */
|
||||
{BR, TL, 5}, /* ▖ */
|
||||
{BL, TL, 4}, /* ▗ */
|
||||
{BR, TL, 4}, /* ▗ */
|
||||
{-1, TL, 0}, /* */
|
||||
{TR, TL, 4}, /* ▗ */
|
||||
{TR, TL, 5}, /* ▖ */
|
||||
{TR, TL, 1}, /* ▄ */
|
||||
{TR, TL, 3}, /* ▝ */
|
||||
{TL, TR, 2}, /* ▌ */
|
||||
{TR, TL, 6}, /* ▞ */
|
||||
{TL, TR, 7}, /* ▘ */
|
||||
{TR, BL, 7}, /* ▘ */
|
||||
{BL, TR, 6}, /* ▞ */
|
||||
{TR, BL, 2}, /* ▌ */
|
||||
{BL, TR, 3}, /* ▝ */
|
||||
{TR, BR, 7}, /* ▘ */
|
||||
{BR, TR, 6}, /* ▞ */
|
||||
{TR, BR, 2}, /* ▌ */
|
||||
{BR, TR, 3}, /* ▝ */
|
||||
{TR, TL, 7}, /* ▘ */
|
||||
{TL, TR, 6}, /* ▞ */
|
||||
{TR, TL, 2}, /* ▌ */
|
||||
{TL, TR, 3}, /* ▝ */
|
||||
{BL, TR, 1}, /* ▄ */
|
||||
{BL, TR, 5}, /* ▖ */
|
||||
{BR, TR, 1}, /* ▄ */
|
||||
{BR, TR, 5}, /* ▖ */
|
||||
{TL, TR, 1}, /* ▄ */
|
||||
{TL, TR, 5}, /* ▖ */
|
||||
{BL, TR, 4}, /* ▗ */
|
||||
{BR, TR, 4}, /* ▗ */
|
||||
{TL, TR, 4}, /* ▗ */
|
||||
{-1, TR, 0}, /* */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
};
|
||||
|
||||
static const struct Pick kPicksCp437[32] = {
|
||||
{-1, BL, 0}, /* */
|
||||
{BR, BL, 1}, /* ▄ */
|
||||
{TL, BL, 1}, /* ▄ */
|
||||
{TR, BL, 1}, /* ▄ */
|
||||
{BL, BR, 1}, /* ▄ */
|
||||
{BL, TL, 1}, /* ▄ */
|
||||
{BL, TR, 1}, /* ▄ */
|
||||
{BL, BR, 2}, /* ▌ */
|
||||
{BL, TL, 2}, /* ▌ */
|
||||
{BL, TR, 2}, /* ▌ */
|
||||
{BR, BL, 2}, /* ▌ */
|
||||
{-1, BR, 0}, /* */
|
||||
{TL, BR, 1}, /* ▄ */
|
||||
{TR, BR, 1}, /* ▄ */
|
||||
{BR, TL, 2}, /* ▌ */
|
||||
{BR, TR, 2}, /* ▌ */
|
||||
{TL, BL, 2}, /* ▌ */
|
||||
{TL, BR, 2}, /* ▌ */
|
||||
{BR, TL, 1}, /* ▄ */
|
||||
{-1, TL, 0}, /* */
|
||||
{TR, TL, 1}, /* ▄ */
|
||||
{TL, TR, 2}, /* ▌ */
|
||||
{TR, BL, 2}, /* ▌ */
|
||||
{TR, BR, 2}, /* ▌ */
|
||||
{TR, TL, 2}, /* ▌ */
|
||||
{BR, TR, 1}, /* ▄ */
|
||||
{TL, TR, 1}, /* ▄ */
|
||||
{-1, TR, 0}, /* */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
{-1, -1, -1}, /* X */
|
||||
};
|
||||
|
||||
static const struct Pick kPicksMixBlock[32] = {
|
||||
{BR, BL, 8}, /* ░ */
|
||||
{BR, BL, 9}, /* ▓ */
|
||||
{TL, BL, 8}, /* ░ */
|
||||
{TL, BL, 9}, /* ▓ */
|
||||
{TR, BL, 8}, /* ░ */
|
||||
{TR, BL, 9}, /* ▓ */
|
||||
{TL, BR, 8}, /* ░ */
|
||||
{TL, BR, 9}, /* ▓ */
|
||||
{TR, BR, 8}, /* ░ */
|
||||
{TR, BR, 9}, /* ▓ */
|
||||
{BL, TL, 8}, /* ░ */
|
||||
{BL, TL, 9}, /* ▓ */
|
||||
{BL, TL, 8}, /* ░ */
|
||||
{BL, TL, 9}, /* ▓ */
|
||||
{TR, TL, 8}, /* ░ */
|
||||
{TR, TL, 9}, /* ▓ */
|
||||
{BL, TR, 8}, /* ░ */
|
||||
{BL, TR, 9}, /* ▓ */
|
||||
{BR, TR, 8}, /* ░ */
|
||||
{BR, TR, 9}, /* ▓ */
|
||||
{TL, TR, 8}, /* ░ */
|
||||
{TL, TR, 9}, /* ▓ */
|
||||
/**/
|
||||
{BL, TL, 8}, /* ░ */
|
||||
{BL, TL, 9}, /* ▓ */
|
||||
{TR, TL, 8}, /* ░ */
|
||||
{TR, TL, 9}, /* ▓ */
|
||||
{BL, TR, 8}, /* ░ */
|
||||
{BL, TR, 9}, /* ▓ */
|
||||
{BR, TR, 8}, /* ░ */
|
||||
{BR, TR, 9}, /* ▓ */
|
||||
{TL, TR, 8}, /* ░ */
|
||||
{TL, TR, 9}, /* ▓ */
|
||||
};
|
||||
|
||||
static unsigned short bdist(struct TtyRgb a, struct TtyRgb b, struct TtyRgb c,
|
||||
struct TtyRgb d, struct TtyRgb w, struct TtyRgb x,
|
||||
struct TtyRgb y, struct TtyRgb z) {
|
||||
unsigned short dist;
|
||||
dist = 0;
|
||||
dist += ABS(a.r - w.r);
|
||||
dist += ABS(a.g - w.g);
|
||||
dist += ABS(a.b - w.b);
|
||||
dist += ABS(b.r - x.r);
|
||||
dist += ABS(b.g - x.g);
|
||||
dist += ABS(b.b - x.b);
|
||||
dist += ABS(c.r - y.r);
|
||||
dist += ABS(c.g - y.g);
|
||||
dist += ABS(c.b - y.b);
|
||||
dist += ABS(d.r - z.r);
|
||||
dist += ABS(d.g - z.g);
|
||||
dist += ABS(d.b - z.b);
|
||||
return dist;
|
||||
}
|
||||
|
||||
static uint16_t *mixblock(uint16_t *p, struct TtyRgb ttl, struct TtyRgb ttr,
|
||||
struct TtyRgb tbl, struct TtyRgb tbr,
|
||||
struct TtyRgb qtl, struct TtyRgb qtr,
|
||||
struct TtyRgb qbl, struct TtyRgb qbr) {
|
||||
unsigned char ttlr, ttlg, ttlb, qtlr, qtlg, qtlb, ttrr, ttrg, ttrb, qtrr,
|
||||
qtrg, qtrb, tblr, tblg, tblb, qblr, qblg, qblb, tbrr, tbrg, tbrb, qbrr,
|
||||
qbrg, qbrb, l00r, l00g, l00b, l01r, l01g, l01b, l02r, l02g, l02b, l03r,
|
||||
l03g, l03b, l04r, l04g, l04b, l05r, l05g, l05b, l06r, l06g, l06b, l07r,
|
||||
l07g, l07b, l08r, l08g, l08b, l09r, l09g, l09b, l10r, l10g, l10b, l11r,
|
||||
l11g, l11b, l12r, l12g, l12b, l13r, l13g, l13b, l14r, l14g, l14b, l15r,
|
||||
l15g, l15b, l16r, l16g, l16b, l17r, l17g, l17b, l18r, l18g, l18b, l19r,
|
||||
l19g, l19b, l20r, l20g, l20b, l21r, l21g, l21b, l22r, l22g, l22b, l23r,
|
||||
l23g, l23b, l24r, l24g, l24b, l25r, l25g, l25b, l26r, l26g, l26b, l27r,
|
||||
l27g, l27b, l28r, l28g, l28b, l29r, l29g, l29b, l30r, l30g, l30b, l31r,
|
||||
l31g, l31b;
|
||||
unsigned short p00, p01, p02, p03, p04, p05, p06, p07, p08, p09, p10, p11,
|
||||
p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26,
|
||||
p27, p28, p29, p30, p31;
|
||||
ttlr = ttl.r;
|
||||
ttlg = ttl.g;
|
||||
ttlb = ttl.b;
|
||||
qtlr = qtl.r;
|
||||
qtlg = qtl.g;
|
||||
qtlb = qtl.b;
|
||||
ttrr = ttr.r;
|
||||
ttrg = ttr.g;
|
||||
ttrb = ttr.b;
|
||||
qtrr = qtr.r;
|
||||
qtrg = qtr.g;
|
||||
qtrb = qtr.b;
|
||||
tblr = tbl.r;
|
||||
tblg = tbl.g;
|
||||
tblb = tbl.b;
|
||||
qblr = qbl.r;
|
||||
qblg = qbl.g;
|
||||
qblb = qbl.b;
|
||||
tbrr = tbr.r;
|
||||
tbrg = tbr.g;
|
||||
tbrb = tbr.b;
|
||||
qbrr = qbr.r;
|
||||
qbrg = qbr.g;
|
||||
qbrb = qbr.b;
|
||||
l00r = twixt8(qblr, qbrr, 0100);
|
||||
l00g = twixt8(qblg, qbrg, 0100);
|
||||
l00b = twixt8(qblb, qbrb, 0100);
|
||||
l01r = twixt8(qblr, qbrr, 0300);
|
||||
l01g = twixt8(qblg, qbrg, 0300);
|
||||
l01b = twixt8(qblb, qbrb, 0300);
|
||||
l02r = twixt8(qblr, qbrr, 0200);
|
||||
l02g = twixt8(qblg, qbrg, 0200);
|
||||
l02b = twixt8(qblb, qbrb, 0200);
|
||||
l03r = twixt8(qblr, qtlr, 0100);
|
||||
l03g = twixt8(qblg, qtlg, 0100);
|
||||
l03b = twixt8(qblb, qtlb, 0100);
|
||||
l04r = twixt8(qblr, qtlr, 0300);
|
||||
l04g = twixt8(qblg, qtlg, 0300);
|
||||
l04b = twixt8(qblb, qtlb, 0300);
|
||||
l05r = twixt8(qblr, qtlr, 0200);
|
||||
l05g = twixt8(qblg, qtlg, 0200);
|
||||
l05b = twixt8(qblb, qtlb, 0200);
|
||||
l06r = twixt8(qblr, qtrr, 0100);
|
||||
l06g = twixt8(qblg, qtrg, 0100);
|
||||
l06b = twixt8(qblb, qtrb, 0100);
|
||||
l07r = twixt8(qblr, qtrr, 0300);
|
||||
l07g = twixt8(qblg, qtrg, 0300);
|
||||
l07b = twixt8(qblb, qtrb, 0300);
|
||||
l08r = twixt8(qblr, qtrr, 0200);
|
||||
l08g = twixt8(qblg, qtrg, 0200);
|
||||
l08b = twixt8(qblb, qtrb, 0200);
|
||||
l09r = twixt8(qbrr, qtlr, 0100);
|
||||
l09g = twixt8(qbrg, qtlg, 0100);
|
||||
l09b = twixt8(qbrb, qtlb, 0100);
|
||||
l10r = twixt8(qbrr, qtlr, 0300);
|
||||
l10g = twixt8(qbrg, qtlg, 0300);
|
||||
l10b = twixt8(qbrb, qtlb, 0300);
|
||||
l11r = twixt8(qbrr, qtlr, 0200);
|
||||
l11g = twixt8(qbrg, qtlg, 0200);
|
||||
l11b = twixt8(qbrb, qtlb, 0200);
|
||||
l12r = twixt8(qbrr, qtrr, 0100);
|
||||
l12g = twixt8(qbrg, qtrg, 0100);
|
||||
l12b = twixt8(qbrb, qtrb, 0100);
|
||||
l13r = twixt8(qbrr, qtrr, 0300);
|
||||
l13g = twixt8(qbrg, qtrg, 0300);
|
||||
l13b = twixt8(qbrb, qtrb, 0300);
|
||||
l14r = twixt8(qbrr, qtrr, 0200);
|
||||
l14g = twixt8(qbrg, qtrg, 0200);
|
||||
l14b = twixt8(qbrb, qtrb, 0200);
|
||||
l15r = twixt8(qtlr, qblr, 0100);
|
||||
l15g = twixt8(qtlg, qblg, 0100);
|
||||
l15b = twixt8(qtlb, qblb, 0100);
|
||||
l16r = twixt8(qtlr, qblr, 0300);
|
||||
l16g = twixt8(qtlg, qblg, 0300);
|
||||
l16b = twixt8(qtlb, qblb, 0300);
|
||||
l17r = twixt8(qtlr, qblr, 0200);
|
||||
l17g = twixt8(qtlg, qblg, 0200);
|
||||
l17b = twixt8(qtlb, qblb, 0200);
|
||||
l18r = twixt8(qtlr, qbrr, 0100);
|
||||
l18g = twixt8(qtlg, qbrg, 0100);
|
||||
l18b = twixt8(qtlb, qbrb, 0100);
|
||||
l19r = twixt8(qtlr, qbrr, 0300);
|
||||
l19g = twixt8(qtlg, qbrg, 0300);
|
||||
l19b = twixt8(qtlb, qbrb, 0300);
|
||||
l20r = twixt8(qtlr, qbrr, 0200);
|
||||
l20g = twixt8(qtlg, qbrg, 0200);
|
||||
l20b = twixt8(qtlb, qbrb, 0200);
|
||||
l21r = twixt8(qtlr, qtrr, 0100);
|
||||
l21g = twixt8(qtlg, qtrg, 0100);
|
||||
l21b = twixt8(qtlb, qtrb, 0100);
|
||||
l22r = twixt8(qtlr, qtrr, 0300);
|
||||
l22g = twixt8(qtlg, qtrg, 0300);
|
||||
l22b = twixt8(qtlb, qtrb, 0300);
|
||||
l23r = twixt8(qtlr, qtrr, 0200);
|
||||
l23g = twixt8(qtlg, qtrg, 0200);
|
||||
l23b = twixt8(qtlb, qtrb, 0200);
|
||||
l24r = twixt8(qtrr, qblr, 0100);
|
||||
l24g = twixt8(qtrg, qblg, 0100);
|
||||
l24b = twixt8(qtrb, qblb, 0100);
|
||||
l25r = twixt8(qtrr, qblr, 0300);
|
||||
l25g = twixt8(qtrg, qblg, 0300);
|
||||
l25b = twixt8(qtrb, qblb, 0300);
|
||||
l26r = twixt8(qtrr, qblr, 0200);
|
||||
l26g = twixt8(qtrg, qblg, 0200);
|
||||
l26b = twixt8(qtrb, qblb, 0200);
|
||||
l27r = twixt8(qtrr, qbrr, 0100);
|
||||
l27g = twixt8(qtrg, qbrg, 0100);
|
||||
l27b = twixt8(qtrb, qbrb, 0100);
|
||||
l28r = twixt8(qtrr, qbrr, 0300);
|
||||
l28g = twixt8(qtrg, qbrg, 0300);
|
||||
l28b = twixt8(qtrb, qbrb, 0300);
|
||||
l29r = twixt8(qtrr, qbrr, 0200);
|
||||
l29g = twixt8(qtrg, qbrg, 0200);
|
||||
l29b = twixt8(qtrb, qbrb, 0200);
|
||||
l30r = twixt8(qtrr, qtlr, 0100);
|
||||
l30g = twixt8(qtrg, qtlg, 0100);
|
||||
l30b = twixt8(qtrb, qtlb, 0100);
|
||||
l31r = twixt8(qtrr, qtlr, 0300);
|
||||
l31g = twixt8(qtrg, qtlg, 0300);
|
||||
l31b = twixt8(qtrb, qtlb, 0300);
|
||||
p00 = JUDGE(l00);
|
||||
p01 = JUDGE(l01);
|
||||
p02 = JUDGE(l02);
|
||||
p03 = JUDGE(l03);
|
||||
p04 = JUDGE(l04);
|
||||
p05 = JUDGE(l05);
|
||||
p06 = JUDGE(l06);
|
||||
p07 = JUDGE(l07);
|
||||
p08 = JUDGE(l08);
|
||||
p09 = JUDGE(l09);
|
||||
p10 = JUDGE(l10);
|
||||
p11 = JUDGE(l11);
|
||||
p12 = JUDGE(l12);
|
||||
p13 = JUDGE(l13);
|
||||
p14 = JUDGE(l14);
|
||||
p15 = JUDGE(l15);
|
||||
p16 = JUDGE(l16);
|
||||
p17 = JUDGE(l17);
|
||||
p18 = JUDGE(l18);
|
||||
p19 = JUDGE(l19);
|
||||
p20 = JUDGE(l20);
|
||||
p21 = JUDGE(l21);
|
||||
p22 = JUDGE(l22);
|
||||
p23 = JUDGE(l23);
|
||||
p24 = JUDGE(l24);
|
||||
p25 = JUDGE(l25);
|
||||
p26 = JUDGE(l26);
|
||||
p27 = JUDGE(l27);
|
||||
p28 = JUDGE(l28);
|
||||
p29 = JUDGE(l29);
|
||||
p30 = JUDGE(l30);
|
||||
p31 = JUDGE(l31);
|
||||
*p++ = p00;
|
||||
*p++ = p01;
|
||||
*p++ = p02;
|
||||
*p++ = p03;
|
||||
*p++ = p04;
|
||||
*p++ = p05;
|
||||
*p++ = p06;
|
||||
*p++ = p07;
|
||||
*p++ = p08;
|
||||
*p++ = p09;
|
||||
*p++ = p10;
|
||||
*p++ = p11;
|
||||
*p++ = p12;
|
||||
*p++ = p13;
|
||||
*p++ = p14;
|
||||
*p++ = p15;
|
||||
*p++ = p16;
|
||||
*p++ = p17;
|
||||
*p++ = p18;
|
||||
*p++ = p19;
|
||||
*p++ = p20;
|
||||
*p++ = p21;
|
||||
*p++ = p22;
|
||||
*p++ = p23;
|
||||
*p++ = p24;
|
||||
*p++ = p25;
|
||||
*p++ = p26;
|
||||
*p++ = p27;
|
||||
*p++ = p28;
|
||||
*p++ = p29;
|
||||
*p++ = p30;
|
||||
*p++ = p31;
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct TtyRgb getquant(struct TtyRgb rgb) {
|
||||
return g_ansi2rgb_[rgb.xt];
|
||||
}
|
||||
|
||||
static uint16_t *pickunicode(uint16_t *p, struct TtyRgb tl, struct TtyRgb tr,
|
||||
struct TtyRgb bl, struct TtyRgb br,
|
||||
struct TtyRgb tl2, struct TtyRgb tr2,
|
||||
struct TtyRgb bl2, struct TtyRgb br2) {
|
||||
#define PICK(A, B, C, D) *p++ = bdist(tl, tr, bl, br, A, B, C, D)
|
||||
PICK(bl2, bl2, bl2, bl2); /* k=0 bg=bl fg=NULL */
|
||||
PICK(bl2, bl2, bl2, br2); /* ▗ k=4 bg=bl fg=br */
|
||||
PICK(bl2, bl2, bl2, tl2); /* ▗ k=4 bg=bl fg=tl */
|
||||
PICK(bl2, bl2, bl2, tr2); /* ▗ k=4 bg=bl fg=tr */
|
||||
PICK(bl2, bl2, br2, bl2); /* ▖ k=5 bg=bl fg=br */
|
||||
PICK(bl2, bl2, br2, br2); /* ▄ k=1 bg=bl fg=br */
|
||||
PICK(bl2, bl2, tl2, bl2); /* ▖ k=5 bg=bl fg=tl */
|
||||
PICK(bl2, bl2, tl2, tl2); /* ▄ k=1 bg=bl fg=tl */
|
||||
PICK(bl2, bl2, tr2, bl2); /* ▖ k=5 bg=bl fg=tr */
|
||||
PICK(bl2, bl2, tr2, tr2); /* ▄ k=1 bg=bl fg=tr */
|
||||
PICK(bl2, br2, bl2, bl2); /* ▝ k=3 bg=bl fg=br */
|
||||
PICK(bl2, br2, bl2, br2); /* ▌ k=2 bg=br fg=bl */
|
||||
PICK(bl2, br2, br2, bl2); /* ▞ k=6 bg=bl fg=br */
|
||||
PICK(bl2, br2, br2, br2); /* ▘ k=7 bg=br fg=bl */
|
||||
PICK(bl2, tl2, bl2, bl2); /* ▝ k=3 bg=bl fg=tl */
|
||||
PICK(bl2, tl2, bl2, tl2); /* ▌ k=2 bg=tl fg=bl */
|
||||
PICK(bl2, tl2, tl2, bl2); /* ▞ k=6 bg=bl fg=tl */
|
||||
PICK(bl2, tl2, tl2, tl2); /* ▘ k=7 bg=tl fg=bl */
|
||||
PICK(bl2, tr2, bl2, bl2); /* ▝ k=3 bg=bl fg=tr */
|
||||
PICK(bl2, tr2, bl2, tr2); /* ▌ k=2 bg=tr fg=bl */
|
||||
PICK(bl2, tr2, tr2, bl2); /* ▞ k=6 bg=bl fg=tr */
|
||||
PICK(bl2, tr2, tr2, tr2); /* ▘ k=7 bg=tr fg=bl */
|
||||
PICK(br2, bl2, bl2, bl2); /* ▘ k=7 bg=bl fg=br */
|
||||
PICK(br2, bl2, bl2, br2); /* ▞ k=6 bg=br fg=bl */
|
||||
PICK(br2, bl2, br2, bl2); /* ▌ k=2 bg=bl fg=br */
|
||||
PICK(br2, bl2, br2, br2); /* ▝ k=3 bg=br fg=bl */
|
||||
PICK(br2, br2, bl2, bl2); /* ▄ k=1 bg=br fg=bl */
|
||||
PICK(br2, br2, bl2, br2); /* ▖ k=5 bg=br fg=bl */
|
||||
PICK(br2, br2, br2, bl2); /* ▗ k=4 bg=br fg=bl */
|
||||
PICK(br2, br2, br2, br2); /* k=0 bg=br fg=NULL */
|
||||
PICK(br2, br2, br2, tl2); /* ▗ k=4 bg=br fg=tl */
|
||||
PICK(br2, br2, br2, tr2); /* ▗ k=4 bg=br fg=tr */
|
||||
PICK(br2, br2, tl2, br2); /* ▖ k=5 bg=br fg=tl */
|
||||
PICK(br2, br2, tl2, tl2); /* ▄ k=1 bg=br fg=tl */
|
||||
PICK(br2, br2, tr2, br2); /* ▖ k=5 bg=br fg=tr */
|
||||
PICK(br2, br2, tr2, tr2); /* ▄ k=1 bg=br fg=tr */
|
||||
PICK(br2, tl2, br2, br2); /* ▝ k=3 bg=br fg=tl */
|
||||
PICK(br2, tl2, br2, tl2); /* ▌ k=2 bg=tl fg=br */
|
||||
PICK(br2, tl2, tl2, br2); /* ▞ k=6 bg=br fg=tl */
|
||||
PICK(br2, tl2, tl2, tl2); /* ▘ k=7 bg=tl fg=br */
|
||||
PICK(br2, tr2, br2, br2); /* ▝ k=3 bg=br fg=tr */
|
||||
PICK(br2, tr2, br2, tr2); /* ▌ k=2 bg=tr fg=br */
|
||||
PICK(br2, tr2, tr2, br2); /* ▞ k=6 bg=br fg=tr */
|
||||
PICK(br2, tr2, tr2, tr2); /* ▘ k=7 bg=tr fg=br */
|
||||
PICK(tl2, bl2, bl2, bl2); /* ▘ k=7 bg=bl fg=tl */
|
||||
PICK(tl2, bl2, bl2, tl2); /* ▞ k=6 bg=tl fg=bl */
|
||||
PICK(tl2, bl2, tl2, bl2); /* ▌ k=2 bg=bl fg=tl */
|
||||
PICK(tl2, bl2, tl2, tl2); /* ▝ k=3 bg=tl fg=bl */
|
||||
PICK(tl2, br2, br2, br2); /* ▘ k=7 bg=br fg=tl */
|
||||
PICK(tl2, br2, br2, tl2); /* ▞ k=6 bg=tl fg=br */
|
||||
PICK(tl2, br2, tl2, br2); /* ▌ k=2 bg=br fg=tl */
|
||||
PICK(tl2, br2, tl2, tl2); /* ▝ k=3 bg=tl fg=br */
|
||||
PICK(tl2, tl2, bl2, bl2); /* ▄ k=1 bg=tl fg=bl */
|
||||
PICK(tl2, tl2, bl2, tl2); /* ▖ k=5 bg=tl fg=bl */
|
||||
PICK(tl2, tl2, br2, br2); /* ▄ k=1 bg=tl fg=br */
|
||||
PICK(tl2, tl2, br2, tl2); /* ▖ k=5 bg=tl fg=br */
|
||||
PICK(tl2, tl2, tl2, bl2); /* ▗ k=4 bg=tl fg=bl */
|
||||
PICK(tl2, tl2, tl2, br2); /* ▗ k=4 bg=tl fg=br */
|
||||
PICK(tl2, tl2, tl2, tl2); /* k=0 bg=tl fg=NULL */
|
||||
PICK(tl2, tl2, tl2, tr2); /* ▗ k=4 bg=tl fg=tr */
|
||||
PICK(tl2, tl2, tr2, tl2); /* ▖ k=5 bg=tl fg=tr */
|
||||
PICK(tl2, tl2, tr2, tr2); /* ▄ k=1 bg=tl fg=tr */
|
||||
PICK(tl2, tr2, tl2, tl2); /* ▝ k=3 bg=tl fg=tr */
|
||||
PICK(tl2, tr2, tl2, tr2); /* ▌ k=2 bg=tr fg=tl */
|
||||
PICK(tl2, tr2, tr2, tl2); /* ▞ k=6 bg=tl fg=tr */
|
||||
PICK(tl2, tr2, tr2, tr2); /* ▘ k=7 bg=tr fg=tl */
|
||||
PICK(tr2, bl2, bl2, bl2); /* ▘ k=7 bg=bl fg=tr */
|
||||
PICK(tr2, bl2, bl2, tr2); /* ▞ k=6 bg=tr fg=bl */
|
||||
PICK(tr2, bl2, tr2, bl2); /* ▌ k=2 bg=bl fg=tr */
|
||||
PICK(tr2, bl2, tr2, tr2); /* ▝ k=3 bg=tr fg=bl */
|
||||
PICK(tr2, br2, br2, br2); /* ▘ k=7 bg=br fg=tr */
|
||||
PICK(tr2, br2, br2, tr2); /* ▞ k=6 bg=tr fg=br */
|
||||
PICK(tr2, br2, tr2, br2); /* ▌ k=2 bg=br fg=tr */
|
||||
PICK(tr2, br2, tr2, tr2); /* ▝ k=3 bg=tr fg=br */
|
||||
PICK(tr2, tl2, tl2, tl2); /* ▘ k=7 bg=tl fg=tr */
|
||||
PICK(tr2, tl2, tl2, tr2); /* ▞ k=6 bg=tr fg=tl */
|
||||
PICK(tr2, tl2, tr2, tl2); /* ▌ k=2 bg=tl fg=tr */
|
||||
PICK(tr2, tl2, tr2, tr2); /* ▝ k=3 bg=tr fg=tl */
|
||||
PICK(tr2, tr2, bl2, bl2); /* ▄ k=1 bg=tr fg=bl */
|
||||
PICK(tr2, tr2, bl2, tr2); /* ▖ k=5 bg=tr fg=bl */
|
||||
PICK(tr2, tr2, br2, br2); /* ▄ k=1 bg=tr fg=br */
|
||||
PICK(tr2, tr2, br2, tr2); /* ▖ k=5 bg=tr fg=br */
|
||||
PICK(tr2, tr2, tl2, tl2); /* ▄ k=1 bg=tr fg=tl */
|
||||
PICK(tr2, tr2, tl2, tr2); /* ▖ k=5 bg=tr fg=tl */
|
||||
PICK(tr2, tr2, tr2, bl2); /* ▗ k=4 bg=tr fg=bl */
|
||||
PICK(tr2, tr2, tr2, br2); /* ▗ k=4 bg=tr fg=br */
|
||||
PICK(tr2, tr2, tr2, tl2); /* ▗ k=4 bg=tr fg=tl */
|
||||
PICK(tr2, tr2, tr2, tr2); /* k=0 bg=tr fg=NULL */
|
||||
#undef PICK
|
||||
return p;
|
||||
}
|
||||
|
||||
static uint16_t *pickcp437(uint16_t *p, struct TtyRgb tl, struct TtyRgb tr,
|
||||
struct TtyRgb bl, struct TtyRgb br,
|
||||
struct TtyRgb tl2, struct TtyRgb tr2,
|
||||
struct TtyRgb bl2, struct TtyRgb br2) {
|
||||
#define PICK(A, B, C, D) *p++ = bdist(tl, tr, bl, br, A, B, C, D)
|
||||
PICK(bl2, bl2, bl2, bl2); /* k=0 bg=bl fg=NULL */
|
||||
PICK(bl2, bl2, br2, br2); /* ▄ k=1 bg=bl fg=br */
|
||||
PICK(bl2, bl2, tl2, tl2); /* ▄ k=1 bg=bl fg=tl */
|
||||
PICK(bl2, bl2, tr2, tr2); /* ▄ k=1 bg=bl fg=tr */
|
||||
PICK(br2, br2, bl2, bl2); /* ▄ k=1 bg=br fg=bl */
|
||||
PICK(tl2, tl2, bl2, bl2); /* ▄ k=1 bg=tl fg=bl */
|
||||
PICK(tr2, tr2, bl2, bl2); /* ▄ k=1 bg=tr fg=bl */
|
||||
PICK(bl2, br2, bl2, br2); /* ▌ k=2 bg=br fg=bl */
|
||||
PICK(bl2, tl2, bl2, tl2); /* ▌ k=2 bg=tl fg=bl */
|
||||
PICK(bl2, tr2, bl2, tr2); /* ▌ k=2 bg=tr fg=bl */
|
||||
PICK(br2, bl2, br2, bl2); /* ▌ k=2 bg=bl fg=br */
|
||||
PICK(br2, br2, br2, br2); /* k=0 bg=br fg=NULL */
|
||||
PICK(br2, br2, tl2, tl2); /* ▄ k=1 bg=br fg=tl */
|
||||
PICK(br2, br2, tr2, tr2); /* ▄ k=1 bg=br fg=tr */
|
||||
PICK(br2, tl2, br2, tl2); /* ▌ k=2 bg=tl fg=br */
|
||||
PICK(br2, tr2, br2, tr2); /* ▌ k=2 bg=tr fg=br */
|
||||
PICK(tl2, bl2, tl2, bl2); /* ▌ k=2 bg=bl fg=tl */
|
||||
PICK(tl2, br2, tl2, br2); /* ▌ k=2 bg=br fg=tl */
|
||||
PICK(tl2, tl2, br2, br2); /* ▄ k=1 bg=tl fg=br */
|
||||
PICK(tl2, tl2, tl2, tl2); /* k=0 bg=tl fg=NULL */
|
||||
PICK(tl2, tl2, tr2, tr2); /* ▄ k=1 bg=tl fg=tr */
|
||||
PICK(tl2, tr2, tl2, tr2); /* ▌ k=2 bg=tr fg=tl */
|
||||
PICK(tr2, bl2, tr2, bl2); /* ▌ k=2 bg=bl fg=tr */
|
||||
PICK(tr2, br2, tr2, br2); /* ▌ k=2 bg=br fg=tr */
|
||||
PICK(tr2, tl2, tr2, tl2); /* ▌ k=2 bg=tl fg=tr */
|
||||
PICK(tr2, tr2, br2, br2); /* ▄ k=1 bg=tr fg=br */
|
||||
PICK(tr2, tr2, tl2, tl2); /* ▄ k=1 bg=tr fg=tl */
|
||||
PICK(tr2, tr2, tr2, tr2); /* k=0 bg=tr fg=NULL */
|
||||
#undef PICK
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct Pick pickblock_unicode_ansi(struct TtyRgb tl, struct TtyRgb tr,
|
||||
struct TtyRgb bl, struct TtyRgb br) {
|
||||
struct TtyRgb tl2 = getquant(tl);
|
||||
struct TtyRgb tr2 = getquant(tr);
|
||||
struct TtyRgb bl2 = getquant(bl);
|
||||
struct TtyRgb br2 = getquant(br);
|
||||
unsigned i, p1, p2;
|
||||
uint16_t picks1[96] aligned(32);
|
||||
uint16_t picks2[32] aligned(32);
|
||||
memset(picks1, 0x79, sizeof(picks1));
|
||||
memset(picks2, 0x79, sizeof(picks2));
|
||||
pickunicode(picks1, tl, tr, bl, br, tl2, tr2, bl2, br2);
|
||||
mixblock(picks2, tl, tr, bl, br, tl2, tr2, bl2, br2);
|
||||
p1 = windex(picks1, 96);
|
||||
p2 = windex(picks2, 32);
|
||||
return picks1[p1] <= picks2[p2] ? kPicksUnicode[p1] : kPicksMixBlock[p2];
|
||||
}
|
||||
|
||||
static struct Pick pickblock_unicode_true(struct TtyRgb tl, struct TtyRgb tr,
|
||||
struct TtyRgb bl, struct TtyRgb br) {
|
||||
unsigned i;
|
||||
uint16_t picks[96] aligned(32);
|
||||
memset(picks, 0x79, sizeof(picks));
|
||||
pickunicode(picks, tl, tr, bl, br, tl, tr, bl, br);
|
||||
i = windex(picks, 96);
|
||||
if (i >= 88) {
|
||||
unsigned j;
|
||||
fprintf(stderr, "uint16_t picks[96] = {");
|
||||
for (j = 0; j < 96; ++j) {
|
||||
fprintf(stderr, "%3d,", picks[j]);
|
||||
}
|
||||
fprintf(stderr, "}\n");
|
||||
}
|
||||
CHECK_LT(i, 88);
|
||||
return kPicksUnicode[i];
|
||||
}
|
||||
|
||||
static struct Pick pickblock_cp437_ansi(struct TtyRgb tl, struct TtyRgb tr,
|
||||
struct TtyRgb bl, struct TtyRgb br) {
|
||||
struct TtyRgb tl2 = getquant(tl);
|
||||
struct TtyRgb tr2 = getquant(tr);
|
||||
struct TtyRgb bl2 = getquant(bl);
|
||||
struct TtyRgb br2 = getquant(br);
|
||||
unsigned i, p1, p2;
|
||||
uint16_t picks1[32] aligned(32);
|
||||
uint16_t picks2[32] aligned(32);
|
||||
memset(picks1, 0x79, sizeof(picks1));
|
||||
memset(picks2, 0x79, sizeof(picks2));
|
||||
pickcp437(picks1, tl, tr, bl, br, tl2, tr2, bl2, br2);
|
||||
mixblock(picks2, tl, tr, bl, br, tl2, tr2, bl2, br2);
|
||||
p1 = windex(picks1, 32);
|
||||
p2 = windex(picks2, 32);
|
||||
return picks1[p1] <= picks2[p2] ? kPicksCp437[p1] : kPicksMixBlock[p2];
|
||||
}
|
||||
|
||||
static struct Pick pickblock_cp437_true(struct TtyRgb tl, struct TtyRgb tr,
|
||||
struct TtyRgb bl, struct TtyRgb br) {
|
||||
unsigned i;
|
||||
uint16_t picks[32] aligned(32);
|
||||
memset(picks, 0x79, sizeof(picks));
|
||||
pickcp437(picks, tl, tr, bl, br, tl, tr, bl, br);
|
||||
return kPicksCp437[windex(picks, 32)];
|
||||
}
|
||||
|
||||
static char *copyglyph(char *v, struct Glyph glyph) {
|
||||
memcpy(v, &glyph, 4);
|
||||
return v + glyph.len;
|
||||
}
|
||||
|
||||
static char *copyblock(char *v, const struct TtyRgb chunk[hasatleast 4],
|
||||
struct Pick pick, struct TtyRgb *bg, struct TtyRgb *fg,
|
||||
struct Glyph *glyph) {
|
||||
unsigned i;
|
||||
CHECK_LT(pick.bg, 4);
|
||||
if (pick.fg != 0xff) CHECK_LT(pick.fg, 4);
|
||||
i = 0;
|
||||
if (pick.fg == 0xff) {
|
||||
if (!ttyeq(*bg, chunk[pick.bg])) {
|
||||
if (ttyeq(*fg, chunk[pick.bg])) {
|
||||
if (memcmp(glyph, &kGlyphs[1][0], sizeof(*glyph)) == 0) {
|
||||
v = setbg(v, (*bg = *fg));
|
||||
} else {
|
||||
i = 1;
|
||||
}
|
||||
} else {
|
||||
v = setbg(v, (*bg = chunk[pick.bg]));
|
||||
}
|
||||
}
|
||||
} else if (ttyeq(chunk[pick.bg], chunk[pick.fg])) {
|
||||
pick.k = 0;
|
||||
if (!ttyeq(*bg, chunk[pick.bg])) {
|
||||
if (ttyeq(*fg, chunk[pick.bg])) {
|
||||
if (memcmp(glyph, &kGlyphs[1][0], sizeof(*glyph)) == 0) {
|
||||
v = setbg(v, (*bg = *fg));
|
||||
} else {
|
||||
i = 1;
|
||||
}
|
||||
} else {
|
||||
v = setbg(v, (*bg = chunk[pick.bg]));
|
||||
}
|
||||
}
|
||||
} else if (!ttyeq(*fg, chunk[pick.fg])) {
|
||||
if (!ttyeq(*bg, chunk[pick.bg])) {
|
||||
if (ttyeq(*fg, chunk[pick.bg]) && ttyeq(*bg, chunk[pick.fg])) {
|
||||
if (pick.k == 0 && memcmp(glyph, &kGlyphs[1][0], sizeof(*glyph)) == 0) {
|
||||
v = setbg(v, (*bg = *fg));
|
||||
} else {
|
||||
i = 1;
|
||||
}
|
||||
} else {
|
||||
v = setbgfg(v, (*bg = chunk[pick.bg]), (*fg = chunk[pick.fg]));
|
||||
}
|
||||
} else {
|
||||
v = setfg(v, (*fg = chunk[pick.fg]));
|
||||
}
|
||||
} else if (!ttyeq(*bg, chunk[pick.bg])) {
|
||||
v = setbg(v, (*bg = chunk[pick.bg]));
|
||||
}
|
||||
return copyglyph(v, (*glyph = kGlyphs[i][pick.k]));
|
||||
}
|
||||
|
||||
static bool chunkeq(struct TtyRgb c[hasatleast 4],
|
||||
struct TtyRgb c2[hasatleast 4]) {
|
||||
return ttyeq(c[TL], c[TR]) && ttyeq(c[BL], c[BR]) && ttyeq(c2[TL], c2[TR]) &&
|
||||
ttyeq(c2[BL], c2[BR]);
|
||||
}
|
||||
|
||||
static struct TtyRgb *copychunk(struct TtyRgb chunk[hasatleast 4],
|
||||
const struct TtyRgb *c, size_t n) {
|
||||
chunk[TL] = c[0 + 0];
|
||||
chunk[TR] = c[0 + 1];
|
||||
chunk[BL] = c[n + 0];
|
||||
chunk[BR] = c[n + 1];
|
||||
return chunk;
|
||||
}
|
||||
|
||||
static noinline char *copyrun(char *v, size_t n,
|
||||
struct TtyRgb lastchunk[hasatleast 4],
|
||||
const struct TtyRgb **c, size_t *x,
|
||||
struct TtyRgb *bg, struct TtyRgb *fg,
|
||||
struct Glyph *glyph) {
|
||||
struct TtyRgb chunk[4];
|
||||
if (memcmp(glyph, &kGlyphs[1][0], sizeof(*glyph)) == 0) {
|
||||
if (!ttyeq(*bg, *fg)) {
|
||||
v = setbg(v, (*bg = *fg));
|
||||
}
|
||||
*glyph = kGlyphs[0][0];
|
||||
}
|
||||
do {
|
||||
v = copyglyph(v, *glyph);
|
||||
*x += 2;
|
||||
*c += 2;
|
||||
if (*x >= n) break;
|
||||
copychunk(chunk, *c, n);
|
||||
} while (chunkeq(chunk, lastchunk));
|
||||
*x -= 2;
|
||||
*c -= 2;
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps 2×2 pixel chunks onto ANSI UNICODE cells.
|
||||
* @note h/t Nick Black for his quadrant blitting work on notcurses
|
||||
*/
|
||||
char *ttyraster(char *v, const struct TtyRgb *c, size_t yn, size_t n,
|
||||
struct TtyRgb bg, struct TtyRgb fg) {
|
||||
unsigned y, x;
|
||||
struct Pick p;
|
||||
struct Glyph glyph;
|
||||
struct TtyRgb chun[4], lastchunk[4];
|
||||
for (y = 0; y < yn; y += 2, c += n) {
|
||||
if (y) *v++ = '\r', *v++ = '\n';
|
||||
for (x = 0; x < n; x += 2, c += 2) {
|
||||
copychunk(chun, c, n);
|
||||
if (ttyquant()->alg == kTtyQuantTrue) {
|
||||
if (ttyquant()->blocks == kTtyBlocksCp437) {
|
||||
p = pickblock_cp437_true(chun[TL], chun[TR], chun[BL], chun[BR]);
|
||||
} else {
|
||||
p = pickblock_unicode_true(chun[TL], chun[TR], chun[BL], chun[BR]);
|
||||
}
|
||||
} else {
|
||||
if (ttyquant()->blocks == kTtyBlocksCp437) {
|
||||
p = pickblock_cp437_ansi(chun[TL], chun[TR], chun[BL], chun[BR]);
|
||||
} else {
|
||||
p = pickblock_unicode_ansi(chun[TL], chun[TR], chun[BL], chun[BR]);
|
||||
}
|
||||
}
|
||||
v = copyblock(v, chun, p, &bg, &fg, &glyph);
|
||||
memcpy(lastchunk, chun, sizeof(chun));
|
||||
}
|
||||
}
|
||||
*v = '\0';
|
||||
return v;
|
||||
}
|
155
dsp/tty/ttyraw.c
Normal file
155
dsp/tty/ttyraw.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sigbits.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/calls/typedef/sigaction_f.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/rbx.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
#define FD STDOUT_FILENO
|
||||
|
||||
static struct TtyRaw {
|
||||
bool setup;
|
||||
bool noreentry;
|
||||
bool initialized;
|
||||
enum TtyRawFlags flags;
|
||||
sigaction_f next[10];
|
||||
unsigned char sigs[10];
|
||||
struct termios old;
|
||||
} g_ttyraw;
|
||||
|
||||
static textstartup int ttyraw_setup(void) {
|
||||
if (isatty(FD) &&
|
||||
ttyconfig(FD, ttysetrawmode, g_ttyraw.flags, &g_ttyraw.old) != -1) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static textstartup int ttyraw_enable(void) {
|
||||
int rc;
|
||||
g_ttyraw.setup = (rc = ttyraw_setup()) != -1 || g_ttyraw.setup;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static textstartup void ttyraw_hidecursor(void) {
|
||||
if (!g_ttyraw.setup) return;
|
||||
if (g_ttyraw.flags & kTtyCursor) return;
|
||||
ttyhidecursor(FD);
|
||||
}
|
||||
|
||||
static textexit int ttyraw_disable(void) {
|
||||
if (!g_ttyraw.setup) return 0;
|
||||
ttyshowcursor(FD);
|
||||
return ttyrestore(FD, &g_ttyraw.old);
|
||||
}
|
||||
|
||||
static textexit void ttyraw_onexit(void) {
|
||||
ttyraw_disable();
|
||||
}
|
||||
|
||||
static relegated void ttyraw_onsig(int sig, struct siginfo *info,
|
||||
struct ucontext *ctx) {
|
||||
size_t i;
|
||||
if (g_ttyraw.noreentry) _Exit(128 + sig);
|
||||
g_ttyraw.noreentry = true;
|
||||
if (g_ttyraw.flags != -1) {
|
||||
if (sig == SIGCONT) {
|
||||
ttyraw_enable();
|
||||
} else {
|
||||
ttyraw_disable();
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAYLEN(g_ttyraw.sigs); ++i) {
|
||||
if (g_ttyraw.sigs[i] == sig) {
|
||||
if (g_ttyraw.next[i] != SIG_IGN) {
|
||||
if (g_ttyraw.next[i] != SIG_DFL) {
|
||||
g_ttyraw.next[i](sig, info, ctx);
|
||||
} else if (sig != SIGCONT) {
|
||||
_Exit(128 + sig);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_ttyraw.noreentry = false;
|
||||
}
|
||||
|
||||
static textstartup void ttyraw_initsig(int sig, unsigned flags, unsigned mask) {
|
||||
static unsigned i;
|
||||
struct sigaction old;
|
||||
g_ttyraw.next[i] = xsigaction(sig, ttyraw_onsig, flags, mask, &old) != -1
|
||||
? old.sa_sigaction
|
||||
: SIG_DFL;
|
||||
g_ttyraw.sigs[i++] = sig;
|
||||
}
|
||||
|
||||
static textstartup void ttyraw_init(void) {
|
||||
unsigned crashmask = ~(SIGILL | SIGBUS | SIGSEGV | SIGABRT);
|
||||
ttyraw_initsig(SIGILL, SA_SIGINFO | SA_NODEFER | SA_ONSTACK, crashmask);
|
||||
ttyraw_initsig(SIGSEGV, SA_SIGINFO | SA_NODEFER | SA_ONSTACK, crashmask);
|
||||
ttyraw_initsig(SIGBUS, SA_SIGINFO | SA_NODEFER | SA_ONSTACK, crashmask);
|
||||
ttyraw_initsig(SIGABRT, SA_SIGINFO | SA_NODEFER, crashmask);
|
||||
ttyraw_initsig(SIGFPE, SA_SIGINFO | SA_RESTART, crashmask);
|
||||
ttyraw_initsig(SIGTRAP, SA_SIGINFO | SA_RESTART, crashmask);
|
||||
ttyraw_initsig(SIGHUP, SA_SIGINFO | SA_RESTART, crashmask);
|
||||
ttyraw_initsig(SIGINT, SA_SIGINFO | SA_RESTART, crashmask);
|
||||
ttyraw_initsig(SIGQUIT, SA_SIGINFO | SA_RESTART, crashmask);
|
||||
ttyraw_initsig(SIGCONT, SA_SIGINFO | SA_RESTART, crashmask);
|
||||
atexit(ttyraw_onexit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets raw mode, safely, the easy way.
|
||||
*
|
||||
* This should be called after your signal handlers have been installed.
|
||||
*/
|
||||
textstartup int ttyraw(enum TtyRawFlags flags) {
|
||||
int rc;
|
||||
if ((g_ttyraw.flags = flags) != -1) {
|
||||
if (!g_ttyraw.initialized) {
|
||||
g_ttyraw.initialized = true;
|
||||
ttyraw_init();
|
||||
}
|
||||
if ((rc = ttyraw_enable()) != -1) {
|
||||
ttyraw_hidecursor();
|
||||
}
|
||||
} else {
|
||||
rc = ttyraw_disable();
|
||||
}
|
||||
cancolor();
|
||||
return rc;
|
||||
}
|
12
dsp/tty/ttyrgb.h
Normal file
12
dsp/tty/ttyrgb.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef COSMOPOLITAN_DSP_TTY_RGB_H_
|
||||
#define COSMOPOLITAN_DSP_TTY_RGB_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct TtyRgb {
|
||||
uint8_t r, g, b, xt;
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_TTY_RGB_H_ */
|
72
dsp/tty/windex-avx2.S
Normal file
72
dsp/tty/windex-avx2.S
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Returns index of minimum uint16 in array.
|
||||
/
|
||||
/ @param rdi points to nonempty array
|
||||
/ @param rsi is item count divisible by 16
|
||||
/ @note needs avx2 (haswell+)
|
||||
windex$avx2:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
and $-32,%rsp
|
||||
sub $32,%rsp
|
||||
vmovdqa (%rdi),%ymm1
|
||||
vmovdqa .Lidx(%rip),%ymm3
|
||||
vmovdqa .Linc(%rip),%ymm5
|
||||
cmp $16,%esi
|
||||
jbe 2f
|
||||
vmovdqa %ymm3,%ymm0
|
||||
mov $16,%eax
|
||||
3: vpaddw %ymm0,%ymm5,%ymm0
|
||||
mov %eax,%edx
|
||||
vmovdqa (%rdi,%rdx,2),%ymm2
|
||||
vpcmpgtw %ymm2,%ymm1,%ymm4
|
||||
vpblendvb %ymm4,%ymm0,%ymm3,%ymm3
|
||||
vpminsw %ymm1,%ymm2,%ymm1
|
||||
add $16,%eax
|
||||
cmp %eax,%esi
|
||||
ja 3b
|
||||
2: vphminposuw %xmm1,%xmm0
|
||||
vextracti128 $0x1,%ymm1,%xmm1
|
||||
vphminposuw %xmm1,%xmm1
|
||||
vmovdqa %ymm3,(%rsp)
|
||||
vmovq %xmm0,%rdx
|
||||
vmovq %xmm1,%rax
|
||||
cmp %dx,%ax
|
||||
jbe 4f
|
||||
sar $16,%rdx
|
||||
movzwl %dx,%edx
|
||||
movzwl (%rsp,%rdx,2),%eax
|
||||
jmp 5f
|
||||
4: sar $16,%rax
|
||||
movzwl %ax,%eax
|
||||
movzwl 16(%rsp,%rax,2),%eax
|
||||
5: vzeroupper
|
||||
leave
|
||||
ret
|
||||
.endfn windex$avx2,globl
|
||||
|
||||
.rodata.cst32
|
||||
.Lidx: .short 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
.Linc: .value 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16
|
34
dsp/tty/windex-k8.c
Normal file
34
dsp/tty/windex-k8.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/assert.h"
|
||||
|
||||
unsigned windex$k8(short *a, size_t n) {
|
||||
unsigned short min, res, i;
|
||||
res = 0;
|
||||
min = a[0];
|
||||
for (i = 1; i < n; ++i) {
|
||||
if (a[i] < min) {
|
||||
min = a[i];
|
||||
res = i;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
62
dsp/tty/windex-sse4.S
Normal file
62
dsp/tty/windex-sse4.S
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Returns index of minimum positive int16 in array.
|
||||
/
|
||||
/ @param rdi points to nonempty array
|
||||
/ @param esi is 16-byte aligned 8+ / 8 multiple array item count
|
||||
/ @note needs sse4 (nehalem+)
|
||||
windex$sse4:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
mov $8,%eax
|
||||
sub $32,%rsp
|
||||
movdqa (%rdi),%xmm2
|
||||
movdqa .Lidx(%rip),%xmm1
|
||||
movdqa .Linc(%rip),%xmm6
|
||||
movdqa %xmm1,%xmm3
|
||||
0: cmp %eax,%esi
|
||||
je 1f
|
||||
add $8,%eax
|
||||
movdqa -16(%rdi,%rax,2),%xmm4
|
||||
movdqa %xmm2,%xmm7
|
||||
movdqa %xmm3,%xmm5
|
||||
paddw %xmm6,%xmm5
|
||||
movdqa %xmm5,%xmm3
|
||||
pcmpgtw %xmm4,%xmm7
|
||||
pminsw %xmm4,%xmm2
|
||||
movdqa %xmm7,%xmm0
|
||||
pblendvb %xmm0,%xmm5,%xmm1
|
||||
jmp 0b
|
||||
1: phminposuw %xmm2,%xmm0
|
||||
movd %xmm0,%eax
|
||||
movdqa %xmm1,-32(%rbp)
|
||||
shr $16,%eax
|
||||
movzwl -32(%rbp,%rax,2),%eax
|
||||
leave
|
||||
ret
|
||||
.endfn windex$sse4,globl
|
||||
|
||||
.rodata.cst16
|
||||
.Lidx: .short 0,1,2,3,4,5,6,7
|
||||
.Linc: .value 8,8,8,8,8,8,8,8
|
43
dsp/tty/windex.S
Normal file
43
dsp/tty/windex.S
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Dispatches to fastest windex() implementation.
|
||||
.initbss 300,_init_windex
|
||||
windex: .quad 0
|
||||
.endobj windex,globl
|
||||
.previous
|
||||
|
||||
.init.start 300,_init_windex
|
||||
ezlea windex$avx2,ax
|
||||
#if !X86_NEED(AVX2)
|
||||
ezlea windex$sse4,dx
|
||||
testb X86_HAVE(AVX2)+kCpuids(%rip)
|
||||
cmovz %rdx,%rax
|
||||
#endif /* AVX */
|
||||
#if !X86_NEED(SSE4_2)
|
||||
ezlea windex$k8,dx
|
||||
testb X86_HAVE(SSE4_2)+kCpuids(%rip)
|
||||
cmovz %rdx,%rax
|
||||
#endif /* SSE4 */
|
||||
stosq
|
||||
.init.end 300,_init_windex
|
10
dsp/tty/windex.h
Normal file
10
dsp/tty/windex.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef COSMOPOLITAN_DSP_TTY_WINDEX_H_
|
||||
#define COSMOPOLITAN_DSP_TTY_WINDEX_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern unsigned (*const windex)(uint16_t *, size_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_DSP_TTY_WINDEX_H_ */
|
59
dsp/tty/write.c
Normal file
59
dsp/tty/write.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
* Sends data to teletypewriter the pain-free way.
|
||||
*
|
||||
* This function blocks forever until the full amount is transmitted,
|
||||
* regardless of whether or not the character device is in non-blocking
|
||||
* mode, regardless of whether or not it's interrupted by a signal. It
|
||||
* can still be escaped by longjmp'ing out of a signal handler.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int ttywrite(int fd, const void *data, size_t size) {
|
||||
char *p;
|
||||
ssize_t rc;
|
||||
size_t wrote, n;
|
||||
p = data;
|
||||
n = size;
|
||||
do {
|
||||
TryAgain:
|
||||
if ((rc = write(fd, p, n)) != -1) {
|
||||
wrote = rc;
|
||||
p += wrote;
|
||||
n -= wrote;
|
||||
} else if (errno == EINTR) {
|
||||
goto TryAgain;
|
||||
} else if (errno == EAGAIN) {
|
||||
poll((struct pollfd[]){{fd, POLLOUT}}, 1, -1);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} while (n);
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue