[comp.unix.questions] Curses and the arrow keys

mlake@irscscm.UUCP (Marshall Lake) (08/25/90)

I am writing a program which will be taking advantage of curses.  I am
trying to utilize the arrow keys and am confused (actually all of
curses confuses me).  I am doing a getch () and if I get an ESCAPE I do
another getch ().  If I addch () for each character I get (the ESCAPE
and the next character) then the cursor moves around properly on the
screen but the x/y coordinates in the window structure do not follow
suit.  Curses is recognizing the arrow keys simply as regular
characters.  Am I naive in thinking that curses is smart enough to
handle the arrow keys specially?  Should I be moving the cursor
manually via the move function?

I'm really not sure I know what I'm talking about when it comes to
curses so any help is appreciated.

Thanks.


             
                  
                                    

-- 
Marshall Lake
mlake@irscscm.UUCP
...!uunet!media!ka3ovk!irscscm!mlake

jetzer@studsys.mu.edu (Mike Jetzer) (08/27/90)

In article <1990Aug24.175453.4310@irscscm.UUCP> mlake@irscscm.UUCP (Marshall Lake) writes:
>I am writing a program which will be taking advantage of curses.
[ . . . ]
>I am doing a getch () and if I get an ESCAPE I do
>another getch ().  If I addch () for each character I get (the ESCAPE
>and the next character) then the cursor moves around properly on the
>screen but the x/y coordinates in the window structure do not follow
>suit.  Curses is recognizing the arrow keys simply as regular
>characters.  Am I naive in thinking that curses is smart enough to
>handle the arrow keys specially?  Should I be moving the cursor
>manually via the move function?

Your naivete could be corrected by reading the manpage on curses.

Performing a keypad() will enable the keypad on most terminals, and when
the user presses an arrow key, the return value will be KEY_DOWN, KEY_UP,
etc.  You can then take the proper action based on the key that the
user actually pressed.


-- 
Mike Jetzer
"And we'll have fun, fun, fun until Daddy takes the keyboard awa-ay..."

meissner@osf.org (Michael Meissner) (08/27/90)

In article <1990Aug24.175453.4310@irscscm.UUCP> mlake@irscscm.UUCP
(Marshall Lake) writes:

| I am writing a program which will be taking advantage of curses.  I am
| trying to utilize the arrow keys and am confused (actually all of
| curses confuses me).  I am doing a getch () and if I get an ESCAPE I do
| another getch ().  If I addch () for each character I get (the ESCAPE
| and the next character) then the cursor moves around properly on the
| screen but the x/y coordinates in the window structure do not follow
| suit.  Curses is recognizing the arrow keys simply as regular
| characters.  Am I naive in thinking that curses is smart enough to
| handle the arrow keys specially?  Should I be moving the cursor
| manually via the move function?

If your curses is based on the System V.2 curses, it will have a
'keypad' function which turns on recognizing any arrow keys or
function keys.  Here is a copy of the documentation:


     NAME
          keypad - enable keypad

     SYNTAX
          keypad(win, bf)
          WINDOW *win;
          bool bf;

     DESCRIPTION
	  This option enables the keypad of the user's terminal.  If
          the keypad is enabled, pressing a function key (such as an
          arrow key) will return a single value representing the
          function key.  For example, pressing the left arrow key
          results in the value KEY_LEFT being returned..  For more
          information see the Guide to Curses Screen-Handling.  The
          routine is used to return the character.  If the keypad is
          disabled, does not treat function keys as special keys and
          the program interprets the escape sequences itself.  Keypad
          layout is terminal dependent; some terminals do not even
          have a keypad.

     SEE ALSO
          getch(3cur)
          Guide to Curses Screen-Handling

Note that KEY_LEFT and friends will not fit in an ordinary character,
so make sure getch's result is stored in an int.

If your curses is still based on the Berkeley curses, you have my
sympathies.  This is one area where System V is better than BSD.
--
Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

Do apple growers tell their kids money doesn't grow on bushes?

kimcm@diku.dk (Kim Christian Madsen) (08/27/90)

mlake@irscscm.UUCP (Marshall Lake) writes:


>I am writing a program which will be taking advantage of curses.  I am
>trying to utilize the arrow keys and am confused (actually all of
>curses confuses me).  I am doing a getch () and if I get an ESCAPE I do
>another getch ().  If I addch () for each character I get (the ESCAPE
>and the next character) then the cursor moves around properly on the
>screen but the x/y coordinates in the window structure do not follow
>suit.  Curses is recognizing the arrow keys simply as regular
>characters.  Am I naive in thinking that curses is smart enough to
>handle the arrow keys specially?  Should I be moving the cursor
>manually via the move function?

>I'm really not sure I know what I'm talking about when it comes to
>curses so any help is appreciated.

In the following I suppose that you have System V curses, I'm no real
expert on BSD curses.

The method you're using to catch the arrow-keys will work only if you
know exactly what the arrow-keys send, but hopefully they're described
properly in your terminfo database, so you could get the information
from there and parse it. But a better way to handle this situation is
using the following approach (I assume that we're using stdscr (the
default window).

	...
	initscr();		/* Enable curses */
	keypad(stdscr,TRUE);	/* Enable function-keys */
	noecho();		/* Do not echo typed input on screen */
	...
	switch (ch=getch()) {
	case KEY_DOWN:		/* Down arrow pressed */
		....
		break;
	case KEY_UP:		/* Up arrow pressed */
		...
		break;
	case KEY_LEFT:		/* Left arrow pressed */
		...
		break;
	case KEY_RIGHT:		/* Right arrow pressed */
		...
		break;
	default:
		if ((ch & A_CHARTEXT) != ch) 
			/* Function key was pressed */
		else	/* Normal character read */
		break;
	}

This answers your first question, I hope, as for your second question,
whether you have to move the cursor manually, after determining that
an arrow key has been pressed. The answer is YES! And the reason is
obvious, first only you know that it was an arrow key to curses it was
only a sequence of characters. Remember that almost every terminal of
a different brand has differing escape sequences associated with the
function keys (including arrow keys). Another vital reason for curses
to expect you to decide what to do when an arrow-key is pressed, is
that you might not always want it just to move the cursor on the
screen, you might want to bind the functionality of pulling a menu
down, when you hit the down arrow and then in the menu using it to go
to the next menu item, or you might want another functionality the
authors of curses never dreamed about, even in their nightmares, when
designing the system. So the bottom line is: Yes you can easily detect
when a function key has been pressed, but then you must decide what
you want to do with that information.

					Best Regards
					Kim Chr. Madsen

		

jxf@procyon.cis.ksu.edu (Jerry Frain) (08/27/90)

In article <773@studsys.mu.edu>, jetzer@studsys.mu.edu (Mike Jetzer) writes:
> In article <1990Aug24.175453.4310@irscscm.UUCP> mlake@irscscm.UUCP
(Marshall Lake) writes:
>>I am writing a program which will be taking advantage of curses.
> [ . . . ]
>>I am doing a getch () and if I get an ESCAPE I do
>>another getch ().  If I addch () for each character I get (the ESCAPE
>>and the next character) then the cursor moves around properly on the
>>screen but the x/y coordinates in the window structure do not follow
>>suit.  Curses is recognizing the arrow keys simply as regular
>>characters.  Am I naive in thinking that curses is smart enough to
>>handle the arrow keys specially?  Should I be moving the cursor
>>manually via the move function?
> 
> Your naivete could be corrected by reading the manpage on curses.

Unless Marshall is using BSD curses.  I, also, am writing an application
which requires the use of arrow keys, but I am using BSD curses.  There
is nothing in the man page about using the arrow keys, because there is
no keypad() function, and hence no standardized way of using the arrow
keys with BSD curses.

I be able to answer Marshall's questions (relative to Berkeley curses) in
the next week or so, as soon as I do a little more research into this
dilemma.  If anyone is interested, I will post what I find.

--
Jerry Frain -- Perpetual Student		Kansas State University
                                 	Department of Computing & Info Sciences
Internet : jxf@ksuvax1.cis.ksu.edu                Manhattan, Kansas
UUCP     : ...!{rutgers,textbell}!ksuvax1!jxf

mlake@irscscm.UUCP (Marshall Lake) (08/27/90)

In article <773@studsys.mu.edu> jetzer@studsys.UUCP (Mike Jetzer) writes:
>In article <1990Aug24.175453.4310@irscscm.UUCP> mlake@irscscm.UUCP (Marshall Lake) writes:
>>[questions about using the arrow keys with curses]

>Your naivete could be corrected by reading the manpage on curses.
>
>Performing a keypad() will enable the keypad on most terminals, and when
>the user presses an arrow key, the return value will be KEY_DOWN, KEY_UP,
>etc.  You can then take the proper action based on the key that the
>user actually pressed.
>
>
>-- 
>Mike Jetzer
>"And we'll have fun, fun, fun until Daddy takes the keyboard awa-ay..."


I failed to mention that I'm using ucb curses.  I believe keypad() is a
function of att curses.  Is there some way of simulating att keypad()
in the ucb environment?

-- 
Marshall Lake
mlake@irscscm.UUCP
...!uunet!media!ka3ovk!irscscm!mlake

mlake@irscscm.UUCP (Marshall Lake) (08/28/90)

In article <MEISSNER.90Aug26173207@osf.osf.org> meissner@osf.org (Michael Meissner) writes:
>In article <1990Aug24.175453.4310@irscscm.UUCP> mlake@irscscm.UUCP
>(Marshall Lake) writes:
>
>| [Question about using arrow keys with curses]

>[Docs for keypad ()]
>
>Note that KEY_LEFT and friends will not fit in an ordinary character,
>so make sure getch's result is stored in an int.
>
>If your curses is still based on the Berkeley curses, you have my
>sympathies.  This is one area where System V is better than BSD.

Really?  Sympathies?!?!  That's all I can get using Berkeley curses?!
:<

>--
>Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
>Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142
>
>Do apple growers tell their kids money doesn't grow on bushes?

-- 
Marshall Lake
mlake@irscscm.UUCP
...!uunet!media!ka3ovk!irscscm!mlake