tty pts终端下获取键值 ctrl c 或3秒自动退出。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#define BUFSZ 18
int fd;
int oldkbdmode;
struct termios oldtermios;
void restore(void)
{
ioctl(fd,KDSKBMODE, oldkbdmode);
tcsetattr(fd, 0, &oldtermios);
close(fd);
}
void intrupt(int)
{
restore();
printf("quit\n");
exit(0);
}
void setup()
{
struct termios new = {0};
char* tty = ttyname(STDIN_FILENO);
if(tty)
fd = open(tty,O_RDWR);
if(!isatty(fd) || fd < 0){
fprintf(stderr,"open tty failed\n");
exit(0);
}
signal(SIGINT, intrupt);
signal(SIGALRM,intrupt);
ioctl(fd, KDGKBMODE, &oldkbdmode);
tcgetattr(fd, &oldtermios);
new = oldtermios;
new.c_lflag &= ~(ECHO | ICANON);
new.c_cc[VMIN] = BUFSZ;
new.c_cc[VTIME] = 1;
tcsetattr(fd, TCSAFLUSH, &new);
ioctl(fd, KDSKBMODE, K_UNICODE);
}
int main()
{
unsigned char buf[BUFSZ];
setup();
while(1) {
alarm(3);
ssize_t n = read(fd, buf, sizeof(buf));
if(n > 0)
printf("keycode");
for(int i = 0; i < n; i++)
printf("\thex:0x%2x dec:%3d char:%c \n",buf[i],buf[i],buf[i]);
}
restore();
return 0;
}
K_UNICODE 模式 tty pts 键值一致,xlate模式tty ctrl 无反应,其它一致。
保持一致性最好用K_UNICODE模式,X11下KBDMODE是模拟的,设置kbd模式没什么用,tty下才有用。 有的字符不可打印,%c打印出来会hex 会少个字符。