[comp.unix.wizards] Interesting keyboard read problem

tuck@iris.ucdavis.edu (Devon Tuck) (08/10/90)

Hey wizards,

I have been working with an intersting problem...  How to write a keyboard 
input routine that does not mess up its' transmission of repeated function
keys.  You might have noticed that even in vi, and in the C-shell, if you
sit on an arrow key or some other function key that maps to a character
sequence, you get intermittent beeps, or stray characters, respectively.

I am porting an editor for a bunch of users who are in deep wedlock with
their function keys, and they MUST be able to sit on their little arrow
keys and not lose any characters, BUT character throughput must be VERY
FAST.

The problem is that this editor is very bulky, and spends too much time
away from the keyboard input routine, so that if I do the logical thing
and set VMIN=1 and VTIME=0, portions of the home key sequence (<ESC>[H),
for example, get split across network packets and arrive with too much gap
for the keyboard driver to consider it a valid screen movement sequence.

Has anyone solved this problem?  I think I might have it with a routine that
forks on its' first call, after setting up a pipe and ioctl calls, (VMIN=0,
VTIME=0) and thus leaves a small subprocess running alongside the editor
acting as a slave to the keyboard and sending all characters into a pipe
to be read at the leasure of the main character input routine.

How do other editors do it?  How do Crisp, emacs, etc. handle this? (as I
mentioned, vi doesn't..)

Thanks,
	Devon Tuck
	tuck@iris.ucdavis.edu

PS - Incidentally, when I use a straight character read with VMIN>=1,
VTIME=1 the input is still too slow.

les@chinet.chi.il.us (Leslie Mikesell) (08/14/90)

In article <7562@ucdavis.ucdavis.edu> tuck@iris.ucdavis.edu (Devon Tuck) writes:

>I have been working with an intersting problem...  How to write a keyboard 
>input routine that does not mess up its' transmission of repeated function
>keys.  You might have noticed that even in vi, and in the C-shell, if you
>sit on an arrow key or some other function key that maps to a character
>sequence, you get intermittent beeps, or stray characters, respectively.

>The problem is that this editor is very bulky, and spends too much time
>away from the keyboard input routine, so that if I do the logical thing
>and set VMIN=1 and VTIME=0, portions of the home key sequence (<ESC>[H),
>for example, get split across network packets and arrive with too much gap
>for the keyboard driver to consider it a valid screen movement sequence.

Doesn't look logical to me.  How about setting VMIN=1, VTIME=2 and make
your read()'s request many characters at once in order to always catch
up with the keyboard in one syscall?

>Has anyone solved this problem?  I think I might have it with a routine that
>forks on its' first call, after setting up a pipe and ioctl calls, (VMIN=0,
>VTIME=0) and thus leaves a small subprocess running alongside the editor
>acting as a slave to the keyboard and sending all characters into a pipe
>to be read at the leasure of the main character input routine.

This is a reasonable approach but shouldn't really be necessary unless you
are waiting for slow operations like a screen redraw to complete before
checking for keyboard input.  You certainly wouldn't want to set VMIN=0
though, or you will be making hundreds of syscalls/second and consume most
of the CPU.  A subprocess would want to block when there is no input since
it would have nothing else to do.  An alternative would be to make your
output routine check for input every so often.  A little math involving
chars/sec. should generate a suitable number to catch all the input
without swamping the machine.  (Use ioctl() to set O_NDELAY temporarily
so you can do a non-blocking read into a buffer). 

>How do other editors do it?  How do Crisp, emacs, etc. handle this? (as I
>mentioned, vi doesn't..)

If you don't use a bare "escape" as a command, there is no need to do any
funny timing to detect escape sequences.  If you do need the timing, the
best approach under sysV would be to let the driver do it by setting
VTIME appropriately (and you will still probably miss once in a while).

Les Mikesell
  les@chinet.chi.il.us