我正在努力让ncurses生成KEY_HOME或KEY_END事件,而不是原始转义序列作为字符序列来传递。
以下简单的C程序说明了该问题:
#define _XOPEN_SOURCE 700
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
void clean(void)
{
echo();
nl();
nocbreak();
endwin();
}
int main(int argc, char *argv[])
{
setvbuf(stderr, NULL, _IONBF, 0);
initscr();
cbreak();
nonl();
noecho();
atexit(clean);
keypad(stdscr, TRUE);
clear();
refresh();
int ch = getch();
if (ch == ERR)
errx(EXIT_FAILURE, "getch");
warnx("read: %x", ch);
halfdelay(1);
while((ch = getch()) != ERR)
{
warnx("read: %x", ch);
}
exit(EXIT_SUCCESS);
}
使用-inccurses进行编译,然后将stderr重定向到日志文件。 按下HOME时:
test: read: 1b
test: read: 5b
test: read: 31
test: read: 7e
按UP
test: read: 103
为什么ncurses不能将HOME和END(甚至F1等)解析为KEY_HOME?
答案 0 :(得分:2)
您可能已将 TERM
设置为与终端的行为不匹配的值。例如, linux
终端描述具有khome=\E[1~
(与示例输出相对应),而 xterm
具有{{3 }}。您可以使用
infocmp linux xterm | grep khome
如果终端描述与实际行为不匹配,则ncurses将与传入的字节不匹配,并且行为将如下所示。
答案 1 :(得分:0)
我认为您不应在诅咒上下文中使用warnx
。
如果改用mvprintw
,问题似乎就消失了。
int main(int argc, char *argv[])
{
setvbuf(stderr, NULL, _IONBF, 0);
initscr();
cbreak();
nonl();
noecho();
int y = 1;
atexit(clean);
keypad(stdscr, TRUE);
clear();
refresh();
int ch = getch();
if (ch == ERR)
errx(EXIT_FAILURE, "getch");
mvprintw(y++, 1, "read: %x", ch);
halfdelay(1);
while((ch = getch()) != ERR)
{
mvprintw(y++, 1, "read: %x", ch);
}
/* added some sleep to see the result */
sleep(3);
exit(EXIT_SUCCESS);
}