467,927 Members | 1,827 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,927 developers. It's quick & easy.

termios and keyboard medium raw mode

Hi

I wrote the following program that reads the keyboard in medium raw
mode (keycode mode). Here is the initialization code, the full code is
at the end.

fd = open("/dev/tty0", O_RDONLY);
tcgetattr ( fd, &newkbd );
newkbd.c_lflag &= ~ (ECHO | ICANON | ISIG);
newkbd.c_iflag = 0;
newkbd.c_cc[VMIN] = 18;
newkbd.c_cc[VTIME] = 1;
tcsetattr ( fd, TCSAFLUSH, &newkbd );
ioctl ( fd, KDSKBMODE, K_MEDIUMRAW );

It's suppose to control the value of linvel and rotvel (linear and
rotational velocity) when the user presses the arrow keys or the WASD
keys. To handle multi keys at the same time, I set the value when the
user presses the key, and reset it to 0 on release.

However it doesn't work. Let say I press UP, then RIGHT while
maintaining UP pressed, then release UP while maintaining RIGHT
pressed, then release RIGHT. In that case, I receive the following
events: UP pressed, RIGHT pressed, Right released. UP released is
missing. What am I doing wrong? Can you suggest another way of doing
this?

Also, the terminal keeps scrolling down, as if I was constantly
pressing ENTER. Why? Besides, I have to run this code as super user,
which is not really nice...

I am using linux, kernel 2.6.22 and gcc. Portability is not an issue.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <linux/keyboard.h>

int fd=-1, oldkbmode=K_RAW;
struct termios orig_kb;
float linvel=0, rotvel=0;

void clean_up ( void ) {
ioctl ( fd, KDSKBMODE, oldkbmode );
tcsetattr ( fd, 0, &orig_kb );
close ( fd );
}

void printVel(int i) {
printf("%f %f\n", linvel, rotvel);
alarm(1);
}

int main(){
int keycode, pressed, controlPressed=0;
unsigned char buf[18]; /* divisible by 3 */
int i,n;
struct termios newkbd;

/* Open and configure the keyboard */
fd = open("/dev/tty0", O_RDONLY);
tcgetattr ( fd, &orig_kb );
tcgetattr ( fd, &newkbd );
newkbd.c_lflag &= ~ (ECHO | ICANON | ISIG);
newkbd.c_iflag = 0;
newkbd.c_cc[VMIN] = 18;
newkbd.c_cc[VTIME] = 1;
tcsetattr ( fd, TCSAFLUSH, &newkbd );

/* Set medium raw mode: we receive keycodes. */
ioctl ( fd, KDGKBMODE, &oldkbmode );
ioctl ( fd, KDSKBMODE, K_MEDIUMRAW );

/* Restore the normal keyboard mode on exit */
atexit(clean_up);

/* Every 1 second, print the value of linvel and rotvel */
signal(SIGALRM, printVel);
alarm(1);

while( 1 ){
/* Wait until a key is pressed or released */
n = read ( fd, buf, sizeof ( buf ) );

/* Retrieve the key code and whether the key was pressed or
released */
i = 0;
while ( i < n ) {
pressed = (buf[i] & 0x80)==0x80 ? 0 : 1;
if ( i+2 < n && ( buf[i] & 0x7f ) == 0
&& ( buf[i+1] & 0x80 ) != 0 && ( buf[i+2] & 0x80 ) != 0 )
{
keycode = ( ( buf[i+1] & 0x7f ) << 7 ) | ( buf[i+2] & 0x7f );
i += 3;
}
else keycode = ( buf[i++] & 0x7f );
}

/* Take appropriate action */
switch ( keycode ) {
case 103: //UP ARROW
case 17: //W
linvel = pressed ? 1 : 0;
break;
case 108: //DOWN ARROW
case 31: //S
linvel = pressed ? -1 : 0;
break;
case 105: //LEFT ARROW
case 30: //A
rotvel = pressed ? -1 : 0;
break;
case 106: //RIGHT ARROW
case 32: //D
rotvel = pressed ? 1 : 0;
break;
case 29: //CTRL
controlPressed = pressed;
break;
case 46: //C
if( controlPressed && pressed ) exit(0);
break;
}
}
return 0;
}
Mar 13 '08 #1
  • viewed: 5013
Share:
2 Replies
In article <91**********************************@e6g2000prf.g ooglegroups.com>,
Brice Rebsamen <br************@gmail.comwrote:
>Hi

I wrote the following program that reads the keyboard in medium raw
mode (keycode mode). Here is the initialization code, the full code is
at the end.

fd = open("/dev/tty0", O_RDONLY);
(With love and affection)

Off topic. Not portable. Cant discuss it here. Blah, blah, blah.

--
Useful clc-related links:

http://en.wikipedia.org/wiki/Aspergers
http://en.wikipedia.org/wiki/Clique
http://en.wikipedia.org/wiki/C_programming_language

Mar 13 '08 #2
Brice Rebsamen wrote:
Hi

I wrote the following program that reads the keyboard in medium raw
mode (keycode mode).
[Snip]
I am using linux, kernel 2.6.22 and gcc. Portability is not an issue.
I suggest you try a group appropriate to your platform, as this question
is about platform-specifics rather than the C language.

comp.unix.programmer would probably be a good start.
Mar 13 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by henry xie | last post: by
9 posts views Thread by skearney | last post: by
6 posts views Thread by hem | last post: by
reply views Thread by Laszlo Nagy | last post: by
3 posts views Thread by goblin | last post: by
1 post views Thread by jorba101 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.