fx.term: tty: implement get_cursor_position() and flush()

This commit is contained in:
2026-06-20 15:28:51 +01:00
parent eb759982db
commit c41131eac8
2 changed files with 101 additions and 14 deletions
+6
View File
@@ -50,6 +50,11 @@ enum {
FX_KEY_BACKSPACE, FX_KEY_BACKSPACE,
FX_KEY_RETURN, FX_KEY_RETURN,
/* within this range, we further reserve a sub-range. applications can
* define their own special keycode values within this range */
FX_KEY_RESERVED_START = 0xFFF00,
FX_KEY_RESERVED_END = 0xFFFFD,
FX_MOD_CTRL = 0x10000000, FX_MOD_CTRL = 0x10000000,
FX_KEY_EOF = 0xFFFFFFFF, FX_KEY_EOF = 0xFFFFFFFF,
@@ -153,6 +158,7 @@ FX_API void fx_tty_set_vmode(
struct fx_tty *tty, struct fx_tty *tty,
const struct fx_tty_vmode *vmode); const struct fx_tty_vmode *vmode);
FX_API void fx_tty_reset_vmode(struct fx_tty *tty); FX_API void fx_tty_reset_vmode(struct fx_tty *tty);
FX_API void fx_tty_flush(struct fx_tty *tty);
FX_API enum fx_status fx_tty_get_dimensions( FX_API enum fx_status fx_tty_get_dimensions(
struct fx_tty *tty, struct fx_tty *tty,
+95 -14
View File
@@ -2,6 +2,7 @@
#include "../../tty.h" #include "../../tty.h"
#include <ctype.h>
#include <fx/term/tty.h> #include <fx/term/tty.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -103,6 +104,7 @@ static void init_tty(struct fx_tty *tty, FILE *in, FILE *out)
tcgetattr(fd, &tty->t_ios_default); tcgetattr(fd, &tty->t_ios_default);
memcpy(&tty->t_ios_raw, &tty->t_ios_default, sizeof tty->t_ios_raw); memcpy(&tty->t_ios_raw, &tty->t_ios_default, sizeof tty->t_ios_raw);
setvbuf(out, NULL, _IOLBF, 4096);
tty->t_ios_raw.c_iflag &= ~(ICRNL | IXON); tty->t_ios_raw.c_iflag &= ~(ICRNL | IXON);
tty->t_ios_raw.c_oflag &= ~(OPOST); tty->t_ios_raw.c_oflag &= ~(OPOST);
@@ -207,8 +209,14 @@ void fx_tty_reset_vmode(struct fx_tty *tty)
tty->t_vmode.v_attrib = FX_TTY_ATTRIB_NORMAL; tty->t_vmode.v_attrib = FX_TTY_ATTRIB_NORMAL;
} }
void fx_tty_flush(struct fx_tty *tty)
{
fflush(tty->t_out);
}
static int compare_colour( static int compare_colour(
const struct fx_tty_colour *a, const struct fx_tty_colour *b) const struct fx_tty_colour *a,
const struct fx_tty_colour *b)
{ {
if (a->c_mode != b->c_mode) { if (a->c_mode != b->c_mode) {
return -1; return -1;
@@ -245,7 +253,9 @@ static int compare_colour(
return 0; return 0;
} }
static int compare_vmode(const struct fx_tty_vmode *a, const struct fx_tty_vmode *b) static int compare_vmode(
const struct fx_tty_vmode *a,
const struct fx_tty_vmode *b)
{ {
if (a->v_attrib != b->v_attrib) { if (a->v_attrib != b->v_attrib) {
return -1; return -1;
@@ -273,45 +283,48 @@ static void put_ansi_attrib(struct fx_tty *tty, const char *s)
} }
static void set_attrib( static void set_attrib(
struct fx_tty *tty, enum fx_tty_attrib old, enum fx_tty_attrib new) struct fx_tty *tty,
enum fx_tty_attrib old,
enum fx_tty_attrib new)
{ {
if (old == new) { if (old == new) {
return; return;
} }
/* Bold ON */ /* Bold ON */
if (!(old & FX_TTY_ATTRIB_BOLD) && new &FX_TTY_ATTRIB_BOLD) { if (!(old & FX_TTY_ATTRIB_BOLD) && new & FX_TTY_ATTRIB_BOLD) {
put_ansi_attrib(tty, ANSI_BOLD_ON); put_ansi_attrib(tty, ANSI_BOLD_ON);
} }
/* Bold OFF */ /* Bold OFF */
if (old & FX_TTY_ATTRIB_BOLD && !(new &FX_TTY_ATTRIB_BOLD)) { if (old & FX_TTY_ATTRIB_BOLD && !(new & FX_TTY_ATTRIB_BOLD)) {
put_ansi_attrib(tty, ANSI_BOLD_OFF); put_ansi_attrib(tty, ANSI_BOLD_OFF);
} }
/* Underline ON */ /* Underline ON */
if (!(old & FX_TTY_ATTRIB_UNDERLINE) && new &FX_TTY_ATTRIB_UNDERLINE) { if (!(old & FX_TTY_ATTRIB_UNDERLINE) && new & FX_TTY_ATTRIB_UNDERLINE) {
put_ansi_attrib(tty, ANSI_UNDERLINE_ON); put_ansi_attrib(tty, ANSI_UNDERLINE_ON);
} }
/* Underline OFF */ /* Underline OFF */
if (old & FX_TTY_ATTRIB_UNDERLINE && !(new &FX_TTY_ATTRIB_UNDERLINE)) { if (old & FX_TTY_ATTRIB_UNDERLINE && !(new & FX_TTY_ATTRIB_UNDERLINE)) {
put_ansi_attrib(tty, ANSI_UNDERLINE_OFF); put_ansi_attrib(tty, ANSI_UNDERLINE_OFF);
} }
/* Italic ON */ /* Italic ON */
if (!(old & FX_TTY_ATTRIB_ITALIC) && new &FX_TTY_ATTRIB_ITALIC) { if (!(old & FX_TTY_ATTRIB_ITALIC) && new & FX_TTY_ATTRIB_ITALIC) {
put_ansi_attrib(tty, ANSI_ITALIC_ON); put_ansi_attrib(tty, ANSI_ITALIC_ON);
} }
/* Italic OFF */ /* Italic OFF */
if (old & FX_TTY_ATTRIB_ITALIC && !(new &FX_TTY_ATTRIB_ITALIC)) { if (old & FX_TTY_ATTRIB_ITALIC && !(new & FX_TTY_ATTRIB_ITALIC)) {
put_ansi_attrib(tty, ANSI_ITALIC_OFF); put_ansi_attrib(tty, ANSI_ITALIC_OFF);
} }
} }
static void set_fg( static void set_fg(
struct fx_tty *tty, const struct fx_tty_colour *old, struct fx_tty *tty,
const struct fx_tty_colour *old,
const struct fx_tty_colour *new) const struct fx_tty_colour *new)
{ {
if (compare_colour(old, new) == 0) { if (compare_colour(old, new) == 0) {
@@ -347,7 +360,8 @@ static void set_fg(
} }
static void set_bg( static void set_bg(
struct fx_tty *tty, const struct fx_tty_colour *old, struct fx_tty *tty,
const struct fx_tty_colour *old,
const struct fx_tty_colour *new) const struct fx_tty_colour *new)
{ {
if (compare_colour(old, new) == 0) { if (compare_colour(old, new) == 0) {
@@ -460,7 +474,10 @@ fx_keycode fx_tty_read_key(struct fx_tty *tty)
return c; return c;
} }
void fx_tty_move_cursor_x(struct fx_tty *tty, enum fx_tty_position_base base, int pos) void fx_tty_move_cursor_x(
struct fx_tty *tty,
enum fx_tty_position_base base,
int pos)
{ {
if (base == FX_TTY_POS_CURSOR && pos < 0 && pos >= -4) { if (base == FX_TTY_POS_CURSOR && pos < 0 && pos >= -4) {
for (int i = 0; i > pos; i--) { for (int i = 0; i > pos; i--) {
@@ -489,7 +506,10 @@ void fx_tty_move_cursor_x(struct fx_tty *tty, enum fx_tty_position_base base, in
} }
} }
void fx_tty_move_cursor_y(struct fx_tty *tty, enum fx_tty_position_base base, int pos) void fx_tty_move_cursor_y(
struct fx_tty *tty,
enum fx_tty_position_base base,
int pos)
{ {
if (base == FX_TTY_POS_START) { if (base == FX_TTY_POS_START) {
/* we don't need this functionality right now */ /* we don't need this functionality right now */
@@ -530,7 +550,9 @@ void fx_tty_clear(struct fx_tty *tty, enum fx_tty_clear_mode mode)
} }
enum fx_status fx_tty_get_dimensions( enum fx_status fx_tty_get_dimensions(
struct fx_tty *tty, unsigned int *w, unsigned int *h) struct fx_tty *tty,
unsigned int *w,
unsigned int *h)
{ {
if (!(tty->t_flags & FX_TTY_INTERACTIVE)) { if (!(tty->t_flags & FX_TTY_INTERACTIVE)) {
return -1; return -1;
@@ -552,3 +574,62 @@ enum fx_status fx_tty_get_dimensions(
return 0; return 0;
} }
enum fx_status fx_tty_get_cursor_position(
struct fx_tty *tty,
unsigned int *w,
unsigned int *h)
{
if (!(tty->t_flags & FX_TTY_INTERACTIVE)) {
return -1;
}
int in_fd = fileno(tty->t_in);
int out_fd = fileno(tty->t_out);
write(out_fd, "\x1b[6n", 4);
char c;
read(in_fd, &c, 1);
read(in_fd, &c, 1);
char s[16] = {0};
for (int i = 0; i < sizeof s - 1; i++) {
read(in_fd, &c, 1);
if (!isdigit(c)) {
break;
}
s[i] = c;
s[i + 1] = 0;
}
if (w) {
if (s[0]) {
*w = atoi(s);
} else {
*w = 0;
}
}
s[0] = 0;
for (int i = 0; i < sizeof s - 1; i++) {
read(in_fd, &c, 1);
if (!isdigit(c)) {
break;
}
s[i] = c;
s[i + 1] = 0;
}
if (h) {
if (s[0]) {
*h = atoi(s);
} else {
*h = 0;
}
}
return 0;
}