How to write keypressed()?
Jim Hayes @dance
jjh at telesoft.UUCP
Fri Sep 30 03:37:49 AEST 1988
I'm working on a user interface that needs to differentiate between the
keyboard arrow keys, which send <esc>[<some character>, and the escape key.
Fine, says I, I'll just write a little routine to use when I see <esc> to look
for a character in the stdin stream. Well, not so fine. The routine I wrote
never detected the '[' after the <esc>, so I interpreted all the arrow keys as
escape. Ok, maybe a timing problem; I'll try sleeping a bit before I look for
a character. This works better, but, if I type arrow keys fast enough,
eventually I get the same result -- even though I've typed a bunch of arrows my
function tells me there's nothing in the stdin stream after the <esc>. I've
included the current incarnation of my function below; can anyone shed some
light on what my problem is?
Some environmental information: I'm running under Sun3-3.5 Unix, using
curses, and I've got the terminal in cbreak mode when I'm calling this routine.
I originally tried using select(2) to look for the character; switching to
fcntl(2) and read(2) calls improved things significantly. I've tried playing
with the amount of time the routine sleeps -- I tried a single long sleep, a
single short sleep, incrementally longer sleeps, and, below, a series of short
sleeps. The last two seem to work best.
/*===========================================================================*/
short keypressed() {
/* Returns 1 if a character is available for reading from stdin; 0 otherwise */
char a_char;
int old_flags;
int result;
int retry;
if ( isatty( fileno(stdin) ) == 1 ) {
old_flags = fcntl(fileno(stdin), F_GETFL, 0);
if (old_flags < 0) {
return (0);
}
if ( fcntl(fileno(stdin), F_SETFL, old_flags | FNDELAY) < 0 ) {
return (0);
}
for (retry = 1; retry <= 10; ++retry) {
usleep(2000);
result = read(fileno(stdin), &a_char, 1);
if (result >= 0) {
ungetc(a_char, stdin);
(void) fcntl(fileno(stdin), F_SETFL, old_flags);
return (1);
}
}
(void) fcntl(fileno(stdin), F_SETFL, old_flags);
return (0);
}
else {
return (0);
}
}
------------------------------------------------------------------------------
"There's no problem so awful that you can't | Jim Hayes
add some guilt to it and make it even worse!" | ...!ucsd!telesoft!jjh
More information about the Comp.unix.wizards
mailing list