简体   繁体   English

如何使用termcap获取C程序中的光标位置,而不写字符?

[英]How to get the cursor position in a C program using termcap, without writing a character?

I would like to know how to get the cursor position (x, y) in my program, without writing anything on the screen neither tracking it all the time.我想知道如何在我的程序中获取光标位置 (x, y),而不在屏幕上写任何东西,也不会一直跟踪它。

I found out a way to get its position with this function (I don't check the return of read, write, etc here to write a smaller code on this subject but I do it in my program):我找到了一种使用此函数获取其位置的方法(我在这里不检查读取、写入等的返回来编写有关此主题的较小代码,但我在我的程序中执行此操作):

void get_cursor_position(int *col, int *rows)
{
    int a = 0;
    int i = 0;
    char buf[4];

    write(1, "\033[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++;
    }
}

This function gives me the exact cursor position (*rows = y, *col = x), but it writes on the screen.这个函数给了我准确的光标位置(*rows = y,*col = x),但它写在屏幕上。

How can I get the cursor position without writing anything on the screen?如何在不在屏幕上写任何东西的情况下获得光标位置?
(If the cursor is on one of the printed characters, it will overwrite it.) (如果光标位于打印的字符之一上,它将覆盖它。)
Should echo be toggled before and after sending the escape sequence?应该在发送转义序列之前和之后切换回声吗?

This is a school project, so I only can use termcap, I can't use ncurses functions, the only allowed functions are tputs, tgoto, tgetstr, tgetnum, tgetflag.这是一个学校项目,所以我只能使用termcap,我不能使用ncurses函数,唯一允许的函数是tputs、tgoto、tgetstr、tgetnum、tgetflag。

There are several problems:有几个问题:

  • canonical mode is buffered (see below)规范模式被缓冲(见下文)

  • the read is done on the file-descriptor for standard output (that may happen to work — sometimes — but don't count on it) read是在标准输出的文件描述符上完成的(这可能会起作用——有时——但不要指望它)

  • the read does not read enough characters to get a typical response read未读取足够的字符以获得典型响应

  • the response would have two decimal integers, separated by semicolon ;响应将有两个十进制整数,用分号分隔;

  • the response would have a final character (which would become an issue if the read actually asked for enough characters...)响应将有一个最终字符(如果read实际上要求足够的字符,这将成为一个问题......)

Further reading:进一步阅读:

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.一行由换行符 ( NL )、文件结束符 ( EOF ) 或行结束符 ( EOL ) 分隔。 See Special Characters for more information on EOF and EOL .有关EOFEOL更多信息,请参阅特殊字符。 This means that a read request will not return until an entire line has been typed or a signal has been received.这意味着在输入整行或接收到信号之前, read请求不会返回。 Also, no matter how many bytes are requested in the read() call, at most one line will be returned.此外,无论在 read() 调用中请求多少字节,最多返回一行。 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.可以在 read() 中请求任意数量的字节,甚至是一个字节,而不会丢失信息。

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

That is, your program should be prepared to read Escape [ followed by two decimal integers (with no fixed limit on their length), and two other characters ;也就是说,您的程序应该准备好读取Escape [后跟两个十进制整数(其长度没有固定限制)和另外两个字符; and R .R

By the way, termcap by itself will do little for your solution.顺便说一下, termcap本身对您的解决方案几乎没有作用。 While ncurses has some relevant capabilities defined in the terminal database:虽然 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)

few programs use those, and in any case you would find it difficult to use the cursor position report in a termcap application.很少有程序使用它们,无论如何您会发现在 termcap 应用程序中使用光标位置报告是很困难的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM