C++ noncanonical terminal read() specific keys

Viewed 36

I have the following code:

int setmode(int vtime, int vmin, int echo, int sigint)
{
    termios attr;
    tcgetattr(STDIN_FILENO, &attr);

    attr.c_lflag &= ~ICANON;
    if (echo)
        attr.c_lflag |= ECHO;
    else
        attr.c_lflag &= ~ECHO;
    if (sigint)
        attr.c_lflag |= ISIG;
    else
        attr.c_lflag &= ~ISIG;
    attr.c_cc[VMIN] = vmin;
    attr.c_cc[VTIME] = vtime;
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &attr);
    return 0;
}

int main()
{
    setmode(0, 1, false, true);
    while (true)
    {
        char c;
        read(0, &c, 1);
        cout << c;
        fflush(stdout);
    }
    return 0;
}

This correctly echoes keys (while removing cout << c; stops echoing, so I assume reading works correct and c contains correct char). Now I want to test if some specific keys like arrows, enter or backspace are pressed. For keys I've tried something like

if (c == '\[A') cout << "smth"; instead of cout << c; but this prints nothing. Also from infocmp I found that arrow-keys have following esc-sequences:

kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA and also tested them, but neither work. So in this code how do I test for arrows, enter, backspace, some F-keys? Also, is it possible to simplify setmode's if-else statements to a single bit-expression assignment?

1 Answers

Ok so I found a solution by casting c to int.

  1. Enter - 10
  2. Backspace - 127
  3. Arrows are sequence of 3 chars, first are 27 and 91, third shows the exact char
  4. Functional keys are sequence of 5 chars, first are 27 91 49, 4th is a key, 5th was 126 for both my F-keys (but still needs to be reader from buffer).
Related