cosmopolitan/examples/ttyinfo.c

109 lines
3.4 KiB
C
Raw Normal View History

2020-06-15 14:18:57 +00:00
#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/tty.h"
#include "libc/calls/calls.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/termios.h"
#include "libc/errno.h"
#include "libc/fmt/fmt.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/exit.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/termios.h"
#include "libc/x/x.h"
/*
"\e[c" "\e[?1;2c"
"\e[x" "\e[2;1;1;112;112;1;0x"
"\e[>c" "\e[>83;40500;0c"
"\e[6n" "\e[52;1R"
*/
#define CTRL(C) ((C) ^ 0b01000000)
#define PROBE_VT100 "\e[c" /* e.g. "\e[?1;2c", "\e[>0c" */
#define PROBE_SECONDARY "\e[>c" /* "\e[>83;40500;0c" (Screen v4.05.00) */
#define PROBE_PARAMETERS "\e[x" /* e.g. "\e[2;1;1;112;112;1;0x" */
#define PROBE_CURSOR_POSITION "\e[6n" /* e.g. "\e[𝑦;𝑥R" */
#define PROBE_SUN_DTTERM_SIZE "\e[14t" /* e.g. "\e[𝑦;𝑥R" */
int fd_;
jmp_buf jb_;
ssize_t got_;
uint8_t buf_[128];
struct TtyIdent ti_;
struct winsize wsize_;
volatile bool resized_;
void OnResize(void) {
resized_ = true;
}
void OnKilled(int sig) {
longjmp(jb_, 128 + sig + 1);
}
void getsome(void) {
if ((got_ = read(fd_, buf_, sizeof(buf_))) == -1 && errno != EINTR) {
printf("%s%s\r\n", "error: ", strerror(errno));
longjmp(jb_, EXIT_FAILURE + 1);
}
if (got_ >= 0) {
printf("%`'.*s\r\n", got_, buf_);
if (got_ > 0 && buf_[0] == CTRL('C')) {
longjmp(jb_, EXIT_SUCCESS + 1);
}
}
if (resized_) {
CHECK_NE(-1, getttysize(fd_, &wsize_));
printf("SIGWINCH → %hu×%hu\r\n", wsize_.ws_row, wsize_.ws_col);
resized_ = false;
}
}
void probe(const char *s) {
printf("%`'s → ", s);
write(fd_, s, strlen(s));
getsome();
}
int main(int argc, char *argv[]) {
int rc;
char ttyname[64];
struct termios old;
CHECK_NE(-1, (fd_ = open("/dev/tty", O_RDWR)));
CHECK_NE(-1, ttyconfig(fd_, ttysetrawmode, 0, &old));
if (!(rc = setjmp(jb_))) {
xsigaction(SIGTERM, OnKilled, 0, 0, NULL);
xsigaction(SIGWINCH, OnResize, 0, 0, NULL);
if (ttyident(&ti_, STDIN_FILENO, STDOUT_FILENO) != -1) {
ttysendtitle(fd_, "justine was here", &ti_);
fputs(ttydescribe(ttyname, sizeof(ttyname), &ti_), stdout);
}
fputs("\r\n", stdout);
probe(PROBE_VT100);
probe(PROBE_SECONDARY);
probe(PROBE_PARAMETERS);
probe(PROBE_CURSOR_POSITION);
/* probe(PROBE_SUN_DTTERM_SIZE); */
getsome();
for (;;) getsome();
}
ttyrestore(fd_, &old);
ttyidentclear(&ti_);
return rc - 1;
}