[comp.lang.c] Unix Routines

pm0@springs.cis.ufl.edu (Patrick Martin) (01/13/91)

Could someone tell me how to do the following on a Unix System:

Up() {will move the Cursor up 1 position}
Down() { ... down ...}
Left() { ... left ...}
Right() { ... right ...}

Clear {Clears the Screen leaving the cursor at position 0,0}
Home {Moves the cursor to 0,0 without clearing the screen}

Maybe I am being a little optimistic but a routine:
Cursor(x,y) which would move the cursor to screen location
x,y would be MOST helpful.

It seems when I press the cursor keys the ascii translation
is Escape then Another key.  If someone can explain just what
is happening I would be most appreciative.

PS:  I know I could use a system call to clear the screen but
I would prefer sending the direct ascii code to a printf
statement.

Thanks Alot,
Pat Martin

jpr@jpradley.jpr.com (Jean-Pierre Radley) (01/14/91)

In article <26284@uflorida.cis.ufl.EDU> pm0@springs.cis.ufl.edu (Patrick Martin) writes:
>Could someone tell me how to do the following on a Unix System:
>
>Up() {will move the Cursor up 1 position}
>Down() { ... down ...}
>Left() { ... left ...}
>Right() { ... right ...}
>

The required code is highly dependent on your hardware. 
Check out termcap, terminfo, tgetent, tput, and other such entries in your
manual.
In fact, just browing through /etc/termcap, or /usr/lib/terminfo/*src, will
show you that the code sequences you seek are quite variable.

Your system's C libraries give you tools to find the codes for any
given terminal; you then incorporate them into your code so as to be
device-independent.
-- 

 Jean-Pierre Radley	    NYC Public Unix	jpr@jpr.com	CIS: 72160,1341

mike@bria.UUCP (Michael Stefanik) (01/14/91)

In article <26284@uflorida.cis.ufl.EDU> Patrick Martin writes:
>Could someone tell me how to do the following on a Unix System:

[ asks question about grabbing cursor keys, clearing the screen, etc. ]

This really belongs in comp.unix.programmer, but anyway ...
UNIX has a standard library called 'curses' which deals with screen
management and has reasonable optimization.  The fundamental concept
in curses is that you are working within a window, and that window
has various attributes.  How those attributes are translated into
actual output to your terminal is via a terminal capability database.
There are two flavors of database, the orginal being 'termcap' developed
at UC Berkeley.  The other flavor is 'terminfo' developed at AT&T, and
is a "compiled" database (termcap is a text file).  The good news is that
terminfo has compatability hooks with termcap, so you don't have to
worry too much about which implementation your system uses, unless you
*really* want to get down and dirty.

Here is a little chunk of code to do what you asked about:

#include <stdio.h>
#include <curses.h>

main()
{
char	*id;
int	c;

	initscr();
	cbreak();
	noecho();
	keypad(stdscr,TRUE);
	clear();
	refresh();

	while ( (c = getch()) != 27 ) {
		switch ( c ) {
			case KEY_UP:	id = "up"; 	break;
			case KEY_DOWN:	id = "down"; 	break;
			case KEY_LEFT:	id = "left"; 	break;
			case KEY_RIGHT: id = "right"; 	break;
			default:	id = "not special"; break;
			}
		mvprintw(0,0,"key press was %s",id);
		clrtoeol();
		refresh();
		}

	endwin();
}

Note a few things:

	1. The program begins with initscr(), which initializes the curses
	   environment, and is required.

	2. keypad(stdscr,TRUE) enables "keypad" mode, which is required
	   for curses to detect "special" keys, such as arrow keys and
	   function keys.  Cbreak() and noecho() are also useful when
	   you're doing this kind of work ...

	3. refresh() is used to cause the window buffer to be written to
	   the screen (think of it kind of like an fflush()); use it often.

	4. you'll notice that 'c' is of type int, *not* char.  Declaring
	   it as a char will have unpredictable results (and certainly won't
	   be what you want it to be).

	5. endwin() terminates the curses environment, and is required,
	   otherwise your terminal will be in a rather funky state (to
	   get back to normal, should this happen, enter the command:

			stty sane

	   and press the CTRL-J key (not the enter key, it probably won't
	   work for you).

Dig up some UNIX programming references, and look for the curses manual
pages.  All will be revealed.
-- 
Michael Stefanik, Systems Engineer (JOAT), Briareus Corporation
UUCP: ...!uunet!bria!mike
--
technoignorami (tek'no-ig'no-ram`i) a group of individuals that are constantly
found to be saying things like "Well, it works on my DOS machine ..."

pm0@springs.cis.ufl.edu (Patrick Martin) (01/14/91)

Thanks for the help and thanks for to all the people who
responded to my question.  Posting to this Newsgroup
sure does get results.

Pat

nto0302@dsacg3.dsac.dla.mil (Bob Fisher) (01/14/91)

From article <1991Jan13.163326.8246@jpradley.jpr.com], by jpr@jpradley.jpr.com (Jean-Pierre Radley):
] In article <26284@uflorida.cis.ufl.EDU] pm0@springs.cis.ufl.edu (Patrick Martin) writes:
]]Could someone tell me how to do the following on a Unix System:
]]
]]Up() {will move the Cursor up 1 position}
]]Down() { ... down ...}
]]Left() { ... left ...}
]]Right() { ... right ...}
]]
] 
] The required code is highly dependent on your hardware. 
] Check out termcap, terminfo, tgetent, tput, and other such entries in your
] manual.
] In fact, just browing through /etc/termcap, or /usr/lib/terminfo/*src, will
] show you that the code sequences you seek are quite variable.

Also check out the curses(3) library functions.

The reference to hardware dependency refers to terminals, not just the CPU.
Different brands of terminals on the same system may require different
command sequences.
-- 
Bob Fisher
US Defense Logistics Agency Systems Automation Center
DSAC-TOL, Box 1605, Columbus, OH 43216-5002     614-238-9071 (AV 850-9071)
bfisher@dsac.dla.mil		osu-cis!dsacg1!bfisher

hoepfner@usun01.UUCP (Andreas Hoepfner) (01/15/91)

In <26284@uflorida.cis.ufl.EDU> pm0@springs.cis.ufl.edu (Patrick Martin) writes:

>Could someone tell me how to do the following on a Unix System:

>Up() {will move the Cursor up 1 position}
>Down() { ... down ...}
>Left() { ... left ...}
>Right() { ... right ...}

>PS:  I know I could use a system call to clear the screen but
>I would prefer sending the direct ascii code to a printf
>statement.

Normaly, to do this on all possible terminal types, you should use
the curses library.

This is an easy way for vtxxx Terminals :

#define up()      printf("%cA",0x1b)
#define down()    printf("%cB",0x1b)
#define right()   printf("%cC",0x1b)
#define left()    printf("%cD",0x1b)
#define home()    printf("%cH",0x1b)
#define CLS     printf("\033[2J\033[H")
#define setcur(a,b) printf("\033[%d;%dH",a,b)
#define BELL    printf("%c",0x07)

 :-) Andreas


 +-----------------------------------------------------------------------+
 |                   Andreas Hoepfner                                    |
 |                                                                       |
 |     paper mail:                            e-mail:                    |
 | Siemens Nixdorf Informations                                          |
 | Systeme                        USA:  hoepfner.kd@nixdorf.com          |
 | Abt. PU 2222                   !USA: hoepfner.kd@nixdorf.de           |
 | Heinz Nixdorf Ring                                                    |
 | D-4790 Paderborn                                                      |
 | tel.: (+49) 5251 10-7479                                              |
 +-----------------------------------------------------------------------+

mike (Michael Stefanik) (01/16/91)

In article <2871@dsacg3.dsac.dla.mil> dsacg3.dsac.dla.mil!nto0302 (Bob Fisher) writes:
>From article <1991Jan13.163326.8246@jpradley.jpr.com], by jpr@jpradley.jpr.com (Jean-Pierre Radley):

	[ question about reading "special" keys in C under UNIX ]
>> 
>> The required code is highly dependent on your hardware. 
>> Check out termcap, terminfo, tgetent, tput, and other such entries in your
>> manual.
>> In fact, just browing through /etc/termcap, or /usr/lib/terminfo/*src, will
>> show you that the code sequences you seek are quite variable.
>
>Also check out the curses(3) library functions.
>
>The reference to hardware dependency refers to terminals, not just the CPU.
>Different brands of terminals on the same system may require different
>command sequences.

Actually, the code for this is very terminal *independant*; this is why
termcap/terminfo and the routines that are there exist.  The programmer
is isolated from the differences on terminal types, knowing that the curses
routines will perform the same function on different terminal type (unless
of course, the termcap entry is trashed).  Since most termcap/terminfo
sources have virtually every Tom, Dick, and Harry terminal made by Mankind
since the Dawn of Time, the applications programmer rarely has to worry
about writing his own cap entry.

BTW, I directed follow-ups to comp.unix.programmer, where this really
belongs ...
-- 
Michael Stefanik, Systems Engineer (JOAT), Briareus Corporation
UUCP: ...!uunet!bria!mike
--
technoignorami (tek'no-ig'no-ram`i) a group of individuals that are constantly
found to be saying things like "Well, it works on my DOS machine ..."