你怎么读箭头键?

时间:2016-01-16 07:26:21

标签: c unix xterm termios

对使用带有termios和xterm的原始模式的广泛搜索导致了许多对时间技巧的引用"需要区分转义序列转义字符的单独外观。

那你怎么做的?

我不想使用诅咒,因为我不想清除屏幕。这是一个计算器式的程序,因此保留" ticker-tape"是非常重要的。接口

1 个答案:

答案 0 :(得分:1)

终于在old usenet thread中找到了一个很好的详细描述。我完整引用相关信息。

Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!usenet.ins.cwru.edu!ncoast!allbery
From: all...@NCoast.ORG (Brandon S. Allbery KB8JRR)
Newsgroups: comp.unix.programmer
Subject: Re: How do you read the arrow keys?
Message-ID: 
Date: 1 Jan 91 03:56:56 GMT
References:   
Reply-To: all...@ncoast.ORG (Brandon S. Allbery KB8JRR)
Followup-To: comp.unix.programmer
Organization: North Coast Computer Resources (ncoast)
Lines: 68

As quoted from  by brn...@kramden.acf.nyu.edu (Dan Bernstein):
+---------------
| It's really the terminal's fault, not the programmer's fault. Codes
| coming from the terminal should be uniquely decodable as untimed byte
| streams. In the best situation, no code is a prefix of another.
+---------------
  

AT& T对这个问题有一个非常好的解决方案;不幸的是,这取决于   AT& T termio(或POSIX termios),因此在BSD变体下实现它是   难。虽然可以想象一下使用select的hack,   它不会那么可靠。至少我知道的一种商业产品   使用这种方法(termio,而不是选择),但它至少记录在一个   程序员手册我也读过。

     

Termio(s)并没有真正的“原始”模式;它有一个“数据包”模式。最多   常见用法是数据包大小为1,超时为1(被视为   “没有超时”)。但是,可以将其设置为其他组合。最多   在这种情况下有用的是将数据包大小设置为最长的大小   功能键序列和超时到它所需的最长时间   将作为功能键发送。假设(通常是正确的)是,如果   用户输入它,需要更长时间。

     

完成此操作后,您将尝试读取()最长的字符数   同一时间。 read()返回之前读取的实际字符数   超时,在收到数据包的第一个字符后开始。   因此,像ESC一样的单击键被读取,但给出类似的东西   VT100,PF1将返回3个字符--- ESC O P(ESC [P如果像我一样,你   厌恶应用程序光标和键盘模式。)

struct termio tbuf; /* POSIX: struct termios */
int maxlen = 3, len;
char buf[3];

ioctl(0, TCGETA, &tbuf); /* POSIX: tcgetattr(0, &tbuf); */
tbuf.c_lflags &= ~(ICANON|ECHO);
tbuf.c_cc[VMIN] = maxlen;
tbuf.c_cc[VTIME] = 2; /* 2/10 sec, good at 9600 baud and up */
ioctl(0, TCSETAW, &tbuf); /* POSIX: tcsetattr(0, X???WAIT, &tbuf); */
              /* I forget the exact flag */

len = read(0, buf, maxlen);
if (len == 1)
{
    /* single character */
}
else
{
    /* function key sequence */
}
  

使各种波特率的VTIME正确可能很棘手;但它也是一个   一次性任务。我在自己的程序中使用过这个技巧;它运作良好。   我相信SVR3 curses中的功能键支持可以强制执行   如果halfdelay()已启用并在您的端口中工作,那么这就是

     

对于BSD,我能说的最多就是检查你的版本(例如Ultrix 3.x   或者SunOS 4.x等)支持termio接口,或者等待BSD4.4   据说将有POSIX termios。 (因为BSD4.4要么已经出局,要么将成为   很快---我已经脱离了它 - 毫无疑问,有人会说话   并告诉我们。)请注意,早期的Ultrix版本声称拥有termio   支持,但它没有用。

我已经删除了这位作者的签名栏,因为他承认不是原作者。