From b395001fdea77defb457c7ac976623e0e0daeb25 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 11 Oct 2023 15:32:18 -0300 Subject: [PATCH] clib: Fix Linux cursor positioning --- clib/clib_term.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/clib/clib_term.c b/clib/clib_term.c index a85fafb..eeecb10 100644 --- a/clib/clib_term.c +++ b/clib/clib_term.c @@ -21,6 +21,7 @@ # include # ifdef __GNUC__ # include +# include # include # endif #endif @@ -90,36 +91,40 @@ term_get_size_y() int term_get_cursor_pos(uint8_t *x, uint8_t *y) { - char ch; + int rx, ry, n; + struct termios attrs; - fputs("\033[6n", stderr); - fflush(stderr); - if (getc(stdin) != 0x1b) + /* Capturing then uncapturing stdin like this is weird, but it'll have to do. */ + if (tcgetattr(STDOUT_FILENO, &attrs)) return 0; - if (getc(stdin) != '[') + int old_lflag = attrs.c_lflag; + attrs.c_lflag &= ~(ECHO | ICANON); + if (tcsetattr(STDOUT_FILENO, TCSANOW, &attrs)) return 0; - *x = *y = 0; - while (1) { - ch = getc(stdin); - if ((ch < '0') || (ch > '9')) - break; - *x = (*x * 10) + (ch - '0'); - } - while (1) { - ch = getc(stdin); - if ((ch < '0') || (ch > '9')) - break; - *y = (*y * 10) + (ch - '0'); + + /* Send CPR request. */ + fputs("\033[6n", stderr); + fflush(stderr); + + /* Read CPR response. */ + n = scanf("\033[%d;%dR", &ry, &rx); + if (n >= 2) { + *x = rx - 1; + *y = ry - 1; } - *x -= 1; - *y -= 1; - return 1; + + /* Uncapture stdin. */ + attrs.c_lflag = old_lflag; + tcsetattr(STDOUT_FILENO, TCSANOW, &attrs); + + return n >= 2; } int term_set_cursor_pos(uint8_t x, uint8_t y) { - fprintf(stderr, "\033[%d;%dH", x + 1, y + 1); + fprintf(stdout, "\033[%d;%dH", y + 1, x + 1); + fflush(stdout); return 1; } #else