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_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_KEY_EOF = 0xFFFFFFFF,
@@ -153,6 +158,7 @@ FX_API void fx_tty_set_vmode(
struct fx_tty *tty,
const struct fx_tty_vmode *vmode);
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(
struct fx_tty *tty,
+89 -8
View File
@@ -2,6 +2,7 @@
#include "../../tty.h"
#include <ctype.h>
#include <fx/term/tty.h>
#include <stdio.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);
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_oflag &= ~(OPOST);
@@ -207,8 +209,14 @@ void fx_tty_reset_vmode(struct fx_tty *tty)
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(
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) {
return -1;
@@ -245,7 +253,9 @@ static int compare_colour(
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) {
return -1;
@@ -273,7 +283,9 @@ static void put_ansi_attrib(struct fx_tty *tty, const char *s)
}
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) {
return;
@@ -311,7 +323,8 @@ static void set_attrib(
}
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)
{
if (compare_colour(old, new) == 0) {
@@ -347,7 +360,8 @@ static void set_fg(
}
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)
{
if (compare_colour(old, new) == 0) {
@@ -460,7 +474,10 @@ fx_keycode fx_tty_read_key(struct fx_tty *tty)
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) {
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) {
/* 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(
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)) {
return -1;
@@ -552,3 +574,62 @@ enum fx_status fx_tty_get_dimensions(
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;
}