(linenum→info "unix/slp.c:2238")

bsd-games/2.17/hack/hack.termcap.c

    1: /*      $NetBSD: hack.termcap.c,v 1.12 2003/04/02 18:36:40 jsm Exp $ */
    2: /* For Linux: still using old termcap interface from version 1.9.  */
    3: 
    4: /*
    5:  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
    6:  * Amsterdam
    7:  * All rights reserved.
    8:  *
    9:  * Redistribution and use in source and binary forms, with or without
   10:  * modification, are permitted provided that the following conditions are
   11:  * met:
   12:  *
   13:  * - Redistributions of source code must retain the above copyright notice,
   14:  * this list of conditions and the following disclaimer.
   15:  *
   16:  * - Redistributions in binary form must reproduce the above copyright
   17:  * notice, this list of conditions and the following disclaimer in the
   18:  * documentation and/or other materials provided with the distribution.
   19:  *
   20:  * - Neither the name of the Stichting Centrum voor Wiskunde en
   21:  * Informatica, nor the names of its contributors may be used to endorse or
   22:  * promote products derived from this software without specific prior
   23:  * written permission.
   24:  *
   25:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   26:  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   27:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   28:  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   29:  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   30:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   31:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   32:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   34:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   35:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   36:  */
   37: 
   38: /*
   39:  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
   40:  * All rights reserved.
   41:  *
   42:  * Redistribution and use in source and binary forms, with or without
   43:  * modification, are permitted provided that the following conditions
   44:  * are met:
   45:  * 1. Redistributions of source code must retain the above copyright
   46:  *    notice, this list of conditions and the following disclaimer.
   47:  * 2. Redistributions in binary form must reproduce the above copyright
   48:  *    notice, this list of conditions and the following disclaimer in the
   49:  *    documentation and/or other materials provided with the distribution.
   50:  * 3. The name of the author may not be used to endorse or promote products
   51:  *    derived from this software without specific prior written permission.
   52:  *
   53:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   54:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   55:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   56:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   57:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   58:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   59:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   60:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   61:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   62:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   63:  */
   64: 
   65: #include <sys/cdefs.h>
   66: #ifndef lint
   67: __RCSID("$NetBSD: hack.termcap.c,v 1.12 2003/04/02 18:36:40 jsm Exp $");
   68: #endif                          /* not lint */
   69: 
   70: #include <string.h>
   71: #include <termios.h>
   72: #include <termcap.h>
   73: #include <stdlib.h>
   74: #include <unistd.h>
   75: #include "hack.h"
   76: #include "extern.h"
   77: #include "def.flag.h"           /* for flags.nonull */
   78: 
   79: static char     tbuf[512];
   80: char           *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
   81: static char    *VS, *VE;
   82: static int      SG;
   83: char            PC = '\0';
   84: char           *CD;             /* tested in pri.c: docorner() */
   85: int             CO, LI;         /* used in pri.c and whatis.c */
   86: 
   87: void
   88: startup()
   89: {
   90:         char           *term;
   91:         char           *tptr;
   92:         char           *tbufptr, *pc;
   93: 
   94:         tptr = (char *) alloc(1024);
   95: 
   96:         tbufptr = tbuf;
   97:         if (!(term = getenv("TERM")))
   98:                 error("Can't get TERM.");
   99:         if (!strncmp(term, "5620", 4))
  100:                 flags.nonull = 1;     /* this should be a termcap flag */
  101:         if (tgetent(tptr, term) < 1)
  102:                 error("Unknown terminal type: %s.", term);
  103:         if ((pc = tgetstr("pc", &tbufptr)) != NULL)
  104:                 PC = *pc;
  105:         if (!(BC = tgetstr("bc", &tbufptr))) {
  106:                 if (!tgetflag("bs"))
  107:                         error("Terminal must backspace.");
  108:                 BC = tbufptr;
  109:                 tbufptr += 2;
  110:                 *BC = '\b';
  111:         }
  112:         HO = tgetstr("ho", &tbufptr);
  113:         CO = tgetnum("co");
  114:         LI = tgetnum("li");
  115:         if (CO < COLNO || LI < ROWNO + 2)
  116:                 setclipped();
  117:         if (!(CL = tgetstr("cl", &tbufptr)))
  118:                 error("Hack needs CL.");
  119:         ND = tgetstr("nd", &tbufptr);
  120:         if (tgetflag("os"))
  121:                 error("Hack can't have OS.");
  122:         CE = tgetstr("ce", &tbufptr);
  123:         UP = tgetstr("up", &tbufptr);
  124:         /*
  125:          * It seems that xd is no longer supported, and we should use a
  126:          * linefeed instead; unfortunately this requires resetting CRMOD, and
  127:          * many output routines will have to be modified slightly. Let's
  128:          * leave that till the next release.
  129:          */
  130:         XD = tgetstr("xd", &tbufptr);
  131:         /* not:                XD = tgetstr("do", &tbufptr); */
  132:         if (!(CM = tgetstr("cm", &tbufptr))) {
  133:                 if (!UP && !HO)
  134:                         error("Hack needs CM or UP or HO.");
  135:                 printf("Playing hack on terminals without cm is suspect...\n");
  136:                 getret();
  137:         }
  138:         SO = tgetstr("so", &tbufptr);
  139:         SE = tgetstr("se", &tbufptr);
  140:         SG = tgetnum("sg");    /* -1: not fnd; else # of spaces left by so */
  141:         if (!SO || !SE || (SG > 0))
  142:                 SO = SE = 0;
  143:         CD = tgetstr("cd", &tbufptr);
  144:         set_whole_screen();    /* uses LI and CD */
  145:         if (tbufptr - tbuf > (int)sizeof(tbuf))
  146:                 error("TERMCAP entry too big...\n");
  147:         free(tptr);
  148: }
  149: 
  150: void
  151: start_screen()
  152: {
  153:         xputs(TI);
  154:         xputs(VS);
  155: }
  156: 
  157: void
  158: end_screen()
  159: {
  160:         xputs(VE);
  161:         xputs(TE);
  162: }
  163: 
  164: /* Cursor movements */
  165: void
  166: curs(x, y)
  167:         int             x, y;  /* not xchar: perhaps xchar is unsigned and
  168:                                  * curx-x would be unsigned as well */
  169: {
  170: 
  171:         if (y == cury && x == curx)
  172:                 return;
  173:         if (!ND && (curx != x || x <= 3)) {    /* Extremely primitive */
  174:                 cmov(x, y);   /* bunker!wtm */
  175:                 return;
  176:         }
  177:         if (abs(cury - y) <= 3 && abs(curx - x) <= 3)
  178:                 nocmov(x, y);
  179:         else if ((x <= 3 && abs(cury - y) <= 3) || (!CM && x < abs(curx - x))) {
  180:                 (void) putchar('\r');
  181:                 curx = 1;
  182:                 nocmov(x, y);
  183:         } else if (!CM) {
  184:                 nocmov(x, y);
  185:         } else
  186:                 cmov(x, y);
  187: }
  188: 
  189: void
  190: nocmov(x, y)
  191:         int x, y;
  192: {
  193:         if (cury > y) {
  194:                 if (UP) {
  195:                         while (cury > y) {   /* Go up. */
  196:                                 xputs(UP);
  197:                                 cury--;
  198:                         }
  199:                 } else if (CM) {
  200:                         cmov(x, y);
  201:                 } else if (HO) {
  202:                         home();
  203:                         curs(x, y);
  204:                 }             /* else impossible("..."); */
  205:         } else if (cury < y) {
  206:                 if (XD) {
  207:                         while (cury < y) {
  208:                                 xputs(XD);
  209:                                 cury++;
  210:                         }
  211:                 } else if (CM) {
  212:                         cmov(x, y);
  213:                 } else {
  214:                         while (cury < y) {
  215:                                 xputc('\n');
  216:                                 curx = 1;
  217:                                 cury++;
  218:                         }
  219:                 }
  220:         }
  221:         if (curx < x) {                /* Go to the right. */
  222:                 if (!ND)
  223:                         cmov(x, y);
  224:                 else          /* bah */
  225:                         /* should instead print what is there already */
  226:                         while (curx < x) {
  227:                                 xputs(ND);
  228:                                 curx++;
  229:                         }
  230:         } else if (curx > x) {
  231:                 while (curx > x) {    /* Go to the left. */
  232:                         xputs(BC);
  233:                         curx--;
  234:                 }
  235:         }
  236: }
  237: 
  238: void
  239: cmov(x, y)
  240:         int x, y;
  241: {
  242:         xputs(tgoto(CM, x - 1, y - 1));
  243:         cury = y;
  244:         curx = x;
  245: }
  246: 
  247: int
  248: xputc(c)
  249:         char            c;
  250: {
  251:         return (fputc(c, stdout));
  252: }
  253: 
  254: void
  255: xputs(s)
  256:         char           *s;
  257: {
  258:         tputs(s, 1, xputc);
  259: }
  260: 
  261: void
  262: cl_end()
  263: {
  264:         if (CE)
  265:                 xputs(CE);
  266:         else {                 /* no-CE fix - free after Harold Rynes */
  267:                 /*
  268:                  * this looks terrible, especially on a slow terminal but is
  269:                  * better than nothing
  270:                  */
  271:                 int cx = curx, cy = cury;
  272: 
  273:                 while (curx < COLNO) {
  274:                         xputc(' ');
  275:                         curx++;
  276:                 }
  277:                 curs(cx, cy);
  278:         }
  279: }
  280: 
  281: void
  282: clear_screen()
  283: {
  284:         xputs(CL);
  285:         curx = cury = 1;
  286: }
  287: 
  288: void
  289: home()
  290: {
  291:         if (HO)
  292:                 xputs(HO);
  293:         else if (CM)
  294:                 xputs(tgoto(CM, 0, 0));
  295:         else
  296:                 curs(1, 1);   /* using UP ... */
  297:         curx = cury = 1;
  298: }
  299: 
  300: void
  301: standoutbeg()
  302: {
  303:         if (SO)
  304:                 xputs(SO);
  305: }
  306: 
  307: void
  308: standoutend()
  309: {
  310:         if (SE)
  311:                 xputs(SE);
  312: }
  313: 
  314: void
  315: backsp()
  316: {
  317:         xputs(BC);
  318:         curx--;
  319: }
  320: 
  321: void
  322: bell()
  323: {
  324:         (void) putchar('\007');        /* curx does not change */
  325:         (void) fflush(stdout);
  326: }
  327: 
  328: void
  329: delay_output()
  330: {
  331: 
  332:         /* delay 50 ms - could also use a 'nap'-system call */
  333:           /* or the usleep call like this :-) */
  334:         usleep(50000);
  335: }
  336: 
  337: void
  338: cl_eos()
  339: {                               /* free after Robert Viduya *//* must only be
  340:                                  * called with curx = 1 */
  341: 
  342:         if (CD)
  343:                 xputs(CD);
  344:         else {
  345:                 int             cx = curx, cy = cury;
  346:                 while (cury <= LI - 2) {
  347:                         cl_end();
  348:                         xputc('\n');
  349:                         curx = 1;
  350:                         cury++;
  351:                 }
  352:                 cl_end();
  353:                 curs(cx, cy);
  354:         }
  355: }
Syntax (Markdown)