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

好久不见. 提交于 2019-12-30 23:59:12

问题


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.

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.

How can I get the cursor position without writting anything on the screen ? (because if the cursor is on one of the printed characters, it will overwrite it).

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.


回答1:


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)

  • the read does not read enough characters to get a typical response

  • 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...)

Further reading:

  • General Terminal Interface The Single UNIX ® Specification, Version 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.

  • XTerm Control Sequences
    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 ; and R.

By the way, termcap by itself will do little for your solution. While ncurses has some relevant capabilities defined in the terminal database:

#       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.



来源:https://stackoverflow.com/questions/44078725/how-to-get-the-cursor-position-in-a-c-program-using-termcap-without-writing-a-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!