【问题标题】:How to differentiate between Escape and Up/Down/Left/Right with termios?如何使用 termios 区分 Escape 和 Up/Down/Left/Right?
【发布时间】:2011-07-14 10:17:32
【问题描述】:

GitHub

这是我能想到的最好的处理 ncurses 式按键的方法(出于各种原因,我实际上正在编写 ncurses 的替代方案)。

使用此代码构建的示例应用建议用户“按 Escape 退出”。事实上,它需要 Escape + Escape 或 Escape + An Arrow Key。我想解决这个问题。

#include <sys/ioctl.h>
#include <termios.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *get_key() {
    char c = getchar();

    switch(c) {
        case 'a': return "a";
        case 'b': return "b";
        case 'c': return "c";

        ...

        case '\x1b':
            c = getchar();
            switch(c) {
                case '[':
                    c = getchar();
                    switch(c) {
                        case 'A': return "up";
                        case 'B': return "down";
                        case 'C': return "right";
                        case 'D': return "left";
                    }
                case '\x1b': return "escape";
            }

        default: return "unknown";
    }

【问题讨论】:

    标签: escaping ncurses arrow-keys termios


    【解决方案1】:

    第 1 步。研究。

    http://en.wikipedia.org/wiki/Escape_sequence

    如果 Esc 键和其他发送转义序列的键都是 应该对应用程序有意义,就会产生歧义,如果 终端或终端仿真器正在使用中。特别是,当 应用程序收到 ASCII 转义字符,不清楚 该字符是否是用户按 Esc 键的结果 或者它是否是转义序列的初始字符(例如, 由箭头键按下产生)。传统的方法 解决歧义是观察另一个字符是否 快速跟随转义字符。如果不是,则假定不是 转义序列的一部分。这种启发式在某些情况下可能会失败 情况下,但在实践中它工作得相当好,尤其是 具有更快的现代通信速度。

    第 2 步。弄清楚如何查看操作系统的输入缓冲区中是否有另一个字符在等待。如果缓冲区中已经有一个字符;这是一个转义序列。如果输入缓冲区为空,则为转义。

    由于您没有提及您的操作系统,因此不清楚如何做到这一点。

    Windows:What is the Windows equivalent to the capabilities defined in sys/select.h and termios.h

    Linux:http://linux.die.net/man/3/termios

    【讨论】:

    • 我正在编写一个与操作系统无关的 ncurses 克隆。是的,时间似乎是唯一的方法——roguelikes 就是这样做的。我只是不知道如何使用 VMIN/VTIME。
    【解决方案2】:

    与其依赖VMIN/VTIME 相当脆弱的计时机制,您可能更愿意将计时逻辑上移到纯用户态。我写了一个库来处理这个和其他一些情况:

    http://www.leonerd.org.uk/code/libtermkey/

    除了将 Escape 与箭头键区分开来,它还可以处理现代终端开始使用的修改后的箭头键和修改后的 Unicode,支持阻塞和非阻塞使用,以及许多其他事情。事实上,termkey_waitkey() 可以轻松地执行您的 get_key() 函数以获取按键,然后通过 termkey_strfkey() 将其格式化为字符串缓冲区。

    【讨论】:

      【解决方案3】:

      缓冲区和一些位选项可以很好地完成这项工作。

      GitHub

      【讨论】:

      • 您介意链接到确切的代码吗,我不知道在您的代码库中查找的位置。
      猜你喜欢
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 2019-09-29
      • 2014-03-10
      • 2018-06-10
      • 1970-01-01
      相关资源
      最近更新 更多