107 lines
2.2 KiB
C
107 lines
2.2 KiB
C
#include <termios.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <sys/time.h>
|
|
#include "uselect.h"
|
|
|
|
static int lastFd=-1;
|
|
static struct termios atts;
|
|
static int echo=1;
|
|
|
|
void sys_keys_on(void) {
|
|
int iret;
|
|
|
|
struct termios attr;
|
|
if (echo) {
|
|
iret=tcgetattr(STDIN_FILENO,&attr);
|
|
atts=attr; /* save term. attr. */
|
|
if (iret!=0) { perror("***\n");}
|
|
attr.c_lflag &= ~(ICANON) & ~(ECHO); /* canonical mode off, echo off */
|
|
attr.c_cc[VMIN]=0;
|
|
attr.c_cc[VTIME]=1; /* 0.1 sec */
|
|
iret= tcsetattr(STDIN_FILENO,TCSANOW,&attr);
|
|
if (iret!=0) {perror("***\n");}
|
|
echo=0;
|
|
}
|
|
}
|
|
|
|
void sys_keys_off(void) {
|
|
int iret;
|
|
|
|
if (!echo) {
|
|
iret=tcsetattr(STDIN_FILENO,TCSANOW,&atts); /* restore term. attributes */
|
|
if (iret!=0) {perror("***\n");};
|
|
echo=1;
|
|
}
|
|
}
|
|
|
|
static int getChar(void) {
|
|
unsigned char c;
|
|
int rt;
|
|
|
|
rt = read(STDIN_FILENO, &c, 1);
|
|
if (rt<=0) {
|
|
return EOF;
|
|
} else {
|
|
return c;
|
|
}
|
|
}
|
|
|
|
int sys_select_or_key(fd_set *mask, int msecTmo, int *key) {
|
|
int fd, iret, fd1, chr;
|
|
struct timeval tmo, tmo0={0,0};
|
|
fd_set rmask;
|
|
|
|
sys_keys_on();
|
|
rmask=*mask;
|
|
iret=uselect(FD_SETSIZE, &rmask, NULL, NULL, &tmo0);
|
|
if (iret<0) {
|
|
FD_ZERO(&rmask);
|
|
perror("error in select");
|
|
}
|
|
fd1=STDIN_FILENO;
|
|
/* chr=fgetc(stdin); */
|
|
chr = getChar();
|
|
if (chr == EOF && iret==0) { /* */
|
|
rmask=*mask;
|
|
FD_SET(STDIN_FILENO, &rmask);
|
|
if (msecTmo>=0) {
|
|
if (msecTmo>100) { /* reduce 100 ms for the 1 tenth second in fgetc */
|
|
msecTmo=msecTmo-100;
|
|
} else {
|
|
msecTmo=1;
|
|
}
|
|
tmo.tv_sec=msecTmo / 1000;
|
|
tmo.tv_usec=(msecTmo%1000)*1000;
|
|
iret=uselect(FD_SETSIZE, &rmask, NULL, NULL, &tmo);
|
|
} else {
|
|
iret=uselect(FD_SETSIZE, &rmask, NULL, NULL, NULL);
|
|
}
|
|
if (iret<0) {
|
|
FD_ZERO(&rmask);
|
|
perror("error in select");
|
|
}
|
|
if (FD_ISSET(STDIN_FILENO, &rmask)) {
|
|
chr = getChar();
|
|
/* chr=fgetc(stdin); */
|
|
}
|
|
FD_CLR(STDIN_FILENO, &rmask);
|
|
}
|
|
if (chr==EOF) {
|
|
chr=0;
|
|
fd1=-1;
|
|
for (fd=1; fd<FD_SETSIZE; fd++) {
|
|
if (FD_ISSET(fd, &rmask)) {
|
|
if (fd1<0) {
|
|
fd1=fd; /* first fd */
|
|
} else if (fd>lastFd) {
|
|
fd1=fd; break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*mask=rmask;
|
|
*key=chr;
|
|
return(fd1);
|
|
}
|