您如何阅读箭头键? [英] How do you read the arrow keys?

查看:151
本文介绍了您如何阅读箭头键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在termios和xterm上使用原始模式的广泛搜索导致了对定时技巧"的大量引用,以区分转义序列转义的单独出现字符.

Extensive searching on the use of raw mode with termios and xterm leads to numerous references to a "timing trick" required to distinguish between an escape-sequence and a lone appearance of the escape character.

那你怎么做呢?

我不想使用诅咒,因为我不想清除屏幕.这是用于计算器样式的程序,因此保留"ticker-tape"界面很重要.

I don't want to use curses because I don't want to clear the screen. This is for a calculator-style program, so it's important to retain the "ticker-tape" interface.

推荐答案

最终在

finally found a nice detailed description in an old usenet thread. I quote the relevant message in its entirety.


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来进行黑客入侵, 它不会那么可靠.我至少知道一种商业产品 使用此方法(termio,而不是select),但是至少有一个文档记录了该方法 我也已经阅读了程序员手册.

AT&T has a very nice solution to this problem; unfortunately, it depends on AT&T termio (or POSIX termios), so implementing it under a BSD variant is difficult. Although one could conceivably come up with a hack using select, it would not be quite as reliable. At least one commercial product I know of uses this method (termio, not select), but it was documented in at least one programmer's manual I've read as well.

终端实际上​​没有原始"模式;它具有数据包"模式.最多 通常使用的数据包大小为1,超时为1(被视为 无超时").但是,可以将其设置为其他组合.最多 在这种情况下,有用的是将数据包大小设置为最长的数据包大小. 功能键序列及其超时所需的最长时间 发送作为功能键.假设(通常是正确的)是 用户键入它会花费更长的时间.

Termio(s) doesn't really have a "raw" mode; it has a "packet" mode. The most common use is with a packet size of 1 and a timeout of 1 (which is treated as "no timeout"). However, one can set it for other combinations. The most useful in this case is to set the packet size to the size of the longest function key sequence and the timeout to the longest time needed for it to be sent as a function key. The assumption (usually correct) being that if the user types it, it will take longer.

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

Once this is done, you attempt to read() that longest number of characters at the same time. read() returns the actual number of characters read before the timeout, which starts after the first character of the packet is received. Thus, single keystrokes like ESC are read as such, but given something like a VT100, PF1 would return 3 characters --- ESC O P (ESC [ P if, like me, you detest the applications cursor and keypad modes).

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()并可以在您的端口中使用,则为此.

Getting VTIME correct for various baud rates can be tricky; but it's also a one-time task. And I've used this trick in my own programs; it works well. I believe the function key support in SVR3 curses can be coerced into doing this if halfdelay() is enabled and works in your port.

对于BSD,我最多只能说检查一下您的版本(例如Ultrix 3.x) 或SunOS 4.x等)支持termio接口,或等待BSD4.4 据称将拥有POSIX termios. (由于BSD4.4已发布或即将发布, 很快---我与它失去联系了---无疑有人会鸣叫 并告诉我们.)请注意,早期的Ultrix版本声称具有termio 支持,但是没有用.

For BSD, the most I can say is check to see if your version (e.g. Ultrix 3.x or SunOS 4.x, etc.) supports a termio interface, or wait for BSD4.4 which supposedly will have POSIX termios. (Since BSD4.4 is either out or will be very soon --- I've been out of touch with it --- no doubt someone will chime in and tell us.) Be warned that earlier Ultrix versions claimed to have termio support, but it didn't work.

我已修剪了该作者的签名栏,因为他承认自己仍然不是原始作者.

这篇关于您如何阅读箭头键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆