【发布时间】:2016-04-21 20:18:08
【问题描述】:
通过 termios 和 xterm 对 raw 模式的使用进行广泛搜索,导致大量引用了区分 escape-sequence 和单独出现的 escape 所需的“计时技巧” 字符。
那么你是怎么做到的呢?
我不想使用诅咒,因为我不想清除屏幕。这是一个计算器风格的程序,所以保留“ticker-tape”界面很重要。
【问题讨论】:
通过 termios 和 xterm 对 raw 模式的使用进行广泛搜索,导致大量引用了区分 escape-sequence 和单独出现的 escape 所需的“计时技巧” 字符。
那么你是怎么做到的呢?
我不想使用诅咒,因为我不想清除屏幕。这是一个计算器风格的程序,所以保留“ticker-tape”界面很重要。
【问题讨论】:
终于在old usenet thread 中找到了一个很好的详细描述。我完整引用了相关信息。
路径:utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!usenet.ins.cwru.edu!ncoast!allbery 来自:所有...@NCoast.ORG (Brandon S. Allbery KB8JRR) 新闻组:comp.unix.programmer 主题: Re: 你是怎么看方向键的? 消息 ID: 日期:格林威治标准时间 91 年 1 月 1 日 03:56:56 参考: 回复:所有...@ncoast.ORG (Brandon S. Allbery KB8JRR) 后续行动:comp.unix.programmer 组织:北海岸计算机资源(ncoast) 行数:68 引自 brn...@kramden.acf.nyu.edu (Dan Bernstein): +--------------- |这真的是终端的错,而不是程序员的错。代码 |来自终端的应该是唯一可解码为非定时字节 |流。在最好的情况下,没有代码是另一个代码的前缀。 +---------------AT&T 有一个很好的解决方案来解决这个问题;不幸的是,这取决于 AT&T termio(或 POSIX termios),因此在 BSD 变体下实现它是 难的。虽然可以想象使用 select 想出一个 hack, 它不会那么可靠。我知道的至少一种商业产品 使用此方法(termio,而不是 select),但它至少记录在一个 程序员手册我也看过。
Termio(s) 并没有真正的“原始”模式;它有一个“数据包”模式。最多 常见的用途是数据包大小为 1,超时时间为 1(被视为 “没有超时”)。但是,可以将其设置为其他组合。最多 在这种情况下有用的是将数据包大小设置为最长的大小 功能键序列和超时所需的最长时间 作为功能键发送。假设(通常是正确的)是,如果 用户键入它,它需要更长的时间。
完成此操作后,您将尝试 read() 最长的字符数 同时。 read() 返回之前读取的实际字符数 超时,在收到数据包的第一个字符后开始。 因此,像 ESC 这样的单个击键被这样读取,但给出了类似 VT100, PF1 会返回 3 个字符 --- ESC O P (ESC [ P if, like me, you 讨厌应用程序的光标和键盘模式)。
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 诅咒中的功能键支持可以强制执行 如果启用了 halfdelay() 并在您的端口中工作,则此操作。
对于 BSD,我最多只能检查您的版本(例如 Ultrix 3.x 或 SunOS 4.x 等)支持 termio 接口,或等待 BSD4.4 哪个 据说会有POSIX termios。 (因为 BSD4.4 要么出来要么将会 很快——我已经与它脱节了——毫无疑问有人会插话 并告诉我们。)请注意,早期的 Ultrix 版本声称有 termio 支持,但是没用。
我已经删掉了这个作者的签名栏,因为他承认自己不是原作者。
【讨论】:
VTIME,我建议1纠正25年的摩尔定律。