Distinquishing escape key from arrow and function keys

Distinquishing escape key from arrow and function keys

Post by Brain in Neutr » Fri, 12 Apr 1991 02:44:24



I have a program where the escape key is significant, but I also
want to be able to use the arrow and functions keys (which typically also
begin with escape).  I would be interested in how any of you solve this
problem.

My solution (if you can call it that): when an escape character is seen,
keep reading until
        (i) characters read entirely match some special key.  return some
                value (I use values >= 0200) to indicate such.
        (ii) characters read fail to match any special key character sequence.
                return escape to caller and save any other characters read
                to a pushback queue.
        (iii) timeout after brief wait and neither (i) nor (ii) obtain.
                return escape to caller and save any other characters read
                to a pushback queue.

On a BSD system, select() does the timeout nicely.  I'm not so familiar
with System V.  Do you use the MIN and TIME special control character
values in the termio.c_cc[] array?  What about under POSIX?

--
Paul DuBois                               "The 'C' shell usually doesn't

 
 
 

Distinquishing escape key from arrow and function keys

Post by Brandon S. Allbery KB8JRR/ » Mon, 15 Apr 1991 02:47:56



+---------------
| On a BSD system, select() does the timeout nicely.  I'm not so familiar
| with System V.  Do you use the MIN and TIME special control character
| values in the termio.c_cc[] array?  What about under POSIX?
+---------------

SVR3 curses will do this for you --- when you call keypad() on a window, it
will return special keys as #define'd values starting at 0400.  It has a
timeout of about a second (this may be tuneable via halfdelay()).

Some programs I use make use of VMIN and VTIME.  My own programs don't do
timeouts, but could fairly easily do them because they use select() anyway.
(On systems that support it, at least.)  My main technique for avoiding ESC
anomalies is to not use bare ESC for anything and to try to map things on to
keys without an ESC prefix... which is difficult on a DEC-compatible terminal.

++Brandon
--
Me: Brandon S. Allbery                    Ham: KB8JRR/AA on 2m, 220, 440, 1200

America OnLine: KB8JRR // Delphi: ALLBERY   AMPR: kb8jrr.AmPR.ORG [44.70.4.88]


 
 
 

Distinquishing escape key from arrow and function keys

Post by John Templ » Mon, 15 Apr 1991 01:33:13



Quote:>On a BSD system, select() does the timeout nicely.  I'm not so familiar
>with System V.  Do you use the MIN and TIME special control character
>values in the termio.c_cc[] array?

System V curses works the way you describe, i.e., it can distinguish
between ESC and ESC[A, and return the application a single token for
either input.  What I don't know is how curses implements this.  On my
System V box, you cannot set MIN=1 and TIME=1 to get a .1 second
timeout on a single character read, nor should you be able to,
according to termio(7).  We had a discussion about this very topic
right here a few months back, and I don't think anyone knew how to do
it on System V, even though it obviously can be done.
--

 
 
 

Distinquishing escape key from arrow and function keys

Post by Michael Stefan » Tue, 16 Apr 1991 05:23:30



|System V curses works the way you describe, i.e., it can distinguish
|between ESC and ESC[A, and return the application a single token for
|either input.  What I don't know is how curses implements this.  On my
|System V box, you cannot set MIN=1 and TIME=1 to get a .1 second
|timeout on a single character read, nor should you be able to,
|according to termio(7).  We had a discussion about this very topic
|right here a few months back, and I don't think anyone knew how to do
|it on System V, even though it obviously can be done.

Actually, it isn't that difficult.  Basically, it can be done by reading
termcap/terminfo and getting the values returned by the various keys (which
in the example below, is placed in c_key[]).  You then read characters into
a "circular" buffer (queue[]) and then hunt through that buffer, looking for
matches to your various keys.  Since the timeout is small, a single escape
gets passed thorugh as just an escape, while edit and function keys will
load more characters into the buffer, which are reduced to single integer
values.  Here is the function that I use in an "inline editor" that I
wrote as an external call for our BASIC programmers (note there is the slight
chance that buffer will "overflow" and some keystrokes will be lost if
you lean on a key that outputs alot of characters) ...

tgetch()
{
static int      queue[MAXENQ+8], qptr = 0, nextq = 0, inqueue = 0;
char            buf[MAXENQ], *bptr;
int             bytes, ret, out, special, left;
register int    len, n;

        if ( inqueue > 0 ) {
                out = queue[nextq++];
                if ( nextq > MAXENQ )
                        nextq = 0;
                --inqueue;
                return(out);
                }

        while ( (bytes = read(0,buf,MAXENQ)) == 0 )
                ;
        bptr = buf;

        special = 0;

        /* believe it or not, some terminals out there have cursor
           keys that return a CR or LF; since this is a touchy subject,
           make sure that we interpret them literally */

        if ( bytes == 1 ) {
                if ( (*buf == 015 ) || (*buf == 012) )
                        return((int)*buf);
                }

        while ( bytes > 0 ) {
                ret = (int)*bptr;
                for (n = 0; n < K_MAXKEY; n++) {
                        if ( ((len = strlen(ckey[n])) > bytes) || (len == 0) )
                                continue;
                        if ( memcmp(bptr,ckey[n],len) == 0 ) {
                                bptr += (len-1);
                                bytes -= len;
                                special = 1;
                                ret = K_KEY + n;
                                break;
                                }
                        }
                if ( qptr > MAXENQ )
                        qptr = 0;
                queue[qptr++] = ret;
                ++inqueue;
                ++bptr;
                --bytes;
                }

        out = queue[nextq++];
        if ( nextq > MAXENQ )
                nextq = 0;
        --inqueue;

        return(out);

Quote:}

--
Michael Stefanik, MGI Inc, Los Angeles | Opinions stated are never realistic
Title of the week: Systems Engineer    | UUCP: ...!uunet!bria!mike
-------------------------------------------------------------------------------
If MS-DOS didn't exist, who would UNIX programmers have to make fun of?
 
 
 

1. Processing arrow keys, function keys, etc.

This might be a stupid question, but here it goes.

I'm working on a program that needs to process arrow keys, function keys,
and other special keys -- if they are available. What is the best way of
determining if such keys are available on the user's terminal and, if so,
what sequence of characters I can expect when they are pressed?

I looked at the curses library, but that seems mostly interested in
terminal independent output. It appears to have little to say about input.
I also looked a little at the lower level stuff (terminfo, termcap), but
again the information I'm interested in doesn't seem to be discussed there
either.

Am I missing something here?

TIA

*****************************************************************************
Peter                                    http://twilight.vtc.vsc.edu/~pchapin

2. Harware firewall for personal PC's running linux

3. Escape key timing issue and terminal function keys OSR5

4. andrew system environment variables

5. Interpreting Arrow Keys (and other escape sequences)

6. file count in directory

7. Arrow Keys cause escape sequence

8. Swap file possible?

9. arrow key function in CDE?

10. How to get Function/Arrow Keys? Source wanted

11. Function keys under X-Windows: Why do the generate the keys they do?

12. Function of Keys ALT-CTRL key combinations

13. Function key escape codes for ibm3151