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

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

    1: /*      $NetBSD: hack.tty.c,v 1.12 2003/08/07 09:37:19 agc Exp $     */
    2: 
    3: /*-
    4:  * Copyright (c) 1988, 1993
    5:  *      The Regents of the University of California.  All rights reserved.
    6:  *
    7:  * Redistribution and use in source and binary forms, with or without
    8:  * modification, are permitted provided that the following conditions
    9:  * are met:
   10:  * 1. Redistributions of source code must retain the above copyright
   11:  *    notice, this list of conditions and the following disclaimer.
   12:  * 2. Redistributions in binary form must reproduce the above copyright
   13:  *    notice, this list of conditions and the following disclaimer in the
   14:  *    documentation and/or other materials provided with the distribution.
   15:  * 3. Neither the name of the University nor the names of its contributors
   16:  *    may be used to endorse or promote products derived from this software
   17:  *    without specific prior written permission.
   18:  *
   19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29:  * SUCH DAMAGE.
   30:  */
   31: 
   32: #include <sys/cdefs.h>
   33: #ifndef lint
   34: #if 0
   35: static char     sccsid[] = "@(#)hack.tty.c      8.1 (Berkeley) 5/31/93";
   36: #else
   37: __RCSID("$NetBSD: hack.tty.c,v 1.12 2003/08/07 09:37:19 agc Exp $");
   38: #endif
   39: #endif                          /* not lint */
   40: 
   41: /*
   42:  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
   43:  * Amsterdam
   44:  * All rights reserved.
   45:  *
   46:  * Redistribution and use in source and binary forms, with or without
   47:  * modification, are permitted provided that the following conditions are
   48:  * met:
   49:  *
   50:  * - Redistributions of source code must retain the above copyright notice,
   51:  * this list of conditions and the following disclaimer.
   52:  *
   53:  * - Redistributions in binary form must reproduce the above copyright
   54:  * notice, this list of conditions and the following disclaimer in the
   55:  * documentation and/or other materials provided with the distribution.
   56:  *
   57:  * - Neither the name of the Stichting Centrum voor Wiskunde en
   58:  * Informatica, nor the names of its contributors may be used to endorse or
   59:  * promote products derived from this software without specific prior
   60:  * written permission.
   61:  *
   62:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   63:  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   64:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   65:  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   66:  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   67:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   68:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   69:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   70:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   71:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   72:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   73:  */
   74: 
   75: /*
   76:  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
   77:  * All rights reserved.
   78:  *
   79:  * Redistribution and use in source and binary forms, with or without
   80:  * modification, are permitted provided that the following conditions
   81:  * are met:
   82:  * 1. Redistributions of source code must retain the above copyright
   83:  *    notice, this list of conditions and the following disclaimer.
   84:  * 2. Redistributions in binary form must reproduce the above copyright
   85:  *    notice, this list of conditions and the following disclaimer in the
   86:  *    documentation and/or other materials provided with the distribution.
   87:  * 3. The name of the author may not be used to endorse or promote products
   88:  *    derived from this software without specific prior written permission.
   89:  *
   90:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   91:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   92:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   93:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   94:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   95:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   96:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   97:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   98:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   99:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  100:  */
  101: 
  102: /* hack.tty.c - version 1.0.3 */
  103: /*
  104:  * With thanks to the people who sent code for SYSV - hpscdi!jon,
  105:  * arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others.
  106:  */
  107: 
  108: #include <termios.h>
  109: #include <termcap.h>
  110: #include "hack.h"
  111: #include "extern.h"
  112: 
  113: /*
  114:  * Some systems may have getchar() return EOF for various reasons, and
  115:  * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
  116:  */
  117: #ifndef BSD
  118: #define NR_OF_EOFS      20
  119: #endif  /* BSD */
  120: 
  121: static char     erase_char, kill_char;
  122: static boolean  settty_needed = FALSE;
  123: struct termios  inittyb, curttyb;
  124: 
  125: /*
  126:  * Get initial state of terminal, set ospeed (for termcap routines)
  127:  * and switch off tab expansion if necessary.
  128:  * Called by startup() in termcap.c and after returning from ! or ^Z
  129:  */
  130: void
  131: gettty()
  132: {
  133:         if (tcgetattr(0, &inittyb) < 0)
  134:                 perror("Hack (gettty)");
  135:         curttyb = inittyb;
  136:         ospeed = cfgetospeed(&inittyb);
  137:         erase_char = inittyb.c_cc[VERASE];
  138:         kill_char = inittyb.c_cc[VKILL];
  139:         getioctls();
  140: 
  141:         /* do not expand tabs - they might be needed inside a cm sequence */
  142:         if (curttyb.c_oflag & OXTABS) {
  143:                 curttyb.c_oflag &= ~OXTABS;
  144:                 setctty();
  145:         }
  146:         settty_needed = TRUE;
  147: }
  148: 
  149: /* reset terminal to original state */
  150: void
  151: settty(s)
  152:         const char           *s;
  153: {
  154:         clear_screen();
  155:         end_screen();
  156:         if (s)
  157:                 printf("%s", s);
  158:         (void) fflush(stdout);
  159:         if (tcsetattr(0, TCSADRAIN, &inittyb) < 0)
  160:                 perror("Hack (settty)");
  161:         flags.echo = (inittyb.c_lflag & ECHO) ? ON : OFF;
  162:         flags.cbreak = (inittyb.c_lflag & ICANON) ? OFF : ON;
  163:         setioctls();
  164: }
  165: 
  166: void
  167: setctty()
  168: {
  169:         if (tcsetattr(0, TCSADRAIN, &curttyb) < 0)
  170:                 perror("Hack (setctty)");
  171: }
  172: 
  173: 
  174: void
  175: setftty()
  176: {
  177:         int             change = 0;
  178:         flags.cbreak = ON;
  179:         flags.echo = OFF;
  180:         /* Should use (ECHO|CRMOD) here instead of ECHO */
  181:         if (curttyb.c_lflag & ECHO) {
  182:                 curttyb.c_lflag &= ~ECHO;
  183:                 change++;
  184:         }
  185:         if (curttyb.c_lflag & ICANON) {
  186:                 curttyb.c_lflag &= ~ICANON;
  187:                 /* be satisfied with one character; no timeout */
  188:                 curttyb.c_cc[VMIN] = 1;
  189:                 curttyb.c_cc[VTIME] = 0;
  190:                 change++;
  191:         }
  192:         if (change) {
  193:                 setctty();
  194:         }
  195:         start_screen();
  196: }
  197: 
  198: 
  199: /* fatal error */
  200: /* VARARGS1 */
  201: void
  202: error(const char *fmt, ...)
  203: {
  204:         va_list ap;
  205: 
  206:         va_start(ap, fmt);
  207:         if (settty_needed)
  208:                 settty((char *) 0);
  209:         vprintf(fmt, ap);
  210:         va_end(ap);
  211:         putchar('\n');
  212:         exit(1);
  213: }
  214: 
  215: /*
  216:  * Read a line closed with '\n' into the array char bufp[BUFSZ].
  217:  * (The '\n' is not stored. The string is closed with a '\0'.)
  218:  * Reading can be interrupted by an escape ('\033') - now the
  219:  * resulting string is "\033".
  220:  */
  221: void
  222: getlin(bufp)
  223:         char           *bufp;
  224: {
  225:         char           *obufp = bufp;
  226:         int             c;
  227: 
  228:         flags.toplin = 2;      /* nonempty, no --More-- required */
  229:         for (;;) {
  230:                 (void) fflush(stdout);
  231:                 if ((c = getchar()) == EOF) {
  232:                         *bufp = 0;
  233:                         return;
  234:                 }
  235:                 if (c == '\033') {
  236:                         *obufp = c;
  237:                         obufp[1] = 0;
  238:                         return;
  239:                 }
  240:                 if (c == erase_char || c == '\b') {
  241:                         if (bufp != obufp) {
  242:                                 bufp--;
  243:                                 putstr("\b \b");    /* putsym converts \b */
  244:                         } else
  245:                                 bell();
  246:                 } else if (c == '\n') {
  247:                         *bufp = 0;
  248:                         return;
  249:                 } else if (' ' <= c && c < '\177') {
  250:                         /*
  251:                          * avoid isprint() - some people don't have it ' ' is
  252:                          * not always a printing char
  253:                          */
  254:                         *bufp = c;
  255:                         bufp[1] = 0;
  256:                         putstr(bufp);
  257:                         if (bufp - obufp < BUFSZ - 1 && bufp - obufp < COLNO)
  258:                                 bufp++;
  259:                 } else if (c == kill_char || c == '\177') {   /* Robert Viduya */
  260:                         /* this test last - @ might be the kill_char */
  261:                         while (bufp != obufp) {
  262:                                 bufp--;
  263:                                 putstr("\b \b");
  264:                         }
  265:                 } else
  266:                         bell();
  267:         }
  268: }
  269: 
  270: void
  271: getret()
  272: {
  273:         cgetret("");
  274: }
  275: 
  276: void
  277: cgetret(s)
  278:         const char           *s;
  279: {
  280:         putsym('\n');
  281:         if (flags.standout)
  282:                 standoutbeg();
  283:         putstr("Hit ");
  284:         putstr(flags.cbreak ? "space" : "return");
  285:         putstr(" to continue: ");
  286:         if (flags.standout)
  287:                 standoutend();
  288:         xwaitforspace(s);
  289: }
  290: 
  291: char            morc;           /* tell the outside world what char he used */
  292: 
  293: void
  294: xwaitforspace(s)
  295:         const char *s; /* chars allowed besides space or return */
  296: {
  297:         int             c;
  298: 
  299:         morc = 0;
  300: 
  301:         while ((c = readchar()) != '\n') {
  302:                 if (flags.cbreak) {
  303:                         if (c == ' ')
  304:                                 break;
  305:                         if (s && strchr(s, c)) {
  306:                                 morc = c;
  307:                                 break;
  308:                         }
  309:                         bell();
  310:                 }
  311:         }
  312: }
  313: 
  314: char           *
  315: parse()
  316: {
  317:         static char     inputline[COLNO];
  318:         int            foo;
  319: 
  320:         flags.move = 1;
  321:         if (!Invisible)
  322:                 curs_on_u();
  323:         else
  324:                 home();
  325:         while ((foo = readchar()) >= '0' && foo <= '9')
  326:                 multi = 10 * multi + foo - '0';
  327:         if (multi) {
  328:                 multi--;
  329:                 save_cm = inputline;
  330:         }
  331:         inputline[0] = foo;
  332:         inputline[1] = 0;
  333:         if (foo == 'f' || foo == 'F') {
  334:                 inputline[1] = getchar();
  335: #ifdef QUEST
  336:                 if (inputline[1] == foo)
  337:                         inputline[2] = getchar();
  338:                 else
  339: #endif  /* QUEST */
  340:                         inputline[2] = 0;
  341:         }
  342:         if (foo == 'm' || foo == 'M') {
  343:                 inputline[1] = getchar();
  344:                 inputline[2] = 0;
  345:         }
  346:         clrlin();
  347:         return (inputline);
  348: }
  349: 
  350: char
  351: readchar()
  352: {
  353:         int             sym;
  354: 
  355:         (void) fflush(stdout);
  356:         if ((sym = getchar()) == EOF)
  357: #ifdef NR_OF_EOFS
  358:         {                      /*
  359:                                  * Some SYSV systems seem to return EOFs for various reasons
  360:                                  * (?like when one hits break or for interrupted systemcalls?),
  361:                                  * and we must see several before we quit.
  362:                                  */
  363:                 int             cnt = NR_OF_EOFS;
  364:                 while (cnt--) {
  365:                         clearerr(stdin);     /* omit if clearerr is
  366:                                                  * undefined */
  367:                         if ((sym = getchar()) != EOF)
  368:                                 goto noteof;
  369:                 }
  370:                 end_of_input();
  371: noteof: ;
  372:         }
  373: #else
  374:                 end_of_input();
  375: #endif  /* NR_OF_EOFS */
  376:         if (flags.toplin == 1)
  377:                 flags.toplin = 2;
  378:         return ((char) sym);
  379: }
  380: 
  381: void
  382: end_of_input()
  383: {
  384:         settty("End of input?\n");
  385:         clearlocks();
  386:         exit(0);
  387: }
Syntax (Markdown)