2024-11-14 23:11:55 +00:00
|
|
|
#include "../../print.h"
|
|
|
|
|
|
2024-10-24 21:31:22 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <sys/ioctl.h>
|
2024-10-27 15:36:14 +00:00
|
|
|
#include <termios.h>
|
|
|
|
|
#include <unistd.h>
|
2024-10-24 21:31:22 +01:00
|
|
|
|
2024-10-27 15:36:14 +00:00
|
|
|
int z__b_stream_is_tty(FILE *fp)
|
2024-10-24 21:31:22 +01:00
|
|
|
{
|
|
|
|
|
return isatty(fileno(fp));
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-27 15:36:14 +00:00
|
|
|
int z__b_stream_dimensions(FILE *fp, unsigned int *w, unsigned int *h)
|
2024-10-24 21:31:22 +01:00
|
|
|
{
|
|
|
|
|
if (!isatty(fileno(fp))) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct winsize ws;
|
|
|
|
|
if (ioctl(fileno(fp), TIOCGWINSZ, &ws) == -1) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (w) {
|
|
|
|
|
*w = ws.ws_col;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (h) {
|
|
|
|
|
*h = ws.ws_row;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-27 15:36:14 +00:00
|
|
|
int z__b_stream_cursorpos(FILE *in, FILE *out, unsigned int *x, unsigned int *y)
|
2024-10-24 21:31:22 +01:00
|
|
|
{
|
|
|
|
|
if (!isatty(fileno(in)) || !isatty(fileno(out))) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct termios term, restore;
|
|
|
|
|
|
|
|
|
|
tcgetattr(fileno(in), &term);
|
|
|
|
|
tcgetattr(fileno(in), &restore);
|
2024-10-27 15:36:14 +00:00
|
|
|
term.c_lflag &= ~(ICANON | ECHO);
|
2024-10-24 21:31:22 +01:00
|
|
|
tcsetattr(fileno(in), TCSANOW, &term);
|
|
|
|
|
|
|
|
|
|
const char *cmd = "\033[6n";
|
|
|
|
|
write(fileno(out), cmd, strlen(cmd));
|
|
|
|
|
|
|
|
|
|
char buf[64];
|
|
|
|
|
read(fileno(in), buf, sizeof buf);
|
|
|
|
|
|
|
|
|
|
tcsetattr(fileno(in), TCSANOW, &restore);
|
|
|
|
|
|
|
|
|
|
unsigned int row, col;
|
|
|
|
|
int r = sscanf(buf, "\033[%u;%uR", &row, &col);
|
|
|
|
|
if (r != 2) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*x = col - 1;
|
|
|
|
|
*y = row - 1;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2024-11-14 23:11:55 +00:00
|
|
|
|
|
|
|
|
int z__b_stream_set_modifier(FILE *fp, enum z__b_stream_modifier mod)
|
|
|
|
|
{
|
|
|
|
|
char buf[128];
|
|
|
|
|
int buf_i = 0;
|
|
|
|
|
int nr_codes = 0;
|
|
|
|
|
|
|
|
|
|
buf[buf_i++] = '\033';
|
|
|
|
|
buf[buf_i++] = '[';
|
|
|
|
|
|
|
|
|
|
if (mod & Z__B_STREAM_MOD_RESET) {
|
|
|
|
|
buf[buf_i++] = '0';
|
|
|
|
|
buf[buf_i++] = 'm';
|
|
|
|
|
buf[buf_i++] = '\0';
|
|
|
|
|
fputs(buf, fp);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mod & Z__B_STREAM_MOD_BOLD) {
|
|
|
|
|
if (nr_codes > 0) {
|
|
|
|
|
buf[buf_i++] = ';';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf[buf_i++] = '1';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mod & Z__B_STREAM_MOD_ITALIC) {
|
|
|
|
|
if (nr_codes > 0) {
|
|
|
|
|
buf[buf_i++] = ';';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf[buf_i++] = '3';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mod & Z__B_STREAM_MOD_ULINE) {
|
|
|
|
|
if (nr_codes > 0) {
|
|
|
|
|
buf[buf_i++] = ';';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf[buf_i++] = '4';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mod & Z__B_STREAM_MOD_INVERT) {
|
|
|
|
|
if (nr_codes > 0) {
|
|
|
|
|
buf[buf_i++] = ';';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf[buf_i++] = '7';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Z__B_STREAM_MOD_GET_FG_COLOUR(mod) != 0) {
|
|
|
|
|
if (nr_codes > 0) {
|
|
|
|
|
buf[buf_i++] = ';';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf[buf_i++] = mod & Z__B_STREAM_MOD_BRIGHT ? '9' : '3';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (Z__B_STREAM_MOD_GET_FG_COLOUR(mod)) {
|
|
|
|
|
case Z__B_STREAM_MOD_BLACK:
|
|
|
|
|
buf[buf_i++] = '0';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_RED:
|
|
|
|
|
buf[buf_i++] = '1';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_GREEN:
|
|
|
|
|
buf[buf_i++] = '2';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_BLUE:
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_RED | Z__B_STREAM_MOD_GREEN:
|
|
|
|
|
buf[buf_i++] = '3';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_RED | Z__B_STREAM_MOD_BLUE:
|
|
|
|
|
buf[buf_i++] = '5';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_GREEN | Z__B_STREAM_MOD_BLUE:
|
|
|
|
|
buf[buf_i++] = '6';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_RED | Z__B_STREAM_MOD_GREEN | Z__B_STREAM_MOD_BLUE:
|
|
|
|
|
buf[buf_i++] = '7';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Z__B_STREAM_MOD_GET_BG_COLOUR(mod) != 0) {
|
|
|
|
|
if (nr_codes > 0) {
|
|
|
|
|
buf[buf_i++] = ';';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mod & Z__B_STREAM_MOD_BG_BRIGHT) {
|
|
|
|
|
buf[buf_i++] = '1';
|
|
|
|
|
buf[buf_i++] = '0';
|
|
|
|
|
} else {
|
|
|
|
|
buf[buf_i++] = '9';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (Z__B_STREAM_MOD_GET_BG_COLOUR(mod)) {
|
|
|
|
|
case Z__B_STREAM_MOD_BG_BLACK:
|
|
|
|
|
buf[buf_i++] = '0';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_BG_RED:
|
|
|
|
|
buf[buf_i++] = '1';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_BG_GREEN:
|
|
|
|
|
buf[buf_i++] = '2';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_BG_BLUE:
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_BG_RED | Z__B_STREAM_MOD_BG_GREEN:
|
|
|
|
|
buf[buf_i++] = '3';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_BG_RED | Z__B_STREAM_MOD_BG_BLUE:
|
|
|
|
|
buf[buf_i++] = '5';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_BG_GREEN | Z__B_STREAM_MOD_BG_BLUE:
|
|
|
|
|
buf[buf_i++] = '6';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
case Z__B_STREAM_MOD_BG_RED | Z__B_STREAM_MOD_BG_GREEN
|
|
|
|
|
| Z__B_STREAM_MOD_BG_BLUE:
|
|
|
|
|
buf[buf_i++] = '7';
|
|
|
|
|
nr_codes++;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf[buf_i++] = 'm';
|
|
|
|
|
buf[buf_i++] = '\0';
|
|
|
|
|
fputs(buf, fp);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|