Как получить позицию курсора в программе на C, используя termcap, без написания символа?
Я хотел бы знать, как получить положение курсора (x, y) в моей программе, не записывая ничего на экране и не отслеживая его все время.
Я нашел способ получить свою позицию с помощью этой функции (я не проверяю возвращение read, write и т. Д. Здесь, чтобы написать меньший код на эту тему, но я делаю это в своей программе):
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++;
}
}
Эта функция дает мне точное положение курсора (*row = y, *col = x), но она пишет на экране.
Как я могу получить положение курсора, не записывая ничего на экране? (потому что, если курсор находится на одном из напечатанных символов, он будет перезаписан).
Это школьный проект, поэтому я могу использовать только termcap, я не могу использовать функции ncurses, разрешены только функции tputs, tgoto, tgetstr, tgetnum, tgetflag.
1 ответ
Есть несколько проблем:
канонический режим буферизован (см. ниже)
read
делается на дескриптор файла для стандартного вывода (это может случиться, иногда - но не рассчитывайте на это)read
не читает достаточно символов, чтобы получить типичный ответответ будет иметь два десятичных целых числа, разделенных точкой с запятой
;
ответ будет иметь окончательный характер (который станет проблемой, если
read
на самом деле просят достаточно символов...)
Дальнейшее чтение:
- Общий интерфейс терминала Спецификация Single UNIX ®, версия 2
В обработке ввода в каноническом режиме ввод терминала обрабатывается в единицах строк. Строка ограничена символом новой строки (
NL
), символ конца файла (EOF
) или конец строки (EOL
) персонаж. См. Специальные символы для получения дополнительной информации оEOF
а такжеEOL
, Это означает, чтоread
запрос не вернется, пока не будет введена вся строка или не будет получен сигнал. Кроме того, независимо от того, сколько байтов запрашивается в вызове read (), будет возвращено не более одной строки. Однако нет необходимости читать всю строку сразу; Любое количество байтов, даже один, может быть запрошено в read () без потери информации.
CSI Ps n Отчет о состоянии устройства (DSR). Ps = 5 -> Отчет о состоянии. Результат ("ОК") - CSI 0 n Ps = 6 -> Положение курсора отчета (CPR) [строка; столбец]. Результат - CSI r; с 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.