Path: utzoo!utgpu!water!watmath!clyde!att!rutgers!ucsd!telesoft!jjh From: jjh@telesoft.UUCP (Jim Hayes @dance) Newsgroups: comp.unix.wizards Subject: How to write keypressed()? Message-ID: <315@telesoft.UUCP> Date: 29 Sep 88 17:37:49 GMT Organization: TeleSoft Inc., San Diego, CA Lines: 57 I'm working on a user interface that needs to differentiate between the keyboard arrow keys, which send [, and the escape key. Fine, says I, I'll just write a little routine to use when I see to look for a character in the stdin stream. Well, not so fine. The routine I wrote never detected the '[' after the , 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 . 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