cosmopolitan/examples/ttyinfo.c
2020-06-15 07:18:57 -07:00

108 lines
3.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}