home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 1 / src / tty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-07-26  |  6.2 KB  |  302 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* hack.tty.c - version 1.0.3 */
  3. /* With thanks to the people who sent code for SYSV - hpscdi!jon,
  4.    arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others. */
  5.  
  6. #include    "hack.h"
  7. #include    <stdio.h>
  8.  
  9. /*
  10.  * The distinctions here are not BSD - rest but rather USG - rest, as
  11.  * BSD still has the old sgttyb structure, but SYSV has termio. Thus:
  12.  */
  13. #ifdef BSD
  14. #define    V7
  15. #else
  16. #define USG
  17. #endif BSD
  18.  
  19. /*
  20.  * Some systems may have getchar() return EOF for various reasons, and
  21.  * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
  22.  */
  23. #ifndef BSD
  24. #define    NR_OF_EOFS    20
  25. #endif BSD
  26.  
  27.  
  28. #ifdef USG
  29.  
  30. #include    <termio.h>
  31. #define termstruct    termio
  32. #define kill_sym    c_cc[VKILL]
  33. #define erase_sym    c_cc[VERASE]
  34. #define EXTABS        TAB3
  35. #define tabflgs        c_oflag
  36. #define echoflgs    c_lflag
  37. #define cbrkflgs    c_lflag
  38. #define CBRKMASK    ICANON
  39. #define CBRKON        ! /* reverse condition */
  40. #define OSPEED(x)    ((x).c_cflag & CBAUD)
  41. #define GTTY(x)        (ioctl(0, TCGETA, x))
  42. #define STTY(x)        (ioctl(0, TCSETA, x))    /* TCSETAF? TCSETAW? */
  43.  
  44. #else    /* V7 */
  45.  
  46. #include    <sgtty.h>
  47. #define termstruct    sgttyb
  48. #define    kill_sym    sg_kill
  49. #define    erase_sym    sg_erase
  50. #define EXTABS        XTABS
  51. #define tabflgs        sg_flags
  52. #define echoflgs    sg_flags
  53. #define cbrkflgs    sg_flags
  54. #define CBRKMASK    CBREAK
  55. #define CBRKON        /* empty */
  56. #define OSPEED(x)    (x).sg_ospeed
  57. #define GTTY(x)        (gtty(0, x))
  58. #define STTY(x)        (stty(0, x))
  59.  
  60. #endif USG
  61.  
  62. extern short ospeed;
  63. static char erase_char, kill_char;
  64. static boolean settty_needed = FALSE;
  65. struct termstruct inittyb, curttyb;
  66.  
  67. /*
  68.  * Get initial state of terminal, set ospeed (for termcap routines)
  69.  * and switch off tab expansion if necessary.
  70.  * Called by startup() in termcap.c and after returning from ! or ^Z
  71.  */
  72. gettty(){
  73.     if(GTTY(&inittyb) < 0)
  74.         perror("Hack (gettty)");
  75.     curttyb = inittyb;
  76.     ospeed = OSPEED(inittyb);
  77.     erase_char = inittyb.erase_sym;
  78.     kill_char = inittyb.kill_sym;
  79.     getioctls();
  80.  
  81.     /* do not expand tabs - they might be needed inside a cm sequence */
  82.     if(curttyb.tabflgs & EXTABS) {
  83.         curttyb.tabflgs &= ~EXTABS;
  84.         setctty();
  85.     }
  86.     settty_needed = TRUE;
  87. }
  88.  
  89. /* reset terminal to original state */
  90. settty(s) char *s; {
  91.     clear_screen();
  92.     end_screen();
  93.     if(s) printf(s);
  94.     (void) fflush(stdout);
  95.     if(STTY(&inittyb) < 0)
  96.         perror("Hack (settty)");
  97.     flags.echo = (inittyb.echoflgs & ECHO) ? ON : OFF;
  98.     flags.cbreak = (CBRKON(inittyb.cbrkflgs & CBRKMASK)) ? ON : OFF;
  99.     setioctls();
  100. }
  101.  
  102. setctty(){
  103.     if(STTY(&curttyb) < 0)
  104.         perror("Hack (setctty)");
  105. }
  106.  
  107.  
  108. setftty(){
  109. register int ef = 0;            /* desired value of flags & ECHO */
  110. register int cf = CBRKON(CBRKMASK);    /* desired value of flags & CBREAK */
  111. register int change = 0;
  112.     flags.cbreak = ON;
  113.     flags.echo = OFF;
  114.     /* Should use (ECHO|CRMOD) here instead of ECHO */
  115.     if((curttyb.echoflgs & ECHO) != ef){
  116.         curttyb.echoflgs &= ~ECHO;
  117. /*        curttyb.echoflgs |= ef;                    */
  118.         change++;
  119.     }
  120.     if((curttyb.cbrkflgs & CBRKMASK) != cf){
  121.         curttyb.cbrkflgs &= ~CBRKMASK;
  122.         curttyb.cbrkflgs |= cf;
  123. #ifdef USG
  124.         /* be satisfied with one character; no timeout */
  125.         curttyb.c_cc[VMIN] = 1;        /* was VEOF */
  126.         curttyb.c_cc[VTIME] = 0;    /* was VEOL */
  127. #endif USG
  128.         change++;
  129.     }
  130.     if(change){
  131.         setctty();
  132.     }
  133.     start_screen();
  134. }
  135.  
  136.  
  137. /* fatal error */
  138. /*VARARGS1*/
  139. error(s,x,y) char *s; {
  140.     if(settty_needed)
  141.         settty((char *) 0);
  142.     printf(s,x,y);
  143.     putchar('\n');
  144.     exit(1);
  145. }
  146.  
  147. /*
  148.  * Read a line closed with '\n' into the array char bufp[BUFSZ].
  149.  * (The '\n' is not stored. The string is closed with a '\0'.)
  150.  * Reading can be interrupted by an escape ('\033') - now the
  151.  * resulting string is "\033".
  152.  */
  153. getlin(bufp)
  154. register char *bufp;
  155. {
  156.     register char *obufp = bufp;
  157.     register int c;
  158.  
  159.     flags.toplin = 2;        /* nonempty, no --More-- required */
  160.     for(;;) {
  161.         (void) fflush(stdout);
  162.         if((c = getchar()) == EOF) {
  163.             *bufp = 0;
  164.             return;
  165.         }
  166.         if(c == '\033') {
  167.             *obufp = c;
  168.             obufp[1] = 0;
  169.             return;
  170.         }
  171.         if(c == erase_char || c == '\b') {
  172.             if(bufp != obufp) {
  173.                 bufp--;
  174.                 putstr("\b \b"); /* putsym converts \b */
  175.             } else    bell();
  176.         } else if(c == '\n') {
  177.             *bufp = 0;
  178.             return;
  179.         } else if(' ' <= c && c < '\177') {
  180.                 /* avoid isprint() - some people don't have it
  181.                    ' ' is not always a printing char */
  182.             *bufp = c;
  183.             bufp[1] = 0;
  184.             putstr(bufp);
  185.             if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
  186.                 bufp++;
  187.         } else if(c == kill_char || c == '\177') { /* Robert Viduya */
  188.                 /* this test last - @ might be the kill_char */
  189.             while(bufp != obufp) {
  190.                 bufp--;
  191.                 putstr("\b \b");
  192.             }
  193.         } else
  194.             bell();
  195.     }
  196. }
  197.  
  198. getret() {
  199.     cgetret("");
  200. }
  201.  
  202. cgetret(s)
  203. register char *s;
  204. {
  205.     putsym('\n');
  206.     if(flags.standout)
  207.         standoutbeg();
  208.     putstr("Hit ");
  209.     putstr(flags.cbreak ? "space" : "return");
  210.     putstr(" to continue: ");
  211.     if(flags.standout)
  212.         standoutend();
  213.     xwaitforspace(s);
  214. }
  215.  
  216. char morc;    /* tell the outside world what char he used */
  217.  
  218. xwaitforspace(s)
  219. register char *s;    /* chars allowed besides space or return */
  220. {
  221. register int c;
  222.  
  223.     morc = 0;
  224.  
  225.     while((c = readchar()) != '\n') {
  226.         if(flags.cbreak) {
  227.         if(c == ' ') break;
  228.         if(s && index(s,c)) {
  229.             morc = c;
  230.             break;
  231.         }
  232.         bell();
  233.         }
  234.     }
  235. }
  236.  
  237. char *
  238. parse()
  239. {
  240.     static char inline[COLNO];
  241.     register foo;
  242.  
  243.     flags.move = 1;
  244.     if(!Invisible) curs_on_u(); else home();
  245.     while((foo = readchar()) >= '0' && foo <= '9')
  246.         multi = 10*multi+foo-'0';
  247.     if(multi) {
  248.         multi--;
  249.         save_cm = inline;
  250.     }
  251.     inline[0] = foo;
  252.     inline[1] = 0;
  253.     if(foo == 'f' || foo == 'F'){
  254.         inline[1] = getchar();
  255. #ifdef QUEST
  256.         if(inline[1] == foo) inline[2] = getchar(); else
  257. #endif QUEST
  258.         inline[2] = 0;
  259.     }
  260.     if(foo == 'm' || foo == 'M'){
  261.         inline[1] = getchar();
  262.         inline[2] = 0;
  263.     }
  264.     clrlin();
  265.     return(inline);
  266. }
  267.  
  268. char
  269. readchar() {
  270.     register int sym;
  271.  
  272.     (void) fflush(stdout);
  273.     if((sym = getchar()) == EOF)
  274. #ifdef NR_OF_EOFS
  275.     { /*
  276.        * Some SYSV systems seem to return EOFs for various reasons
  277.        * (?like when one hits break or for interrupted systemcalls?),
  278.        * and we must see several before we quit.
  279.        */
  280.         register int cnt = NR_OF_EOFS;
  281.         while (cnt--) {
  282.             clearerr(stdin);    /* omit if clearerr is undefined */
  283.             if((sym = getchar()) != EOF) goto noteof;
  284.         }
  285.         end_of_input();
  286.          noteof:    ;
  287.     }
  288. #else
  289.         end_of_input();
  290. #endif NR_OF_EOFS
  291.     if(flags.toplin == 1)
  292.         flags.toplin = 2;
  293.     return((char) sym);
  294. }
  295.  
  296. end_of_input()
  297. {
  298.     settty("End of input?\n");
  299.     clearlocks();
  300.     exit(0);
  301. }
  302.