[svlug] Extended Keyboard Input Utility For Bash?

Mark S Bilk mark at cosmicpenguin.com
Tue Mar 27 00:25:11 PDT 2007


On Mon, Mar 26, 2007 at 10:58:42PM -0700, Tim Utschig wrote:
>On Mon, Mar 26, 2007 at 01:36:45PM -0700, Mark S Bilk wrote:
>>...
>> When I run it, it blanks the entire konsole or xterm window until I
>> type the key, so I lose the context of whatever's been output to the
>> screen while deciding what to type.  Does this not happen on your
>> system?
>
>I should have described the environment I tested it with...
>
>    - Ubuntu 6.10 "Edgy" i386
>    - ncurses version 5.5-2ubuntu1
>    - Terminal emulators tested:  gnome-terminal, linux console
>
>I tested it in xterm just now and saw the behavior you described.  Must
>be some difference in the handling of the ncurses initialization since
>gnome-terminal uses TERM=xterm.  I'll try some more things with ncurses
>next time I have some free time.

Thanks!  I'll see if I can run gnome-terminal in KDE.

But somewhere in the curses docs it says that initscr always 
blanks the terminal screen, i.e., it's supposed to.  So maybe 
the init sequence for gnome-terminal is defective.

>> I tried putting a select() call in the code before yours, to wait
>> until the key is pressed, which stopped the blanking, but then it
>> only gets the first byte of keypad escape sequences and only outputs
>> "^[".  
>
>So it didn't wait for a key to be pressed before adding select?
>getch() should block by default...

getch() does block, but by that time initscr() has already
blanked the terminal screen.  So the user sees only the blank 
screen, because the script and the getkey program wait in 
getch() for a new key when the script isn't doing anything, 
which is almost all the time.

So I put the select() call in before initscr(), so it would
be waiting in select() with the screen not blanked, and only 
proceed to initscr() (and blank the screen only momentarily)
when a key is typed.

>> Also, with the select call I have to press Enter to get it to accept
>> whatever I type.  So I inserted code to set the terminal to raw mode 
>> before the select (see below), which eliminates the need to press 
>> Enter, but it's still only putting out ^[ for keypad keys (except 
>> PgUp and PgDn).
>
>I don't think you need raw mode.  "man 3 raw" says it's just like cbreak
>except characters that would normally generate signals are passed
>through.

I put it in raw mode (using my own routine, not one from curses)
before the select call, and thus before the initscr.  Otherwise
the key code(s) doesn't reach select until Enter is pressed.

BTW, I looked through all the termcap entries for the xterm* 
series, and only xterm-noapp has the right escape sequences for 
the up, down, left, right keys.  Weird!

I guess curses can't generally be used in bash scripts because
it keeps virtual screens and other data in memory, so various
curses routines can't be encapsulated in separate C programs
and called at various separate places in the scripts.

So a curses-using programs must be written as a single C program.
And usually, programs that use the arrow keys have a two-dimensional 
interface and use curses (or a GUI).  In my particular case, the 
2-D interface is the mplayer screen; I'm moving a rectangle around
on mplayer's video screen.  But that's rare, so I guess this is
why there's no standard program for accessing the keypad arrow keys 
in bash scripts.

I'll just take the infocmp output, fix the few wrong entries, and
run it through a couple of sed calls to make an array of struct 
of strings initializer.  Do that for xterm and the linux console
(which doesn't need any fixing) and have the getkey C program 
choose the right array according to the value of the TERM variable.
Since getkey outputs any escape sequences that it can't translate
(with all characters made printable), it's easy for anyone who 
wants to use it on a new terminal to find what needs fixing.

  Mark





More information about the Svlug mailing list