Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting raw input from console using C or C++

/* Initialize new terminal i/o settings */
static struct termios old, new1;
void initTermios(int echo) {
    tcgetattr(0, &old); /* grab old terminal i/o settings */
    new1 = old; /* make new settings same as old settings */
    new1.c_lflag &= ~ICANON; /* disable buffered i/o */
    new1.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */
    tcsetattr(0, TCSANOW, &new1); /* use these new terminal i/o settings now */
}

/* Restore old terminal i/o settings */
void resetTermios(void) {
    tcsetattr(0, TCSANOW, &old);
}

How can I get arrow key as input (possibly as a single character), the current code works good for all other things I need... Please no solution with ncurses

like image 308
Shawn Avatar asked Jul 14 '11 18:07

Shawn


2 Answers

Have you tried the read function?

This works for me with cygwin g++, don't have linux handy to test:

#include <unistd.h>
#include <termios.h>
#include <stdio.h>

/* Initialize new terminal i/o settings */
static struct termios old, new1;
void initTermios(int echo) {
    tcgetattr(0, &old); /* grab old terminal i/o settings */
    new1 = old; /* make new settings same as old settings */
    new1.c_lflag &= ~ICANON; /* disable buffered i/o */
    new1.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */
    tcsetattr(0, TCSANOW, &new1); /* use these new terminal i/o settings now */
}

/* Restore old terminal i/o settings */
void resetTermios(void) {
    tcsetattr(0, TCSANOW, &old);
}

int main(void)
{
    char c;
    initTermios(0);
    while (1) { read(0, &c, 1); printf("%d\n", c); }
}

As @Fiktik noted, the echo setup is broken, but I'm using the code in the question without changes.

like image 147
Ben Voigt Avatar answered Sep 28 '22 17:09

Ben Voigt


There is a great tutorial about writing text editors for Unix terminals, with raw input, syntax coloring etc., which uses only the standard C library and standard headers available on Unix-like systems:

https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html

This chapter of the tutorial explains how to switch the terminal input to raw mode and process it with standard IO functions from C (read() & stuff). Then you can handle things like cursor movement, scrolling, colours etc. by writing to the output with certain escape sequences of the VT100 terminal. You can find more in this tutorial, including the links to all the documentations required, and sample source codes. There's also a GitHub repository with all the samples from the tutorial, as well as the final product, which is based on the Kilo editor written by antirez.

As for reading the special keys, like the arrow keys, Home ,End, PgUp, PgDown etc., try outputting the raw characters you get from the input and just press the keys you want to see what codes they map to. For the arrow keys, for example, they usually map to the escape sequences <ESC>[A through <ESC>[D, where <ESC> is the special control character with ASCII code 27 decimal or 0x1B hexadecimal. Those are the VT100 terminal escape codes that instruct the terminal to move the cursor one character into one of these four directions. More on handling these keystrokes in the next chapter of the aforementioned tutorial:

https://viewsourcecode.org/snaptoken/kilo/03.rawInputAndOutput.html

like image 31
BarbaraKwarc Avatar answered Sep 28 '22 18:09

BarbaraKwarc