How can I capture a key stroke immediately in Linux?

Possible duplicate:
What is equivalent to getch () and getche () on Linux?

I am new to Linux programming. :-)

I'm just wondering if my program (using the C language) can immediately capture every single stroke in linux, and then decide whether its echo should or not, and how to display it like telnet.

For example, if the user presses β€œA”, I want the program to display β€œB” if he types β€œB”, β€œC”, etc.

It sounds funny and useless. I'm just curious.

+7
source share
4 answers

Basically, it depends a lot on how you determine right away.

There are two tasks here. First off, turn off the regular echo built into most input libraries. The second is to print a new character instead of the old.

In pseudo code.

echo(off); while (capturing && charIsAvailable()) { c = readOneChar(); if (c == '\n') { capturing = false; } printf("%c", c++); } echo(on); 

There are several reporting systems for fixing keystrokes.

  • Keyboard
  • (possibly) USB bus
  • CPU interrupt handler
  • operating system
  • Window Server Process X
  • X-window in which there is focus.

The last step is performed using a program that starts a continuous loop that captures events from the X server and processes them. If you want to deploy this program in certain ways (get the time, press a key), you need to tell other programs that you want "raw" keyboard events, which means that you really won’t receive fully "cooked" "characters." you will need to keep track of which keys are up and down, and for how long, and process all the odd meta-key actions in your program (this is not β€œa” this is β€œA” because it is a down shift, etc.).

There are other processing modes, for example, canonical and noncanonical, which will control whether you want events to be received in lines oriented to the line (events of the line) or character-oriented fragments (symbolic events). Again, this is somewhat complicated by the need to inform upstream programs about the requirements of the client listed below.

Now that you have an idea of ​​your environment, let me re-examine the actual code needed to suppress character output.

 // define a terminal configuration data structure struct termios term; // copy the stdin terminal configuration into term tcgetattr( fileno(stdin), &term ); // turn off Canonical processing in term term.c_lflag &= ~ICANON; // turn off screen echo in term term.c_lflag &= ~ECHO; // set the terminal configuration for stdin according to term, now tcsetattr( fileno(stdin), TCSANOW, &term); (fetch characters here, use printf to show whatever you like) // turn on Canonical processing in term term.c_lflag |= ICANON; // turn on screen echo in term term.c_lflag |= ECHO; // set the terminal configuration for stdin according to term, now tcsetattr( fileno(stdin), TCSANOW, &term); 

Not even that right away. To get immediate access, you need to approach the source, which ultimately means the kernel module (which is still not as direct as the keyboard microcontroller, which is not as close as the moment the switch closes). If there is a sufficient number of objects between the source and the recipient, in the end it becomes possible to notice the difference, however, in practice, this code has worked hard for people who are looking for the best compromise between performance and flexibility.

+12
source

Edwin Buck gave a great answer. Here is another alternative that uses ncurses , which makes such things easier and is supported for almost all Linux distributions and other Unix variants.

 #include <ncurses.h> int main(int argc, char *argv[]) { int ch,c; initscr(); cbreak(); noecho(); while( ch != 'q') { switch( c = getch() ) { case 'a': ch = 'b'; break; case 'b': ch = 'c'; break; case 'c': ch = 'd'; break; default: ch = c; break; } printw("%c",ch); } endwin(); return(0); } 

compile with gcc code.c -o -lncurses

And here are some supporting links:

ncurses noecho and another page - man
ncurses programming howto

+5
source

This code can be found on the Internet and through kermi3 with c-board

 #include <termios.h> #include <unistd.h> int mygetch(void) { struct termios oldt,newt; int ch; tcgetattr( STDIN_FILENO, &oldt ); newt = oldt; newt.c_lflag &= ~( ICANON | ECHO ); tcsetattr( STDIN_FILENO, TCSANOW, &newt ); ch = getchar(); tcsetattr( STDIN_FILENO, TCSANOW, &oldt ); return ch; } 

EDIT: of course, if you want to get char, not ascii, change to char instead of int

+4
source

it may be too much, but you can use game libraries like sdl to achieve this.

0
source

All Articles