121257Sdist /*
2*63913Sbostic * Copyright (c) 1980, 1993
3*63913Sbostic * The Regents of the University of California. All rights reserved.
433692Sbostic *
542594Sbostic * %sccs.include.redist.c%
621257Sdist */
721257Sdist
813775Ssam #ifndef lint
9*63913Sbostic static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 07/19/93";
1033692Sbostic #endif /* not lint */
1113775Ssam
1213775Ssam /*************************************************************************
1313775Ssam *
1413775Ssam * MOVE LIBRARY
1513775Ssam *
1613775Ssam * This set of subroutines moves a cursor to a predefined
1713775Ssam * location, independent of the terminal type. If the
1813775Ssam * terminal has an addressable cursor, it uses it. If
1913775Ssam * not, it optimizes for tabs (currently) even if you don't
2013775Ssam * have them.
2113775Ssam *
2213775Ssam * At all times the current address of the cursor must be maintained,
2313775Ssam * and that is available as structure cursor.
2413775Ssam *
2513775Ssam * The following calls are allowed:
2613775Ssam * move(sp) move to point sp.
2713775Ssam * up() move up one line.
2813775Ssam * down() move down one line.
2913775Ssam * bs() move left one space (except column 0).
3013775Ssam * nd() move right one space(no write).
3113775Ssam * clear() clear screen.
3213775Ssam * home() home.
3313775Ssam * ll() move to lower left corner of screen.
3413775Ssam * cr() carriage return (no line feed).
3546760Sbostic * pr() just like standard printf, but keeps track
3613775Ssam * of cursor position. (Uses pstring).
3746760Sbostic * apr() same as printf, but first argument is &point.
3813775Ssam * (Uses pstring).
3913775Ssam * pstring(s) output the string of printing characters.
4013775Ssam * However, '\r' is interpreted to mean return
4113775Ssam * to column of origination AND do linefeed.
4213775Ssam * '\n' causes <cr><lf>.
4313775Ssam * putpad(str) calls tputs to output character with proper
4413775Ssam * padding.
4513775Ssam * outch() the output routine for a character used by
4613775Ssam * tputs. It just calls putchar.
4713775Ssam * pch(ch) output character to screen and update
4813775Ssam * cursor address (must be a standard
4913775Ssam * printing character). WILL SCROLL.
5013775Ssam * pchar(ps,ch) prints one character if it is on the
5113775Ssam * screen at the specified location;
5213775Ssam * otherwise, dumps it.(no wrap-around).
5313775Ssam *
5413775Ssam * getcap() initializes strings for later calls.
5513775Ssam * cap(string) outputs the string designated in the termcap
5613775Ssam * data base. (Should not move the cursor.)
5734027Sbostic * done() returns the terminal to intial state and exits.
5813775Ssam *
5913775Ssam * point(&p,x,y) return point set to x,y.
6013775Ssam *
6113775Ssam * baudrate(x) returns the baudrate of the terminal.
6213775Ssam * delay(t) causes an approximately constant delay
6313775Ssam * independent of baudrate.
6413775Ssam * Duration is ~ t/20 seconds.
6513775Ssam *
6613775Ssam ******************************************************************************/
6713775Ssam
6852541Storek #if __STDC__
6946760Sbostic #include <stdarg.h>
7052541Storek #else
7152541Storek #include <varargs.h>
7252541Storek #endif
7313775Ssam #include "snake.h"
7413775Ssam
7513775Ssam int CMlength;
7613775Ssam int NDlength;
7713775Ssam int BSlength;
7813775Ssam int delaystr[10];
7913775Ssam short ospeed;
8013775Ssam
8113775Ssam static char str[80];
8213775Ssam
8313775Ssam move(sp)
8413775Ssam struct point *sp;
8513775Ssam {
8613775Ssam int distance;
8713775Ssam int tabcol,ct;
8813775Ssam struct point z;
8913775Ssam
9013775Ssam if (sp->line <0 || sp->col <0 || sp->col > COLUMNS){
9146760Sbostic pr("move to [%d,%d]?",sp->line,sp->col);
9213775Ssam return;
9313775Ssam }
9413775Ssam if (sp->line >= LINES){
9513775Ssam move(point(&z,sp->col,LINES-1));
9613775Ssam while(sp->line-- >= LINES)putchar('\n');
9713775Ssam return;
9813775Ssam }
9913775Ssam
10013775Ssam if (CM != 0) {
10113775Ssam char *cmstr = tgoto(CM, sp->col, sp->line);
10213775Ssam
10313775Ssam CMlength = strlen(cmstr);
10413775Ssam if(cursor.line == sp->line){
10513775Ssam distance = sp->col - cursor.col;
10613775Ssam if(distance == 0)return; /* Already there! */
10713775Ssam if(distance > 0){ /* Moving to the right */
10813775Ssam if(distance*NDlength < CMlength){
10913775Ssam right(sp);
11013775Ssam return;
11113775Ssam }
11213775Ssam if(TA){
11313775Ssam ct=sp->col&7;
11413775Ssam tabcol=(cursor.col|7)+1;
11513775Ssam do{
11613775Ssam ct++;
11713775Ssam tabcol=(tabcol|7)+1;
11813775Ssam }
11913775Ssam while(tabcol<sp->col);
12013775Ssam if(ct<CMlength){
12113775Ssam right(sp);
12213775Ssam return;
12313775Ssam }
12413775Ssam }
12513775Ssam } else { /* Moving to the left */
12613775Ssam if (-distance*BSlength < CMlength){
12713775Ssam gto(sp);
12813775Ssam return;
12913775Ssam }
13013775Ssam }
13113775Ssam if(sp->col < CMlength){
13213775Ssam cr();
13313775Ssam right(sp);
13413775Ssam return;
13513775Ssam }
13613775Ssam /* No more optimizations on same row. */
13713775Ssam }
13813775Ssam distance = sp->col - cursor.col;
13913775Ssam distance = distance > 0 ?
14013775Ssam distance*NDlength : -distance * BSlength;
14146760Sbostic if (distance < 0)
14246760Sbostic pr("ERROR: distance is negative: %d",distance);
14313775Ssam distance += abs(sp->line - cursor.line);
14413775Ssam if(distance >= CMlength){
14513775Ssam putpad(cmstr);
14613775Ssam cursor.line = sp->line;
14713775Ssam cursor.col = sp->col;
14813775Ssam return;
14913775Ssam }
15013775Ssam }
15113775Ssam
15213775Ssam /*
15313775Ssam * If we get here we have a terminal that can't cursor
15413775Ssam * address but has local motions or one which can cursor
15513775Ssam * address but can get there quicker with local motions.
15613775Ssam */
15713775Ssam gto(sp);
15813775Ssam }
15913775Ssam gto(sp)
16013775Ssam struct point *sp;
16113775Ssam {
16213775Ssam
16313775Ssam int distance,f,tfield,j;
16413775Ssam
16513775Ssam if (cursor.line > LINES || cursor.line <0 ||
16613775Ssam cursor.col <0 || cursor.col > COLUMNS)
16746760Sbostic pr("ERROR: cursor is at %d,%d\n",
16813775Ssam cursor.line,cursor.col);
16913775Ssam if (sp->line > LINES || sp->line <0 ||
17013775Ssam sp->col <0 || sp->col > COLUMNS)
17146760Sbostic pr("ERROR: target is %d,%d\n",sp->line,sp->col);
17213775Ssam tfield = (sp->col) >> 3;
17313775Ssam if (sp->line == cursor.line){
17413775Ssam if (sp->col > cursor.col)right(sp);
17513775Ssam else{
17613775Ssam distance = (cursor.col -sp->col)*BSlength;
17713775Ssam if (((TA) &&
17813775Ssam (distance > tfield+((sp->col)&7)*NDlength)
17913775Ssam ) ||
18013775Ssam (((cursor.col)*NDlength) < distance)
18113775Ssam ){
18213775Ssam cr();
18313775Ssam right(sp);
18413775Ssam }
18513775Ssam else{
18613775Ssam while(cursor.col > sp->col) bs();
18713775Ssam }
18813775Ssam }
18913775Ssam return;
19013775Ssam }
19113775Ssam /*must change row */
19213775Ssam if (cursor.col - sp->col > (cursor.col >> 3)){
19313775Ssam if (cursor.col == 0)f = 0;
19413775Ssam else f = -1;
19513775Ssam }
19613775Ssam else f = cursor.col >> 3;
19713775Ssam if (((sp->line << 1) + 1 < cursor.line - f) && (HO != 0)){
19813775Ssam /*
19913775Ssam * home quicker than rlf:
20013775Ssam * (sp->line + f > cursor.line - sp->line)
20113775Ssam */
20213775Ssam putpad(HO);
20313775Ssam cursor.col = cursor.line = 0;
20413775Ssam gto(sp);
20513775Ssam return;
20613775Ssam }
20713775Ssam if (((sp->line << 1) > cursor.line + LINES+1 + f) && (LL != 0)){
20813775Ssam /* home,rlf quicker than lf
20913775Ssam * (LINES+1 - sp->line + f < sp->line - cursor.line)
21013775Ssam */
21113775Ssam if (cursor.line > f + 1){
21213775Ssam /* is home faster than wraparound lf?
21313775Ssam * (cursor.line + 20 - sp->line > 21 - sp->line + f)
21413775Ssam */
21513775Ssam ll();
21613775Ssam gto(sp);
21713775Ssam return;
21813775Ssam }
21913775Ssam }
22013775Ssam if ((LL != 0) && (sp->line > cursor.line + (LINES >> 1) - 1))
22113775Ssam cursor.line += LINES;
22213775Ssam while(sp->line > cursor.line)down();
22313775Ssam while(sp->line < cursor.line)up();
22413775Ssam gto(sp); /*can recurse since cursor.line = sp->line */
22513775Ssam }
22613775Ssam
22713775Ssam right(sp)
22813775Ssam struct point *sp;
22913775Ssam {
23013775Ssam int field,tfield;
23113775Ssam int tabcol,strlength;
23213775Ssam
23313775Ssam if (sp->col < cursor.col)
23446760Sbostic pr("ERROR:right() can't move left\n");
23513775Ssam if(TA){ /* If No Tabs: can't send tabs because ttydrive
23613775Ssam * loses count with control characters.
23713775Ssam */
23813775Ssam field = cursor.col >> 3;
23913775Ssam /*
24013775Ssam * This code is useful for a terminal which wraps around on backspaces.
24113775Ssam * (Mine does.) Unfortunately, this is not specified in termcap, and
24213775Ssam * most terminals don't work that way. (Of course, most terminals
24313775Ssam * have addressible cursors, too).
24413775Ssam */
24513775Ssam if (BW && (CM == 0) &&
24613775Ssam ((sp->col << 1) - field > (COLUMNS - 8) << 1 )
24713775Ssam ){
24813775Ssam if (cursor.line == 0){
24913775Ssam outch('\n');
25013775Ssam }
25113775Ssam outch('\r');
25213775Ssam cursor.col = COLUMNS + 1;
25313775Ssam while(cursor.col > sp->col)bs();
25413775Ssam if (cursor.line != 0) outch('\n');
25513775Ssam return;
25613775Ssam }
25713775Ssam
25813775Ssam tfield = sp->col >> 3;
25913775Ssam
26013775Ssam while (field < tfield){
26113775Ssam putpad(TA);
26213775Ssam cursor.col = ++field << 3;
26313775Ssam }
26413775Ssam tabcol = (cursor.col|7) + 1;
26513775Ssam strlength = (tabcol - sp->col)*BSlength + 1;
26613775Ssam /* length of sequence to overshoot */
26713775Ssam if (((sp->col - cursor.col)*NDlength > strlength) &&
26813775Ssam (tabcol < COLUMNS)
26913775Ssam ){
27013775Ssam /*
27113775Ssam * Tab past and backup
27213775Ssam */
27313775Ssam putpad(TA);
27413775Ssam cursor.col = (cursor.col | 7) + 1;
27513775Ssam while(cursor.col > sp->col)bs();
27613775Ssam }
27713775Ssam }
27813775Ssam while (sp->col > cursor.col){
27913775Ssam nd();
28013775Ssam }
28113775Ssam }
28213775Ssam
cr()28313775Ssam cr(){
28413775Ssam outch('\r');
28513775Ssam cursor.col = 0;
28613775Ssam }
28713775Ssam
clear()28813775Ssam clear(){
28913775Ssam int i;
29013775Ssam
29113775Ssam if (CL){
29213775Ssam putpad(CL);
29313775Ssam cursor.col=cursor.line=0;
29413775Ssam } else {
29513775Ssam for(i=0; i<LINES; i++) {
29613775Ssam putchar('\n');
29713775Ssam }
29813775Ssam cursor.line = LINES - 1;
29913775Ssam home();
30013775Ssam }
30113775Ssam }
30213775Ssam
home()30313775Ssam home(){
30413775Ssam struct point z;
30513775Ssam
30613775Ssam if(HO != 0){
30713775Ssam putpad(HO);
30813775Ssam cursor.col = cursor.line = 0;
30913775Ssam return;
31013775Ssam }
31113775Ssam z.col = z.line = 0;
31213775Ssam move(&z);
31313775Ssam }
31413775Ssam
ll()31513775Ssam ll(){
31613775Ssam int j,l;
31713775Ssam struct point z;
31813775Ssam
31913775Ssam l = lcnt + 2;
32013775Ssam if(LL != NULL && LINES==l){
32113775Ssam putpad(LL);
32213775Ssam cursor.line = LINES-1;
32313775Ssam cursor.col = 0;
32413775Ssam return;
32513775Ssam }
32613775Ssam z.col = 0;
32713775Ssam z.line = l-1;
32813775Ssam move(&z);
32913775Ssam }
33013775Ssam
up()33113775Ssam up(){
33213775Ssam putpad(UP);
33313775Ssam cursor.line--;
33413775Ssam }
33513775Ssam
down()33613775Ssam down(){
33713775Ssam putpad(DO);
33813775Ssam cursor.line++;
33913775Ssam if (cursor.line >= LINES)cursor.line=LINES-1;
34013775Ssam }
bs()34113775Ssam bs(){
34213775Ssam if (cursor.col > 0){
34313775Ssam putpad(BS);
34413775Ssam cursor.col--;
34513775Ssam }
34613775Ssam }
34713775Ssam
nd()34813775Ssam nd(){
34913775Ssam putpad(ND);
35013775Ssam cursor.col++;
35113775Ssam if (cursor.col == COLUMNS+1){
35213775Ssam cursor.line++;
35313775Ssam cursor.col = 0;
35413775Ssam if (cursor.line >= LINES)cursor.line=LINES-1;
35513775Ssam }
35613775Ssam }
35713775Ssam
pch(c)35813775Ssam pch(c)
35913775Ssam {
36013775Ssam outch(c);
36113775Ssam if(++cursor.col >= COLUMNS && AM) {
36213775Ssam cursor.col = 0;
36313775Ssam ++cursor.line;
36413775Ssam }
36513775Ssam }
36613775Ssam
36757832Storek void
36852541Storek #if __STDC__
apr(struct point * ps,const char * fmt,...)36957832Storek apr(struct point *ps, const char *fmt, ...)
37052541Storek #else
37152541Storek apr(ps, fmt, va_alist)
37246760Sbostic struct point *ps;
37346760Sbostic char *fmt;
37452541Storek va_dcl
37552541Storek #endif
37613775Ssam {
37713775Ssam struct point p;
37846760Sbostic va_list ap;
37913775Ssam
38013775Ssam p.line = ps->line+1; p.col = ps->col+1;
38113775Ssam move(&p);
38252541Storek #if __STDC__
38346760Sbostic va_start(ap, fmt);
38452541Storek #else
38552541Storek va_start(ap);
38652541Storek #endif
38746760Sbostic (void)vsprintf(str, fmt, ap);
38846760Sbostic va_end(ap);
38913775Ssam pstring(str);
39013775Ssam }
39113775Ssam
39257832Storek void
39352541Storek #if __STDC__
pr(const char * fmt,...)39457832Storek pr(const char *fmt, ...)
39552541Storek #else
39652541Storek pr(fmt, va_alist)
39746760Sbostic char *fmt;
39852541Storek va_dcl
39952541Storek #endif
40013775Ssam {
40146760Sbostic va_list ap;
40246760Sbostic
40352541Storek #if __STDC__
40446760Sbostic va_start(ap, fmt);
40552541Storek #else
40652541Storek va_start(ap);
40752541Storek #endif
40846760Sbostic (void)vsprintf(str, fmt, ap);
40946760Sbostic va_end(ap);
41013775Ssam pstring(str);
41113775Ssam }
41213775Ssam
pstring(s)41313775Ssam pstring(s)
41413775Ssam char *s;{
41513775Ssam struct point z;
41613775Ssam int stcol;
41713775Ssam
41813775Ssam stcol = cursor.col;
41913775Ssam while (s[0] != '\0'){
42013775Ssam switch (s[0]){
42113775Ssam case '\n':
42213775Ssam move(point(&z,0,cursor.line+1));
42313775Ssam break;
42413775Ssam case '\r':
42513775Ssam move(point(&z,stcol,cursor.line+1));
42613775Ssam break;
42713775Ssam case '\t':
42813775Ssam z.col = (((cursor.col + 8) >> 3) << 3);
42913775Ssam z.line = cursor.line;
43013775Ssam move(&z);
43113775Ssam break;
43213775Ssam case '\b':
43313775Ssam bs();
43413775Ssam break;
43533114Sbostic case CTRL('g'):
43633114Sbostic outch(CTRL('g'));
43713775Ssam break;
43813775Ssam default:
43913775Ssam if (s[0] < ' ')break;
44013775Ssam pch(s[0]);
44113775Ssam }
44213775Ssam s++;
44313775Ssam }
44413775Ssam }
44513775Ssam
44613775Ssam pchar(ps,ch)
44713775Ssam struct point *ps;
44813775Ssam char ch;{
44913775Ssam struct point p;
45013775Ssam p.col = ps->col + 1; p.line = ps->line + 1;
45113775Ssam if (
45213775Ssam (p.col >= 0) &&
45313775Ssam (p.line >= 0) &&
45413775Ssam (
45513775Ssam (
45613775Ssam (p.line < LINES) &&
45713775Ssam (p.col < COLUMNS)
45813775Ssam ) ||
45913775Ssam (
46013775Ssam (p.col == COLUMNS) &&
46113775Ssam (p.line < LINES-1)
46213775Ssam )
46313775Ssam )
46413775Ssam ){
46513775Ssam move(&p);
46613775Ssam pch(ch);
46713775Ssam }
46813775Ssam }
46913775Ssam
47013775Ssam
outch(c)47113775Ssam outch(c)
47213775Ssam {
47313775Ssam putchar(c);
47413775Ssam }
47513775Ssam
putpad(str)47613775Ssam putpad(str)
47713775Ssam char *str;
47813775Ssam {
47913775Ssam if (str)
48013775Ssam tputs(str, 1, outch);
48113775Ssam }
baudrate()48213775Ssam baudrate()
48313775Ssam {
48413775Ssam
48513775Ssam switch (orig.sg_ospeed){
48613775Ssam case B300:
48713775Ssam return(300);
48813775Ssam case B1200:
48913775Ssam return(1200);
49013775Ssam case B4800:
49113775Ssam return(4800);
49213775Ssam case B9600:
49313775Ssam return(9600);
49413775Ssam default:
49513775Ssam return(0);
49613775Ssam }
49713775Ssam }
delay(t)49813775Ssam delay(t)
49913775Ssam int t;
50013775Ssam {
50113775Ssam int k,j;
50213775Ssam
50313775Ssam k = baudrate() * t / 300;
50413775Ssam for(j=0;j<k;j++){
50513775Ssam putchar(PC);
50613775Ssam }
50713775Ssam }
50813775Ssam
done()50913775Ssam done()
51013775Ssam {
51113775Ssam cook();
51213775Ssam exit(0);
51313775Ssam }
51413775Ssam
cook()51513775Ssam cook()
51613775Ssam {
51713775Ssam delay(1);
51813775Ssam putpad(TE);
51913775Ssam putpad(KE);
52013775Ssam fflush(stdout);
52113775Ssam stty(0, &orig);
52213775Ssam #ifdef TIOCSLTC
52313775Ssam ioctl(0, TIOCSLTC, &olttyc);
52413775Ssam #endif
52513775Ssam }
52613775Ssam
raw()52713775Ssam raw()
52813775Ssam {
52913775Ssam stty(0, &new);
53013775Ssam #ifdef TIOCSLTC
53113775Ssam ioctl(0, TIOCSLTC, &nlttyc);
53213775Ssam #endif
53313775Ssam }
53413775Ssam
point(ps,x,y)53513775Ssam struct point *point(ps,x,y)
53613775Ssam struct point *ps;
53713775Ssam int x,y;
53813775Ssam {
53913775Ssam ps->col=x;
54013775Ssam ps->line=y;
54113775Ssam return(ps);
54213775Ssam }
54313775Ssam
54413775Ssam char *ap;
54513775Ssam
getcap()54613775Ssam getcap()
54713775Ssam {
54813775Ssam char *getenv();
54913775Ssam char *term;
55013775Ssam char *xPC;
55113775Ssam struct point z;
55246760Sbostic void stop();
55363912Sbostic #ifdef TIOCGWINSZ
55463912Sbostic struct winsize win;
55563912Sbostic #endif
55613775Ssam
55713775Ssam term = getenv("TERM");
55813775Ssam if (term==0) {
55913775Ssam fprintf(stderr, "No TERM in environment\n");
56013775Ssam exit(1);
56113775Ssam }
56213775Ssam
56313775Ssam switch (tgetent(tbuf, term)) {
56413775Ssam case -1:
56513775Ssam fprintf(stderr, "Cannot open termcap file\n");
56613775Ssam exit(2);
56713775Ssam case 0:
56813775Ssam fprintf(stderr, "%s: unknown terminal", term);
56913775Ssam exit(3);
57013775Ssam }
57113775Ssam
57213775Ssam ap = tcapbuf;
57313775Ssam
57463912Sbostic #ifdef TIOCGWINSZ
57563912Sbostic if (ioctl(0, TIOCGWINSZ, (char *) &win) < 0 ||
57663912Sbostic (LINES = win.ws_row) == 0 || (COLUMNS = win.ws_col) == 0) {
57763912Sbostic #endif
57863912Sbostic LINES = tgetnum("li");
57963912Sbostic COLUMNS = tgetnum("co");
58063912Sbostic #ifdef TIOCGWINSZ
58163912Sbostic }
58263912Sbostic #endif
58334027Sbostic if (!lcnt)
58434027Sbostic lcnt = LINES - 2;
58534027Sbostic if (!ccnt)
58634027Sbostic ccnt = COLUMNS - 3;
58713775Ssam
58813775Ssam AM = tgetflag("am");
58913775Ssam BW = tgetflag("bw");
59013775Ssam
59113775Ssam ND = tgetstr("nd", &ap);
59213775Ssam UP = tgetstr("up", &ap);
59313775Ssam
59413775Ssam DO = tgetstr("do", &ap);
59513775Ssam if (DO == 0)
59613775Ssam DO = "\n";
59713775Ssam
59813775Ssam BS = tgetstr("bc", &ap);
59913775Ssam if (BS == 0 && tgetflag("bs"))
60013775Ssam BS = "\b";
60113775Ssam if (BS)
60213775Ssam xBC = *BS;
60313775Ssam
60413775Ssam TA = tgetstr("ta", &ap);
60513775Ssam if (TA == 0 && tgetflag("pt"))
60613775Ssam TA = "\t";
60713775Ssam
60813775Ssam HO = tgetstr("ho", &ap);
60913775Ssam CL = tgetstr("cl", &ap);
61013775Ssam CM = tgetstr("cm", &ap);
61113775Ssam LL = tgetstr("ll", &ap);
61213775Ssam
61313775Ssam KL = tgetstr("kl", &ap);
61413775Ssam KR = tgetstr("kr", &ap);
61513775Ssam KU = tgetstr("ku", &ap);
61613775Ssam KD = tgetstr("kd", &ap);
61713775Ssam Klength = strlen(KL);
61813775Ssam /* NOTE: If KL, KR, KU, and KD are not
61913775Ssam * all the same length, some problems
62013775Ssam * may arise, since tests are made on
62113775Ssam * all of them together.
62213775Ssam */
62313775Ssam
62413775Ssam TI = tgetstr("ti", &ap);
62513775Ssam TE = tgetstr("te", &ap);
62613775Ssam KS = tgetstr("ks", &ap);
62713775Ssam KE = tgetstr("ke", &ap);
62813775Ssam
62913775Ssam xPC = tgetstr("pc", &ap);
63013775Ssam if (xPC)
63113775Ssam PC = *xPC;
63213775Ssam
63313775Ssam NDlength = strlen(ND);
63413775Ssam BSlength = strlen(BS);
63513775Ssam if ((CM == 0) &&
63613775Ssam (HO == 0 | UP==0 || BS==0 || ND==0)) {
63713775Ssam fprintf(stderr, "Terminal must have addressible ");
63813775Ssam fprintf(stderr, "cursor or home + 4 local motions\n");
63913775Ssam exit(5);
64013775Ssam }
64113775Ssam if (tgetflag("os")) {
64213775Ssam fprintf(stderr, "Terminal must not overstrike\n");
64313775Ssam exit(5);
64413775Ssam }
64513775Ssam if (LINES <= 0 || COLUMNS <= 0) {
64613775Ssam fprintf(stderr, "Must know the screen size\n");
64713775Ssam exit(5);
64813775Ssam }
64913775Ssam
65013775Ssam gtty(0, &orig);
65113775Ssam new=orig;
65213775Ssam new.sg_flags &= ~(ECHO|CRMOD|ALLDELAY|XTABS);
65313775Ssam new.sg_flags |= CBREAK;
65413775Ssam signal(SIGINT,stop);
65513775Ssam ospeed = orig.sg_ospeed;
65613775Ssam #ifdef TIOCGLTC
65713775Ssam ioctl(0, TIOCGLTC, &olttyc);
65813775Ssam nlttyc = olttyc;
65913775Ssam nlttyc.t_suspc = '\377';
66013775Ssam nlttyc.t_dsuspc = '\377';
66113775Ssam #endif
66213775Ssam raw();
66313775Ssam
66413775Ssam if ((orig.sg_flags & XTABS) == XTABS) TA=0;
66513775Ssam putpad(KS);
66613775Ssam putpad(TI);
66713775Ssam point(&cursor,0,LINES-1);
66813775Ssam }
669