如何在不写字符的情况下使用 termcap 获取 C 程序中的光标位置?
How to get the cursor position in a C program using termcap, without writing a character?
我想知道如何在我的程序中获取光标位置 (x, y),而不用在屏幕上写任何东西,也不会一直跟踪它。
我找到了一种使用此函数获取其位置的方法(我不检查 return 的读、写等,以编写有关此主题的较小代码,但我在我的程序):
void get_cursor_position(int *col, int *rows)
{
int a = 0;
int i = 0;
char buf[4];
write(1, "3[6n", 4); // string asking for the cursor position
read(1, buf, 4);
while (buf[i])
{
if (buf[i] >= 48 && buf[i] <= 57)
{
if (a == 0)
*rows = atoi(&buf[i]) - 1;
else
*col = atoi(&buf[i]) - 1;
a++;
}
i++;
}
}
这个函数给我准确的光标位置(*rows = y,*col = x),但它写在屏幕上。
如何在不在屏幕上写任何东西的情况下获取光标位置?
(如果光标在其中一个打印字符上,它将覆盖它。)
是否应该在发送转义序列之前和之后切换 echo?
这是一个学校项目,所以我只能使用termcap,不能使用ncurses函数,唯一允许的函数是tputs、tgoto、tgetstr、tgetnum、tgetflag。
有几个问题:
规范模式是 缓冲的(见下文)
read
是在 标准输出 的文件描述符上完成的(这可能会起作用——有时——但不算在内就可以了)
read
未读取足够的字符以获得典型响应
响应将有两个十进制整数,用分号分隔 ;
响应将有一个最终字符(如果 read
实际上要求足够的字符,这将成为一个问题...)
延伸阅读:
- General Terminal Interface 单一 UNIX® 规范,版本 2
In canonical mode input processing, terminal input is processed in units of lines. A line is delimited by a newline character (NL
), an end-of-file character (EOF
), or an end-of-line (EOL
) character. See Special Characters for more information on EOF
and EOL
. This means that a read
request will not return until an entire line has been typed or a signal has been received. Also, no matter how many bytes are requested in the read() call, at most one line will be returned. It is not, however, necessary to read a whole line at once; any number of bytes, even one, may be requested in a read() without losing information.
CSI Ps n Device Status Report (DSR).
Ps = 5 -> Status Report.
Result ("OK") is CSI 0 n
Ps = 6 -> Report Cursor Position (CPR) [row;column].
Result is CSI r ; c R
也就是你的程序要准备读取Escape[
后跟两个十进制整数(对它们的长度没有固定限制),以及另外两个字符 ;
和 R
.
顺便说一下,termcap 本身对您的解决方案作用不大。虽然 ncurses 在终端数据库中定义了一些相关功能:
# u9 terminal enquire string (equiv. to ANSI/ECMA-48 DA)
# u8 terminal answerback description
# u7 cursor position request (equiv. to VT100/ANSI/ECMA-48 DSR 6)
# u6 cursor position report (equiv. to ANSI/ECMA-48 CPR)
很少有程序使用它们,而且在任何情况下您都会发现很难在 termcap 应用程序中使用光标位置报告。
我想知道如何在我的程序中获取光标位置 (x, y),而不用在屏幕上写任何东西,也不会一直跟踪它。
我找到了一种使用此函数获取其位置的方法(我不检查 return 的读、写等,以编写有关此主题的较小代码,但我在我的程序):
void get_cursor_position(int *col, int *rows)
{
int a = 0;
int i = 0;
char buf[4];
write(1, "3[6n", 4); // string asking for the cursor position
read(1, buf, 4);
while (buf[i])
{
if (buf[i] >= 48 && buf[i] <= 57)
{
if (a == 0)
*rows = atoi(&buf[i]) - 1;
else
*col = atoi(&buf[i]) - 1;
a++;
}
i++;
}
}
这个函数给我准确的光标位置(*rows = y,*col = x),但它写在屏幕上。
如何在不在屏幕上写任何东西的情况下获取光标位置?
(如果光标在其中一个打印字符上,它将覆盖它。)
是否应该在发送转义序列之前和之后切换 echo?
这是一个学校项目,所以我只能使用termcap,不能使用ncurses函数,唯一允许的函数是tputs、tgoto、tgetstr、tgetnum、tgetflag。
有几个问题:
规范模式是 缓冲的(见下文)
read
是在 标准输出 的文件描述符上完成的(这可能会起作用——有时——但不算在内就可以了)read
未读取足够的字符以获得典型响应响应将有两个十进制整数,用分号分隔
;
响应将有一个最终字符(如果
read
实际上要求足够的字符,这将成为一个问题...)
延伸阅读:
- General Terminal Interface 单一 UNIX® 规范,版本 2
In canonical mode input processing, terminal input is processed in units of lines. A line is delimited by a newline character (
NL
), an end-of-file character (EOF
), or an end-of-line (EOL
) character. See Special Characters for more information onEOF
andEOL
. This means that aread
request will not return until an entire line has been typed or a signal has been received. Also, no matter how many bytes are requested in the read() call, at most one line will be returned. It is not, however, necessary to read a whole line at once; any number of bytes, even one, may be requested in a read() without losing information.
CSI Ps n Device Status Report (DSR). Ps = 5 -> Status Report. Result ("OK") is CSI 0 n Ps = 6 -> Report Cursor Position (CPR) [row;column]. Result is CSI r ; c R
也就是你的程序要准备读取Escape[
后跟两个十进制整数(对它们的长度没有固定限制),以及另外两个字符 ;
和 R
.
顺便说一下,termcap 本身对您的解决方案作用不大。虽然 ncurses 在终端数据库中定义了一些相关功能:
# u9 terminal enquire string (equiv. to ANSI/ECMA-48 DA)
# u8 terminal answerback description
# u7 cursor position request (equiv. to VT100/ANSI/ECMA-48 DSR 6)
# u6 cursor position report (equiv. to ANSI/ECMA-48 CPR)
很少有程序使用它们,而且在任何情况下您都会发现很难在 termcap 应用程序中使用光标位置报告。