home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / uemacs / part4 / sys / ultrix / ttyio.c < prev   
Encoding:
C/C++ Source or Header  |  1986-11-30  |  3.8 KB  |  160 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *        Ultrix-32 terminal I/O.
  4.  * Version:    29
  5.  * Last edit:    05-Feb-86
  6.  * By:        rex::conroy
  7.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  8.  *
  9.  * The functions in this file
  10.  * negotiate with the operating system for
  11.  * keyboard characters, and write characters to
  12.  * the display in a barely buffered fashion.
  13.  */
  14. #include    "def.h"
  15.  
  16. #include    <sgtty.h>
  17.  
  18. #define    NOBUF    512            /* Output buffer size.        */
  19.  
  20. char    obuf[NOBUF];            /* Output buffer.        */
  21. int    nobuf;
  22. struct    sgttyb    oldtty;            /* V6/V7 stty data.        */
  23. struct    sgttyb    newtty;
  24. struct    tchars    oldtchars;        /* V7 editing.            */
  25. struct    tchars    newtchars;
  26. struct    ltchars oldltchars;        /* 4.2 BSD editing.        */
  27. struct    ltchars    newltchars;
  28. int    nrow;                /* Terminal size, rows.        */
  29. int    ncol;                /* Terminal size, columns.    */
  30.  
  31. /*
  32.  * This function gets called once, to set up
  33.  * the terminal channel. On Ultrix is's tricky, since
  34.  * we want flow control, but we don't want any characters
  35.  * stolen to send signals. Use CBREAK mode, and set all
  36.  * characters but start and stop to 0xFF.
  37.  */
  38. ttopen()
  39. {
  40.     register char    *cp;
  41.     extern char    *getenv();
  42.  
  43.     if (ioctl(0, TIOCGETP, &oldtty) < 0)
  44.         abort();
  45.     newtty.sg_ospeed = oldtty.sg_ospeed;
  46.     newtty.sg_ispeed = oldtty.sg_ispeed;
  47.     newtty.sg_erase  = oldtty.sg_erase;
  48.     newtty.sg_kill   = oldtty.sg_kill;
  49.     newtty.sg_flags  = oldtty.sg_flags;
  50.     newtty.sg_flags &= ~(ECHO|CRMOD);    /* Kill echo, CR=>NL.    */
  51.     newtty.sg_flags |= CBREAK;        /* Half-cooked mode.    */
  52.     if (ioctl(0, TIOCSETP, &newtty) < 0)
  53.         abort();
  54.     if (ioctl(0, TIOCGETC, &oldtchars) < 0)
  55.         abort();
  56.     newtchars.t_intrc  = 0xFF;        /* Interrupt.        */
  57.     newtchars.t_quitc  = 0xFF;        /* Quit.        */
  58.     newtchars.t_startc = 0x11;        /* ^Q, for terminal.    */
  59.     newtchars.t_stopc  = 0x13;        /* ^S, for terminal.    */
  60.     newtchars.t_eofc   = 0xFF;
  61.     newtchars.t_brkc   = 0xFF;
  62.     if (ioctl(0, TIOCSETC, &newtchars) < 0)
  63.         abort();
  64.     if (ioctl(0, TIOCGLTC, &oldltchars) < 0)
  65.         abort();
  66.     newltchars.t_suspc  = 0xFF;        /* Suspend #1.        */
  67.     newltchars.t_dsuspc = 0xFF;        /* Suspend #2.        */
  68.     newltchars.t_rprntc = 0xFF;
  69.     newltchars.t_flushc = 0xFF;        /* Output flush.    */
  70.     newltchars.t_werasc = 0xFF;
  71.     newltchars.t_lnextc = 0xFF;        /* Literal next.    */
  72.     if (ioctl(0, TIOCSLTC, &newltchars) < 0)
  73.         abort();
  74.     if ((cp=getenv("TERMCAP")) == NULL
  75.     || (nrow=getvalue(cp, "li")) <= 0
  76.     || (ncol=getvalue(cp, "co")) <= 0) {
  77.         nrow = 24;
  78.         ncol = 80;
  79.     }
  80.     if (nrow > NROW)            /* Don't crash if the    */
  81.         nrow = NROW;            /* termcap entry is    */
  82.     if (ncol > NCOL)            /* too big.        */
  83.         ncol = NCOL;
  84. }
  85.  
  86. /*
  87.  * This routine scans a string, which is
  88.  * actually the return value of a getenv call for the TERMCAP
  89.  * variable, looking for numeric parameter "name". Return the value
  90.  * if found. Return -1 if not there. Assume that "name" is 2
  91.  * characters long. This limited use of the TERMCAP lets us find
  92.  * out the size of a window on the X display.
  93.  */
  94. getvalue(cp, name)
  95. register char    *cp;
  96. register char    *name;
  97. {
  98.     for (;;) {
  99.         while (*cp!=0 && *cp!=':')
  100.             ++cp;
  101.         if (*cp++ == 0)            /* Not found.        */
  102.             return (-1);
  103.         if (cp[0]==name[0] && cp[1]==name[1] && cp[2]=='#')
  104.             return (atoi(cp+3));    /* Stops on ":".    */
  105.     }
  106. }
  107.  
  108. /*
  109.  * This function gets called just
  110.  * before we go back home to the shell. Put all of
  111.  * the terminal parameters back.
  112.  */
  113. ttclose()
  114. {
  115.     ttflush();
  116.     if (ioctl(0, TIOCSLTC, &oldltchars) < 0)
  117.         abort();
  118.     if (ioctl(0, TIOCSETC, &oldtchars) < 0)
  119.         abort();
  120.     if (ioctl(0, TIOCSETP, &oldtty) < 0)
  121.         abort();
  122. }
  123.  
  124. /*
  125.  * Write character to the display.
  126.  * Characters are buffered up, to make things
  127.  * a little bit more efficient.
  128.  */
  129. ttputc(c)
  130. {
  131.     if (nobuf >= NOBUF)
  132.         ttflush();
  133.     obuf[nobuf++] = c;
  134. }
  135.  
  136. /*
  137.  * Flush output.
  138.  */
  139. ttflush()
  140. {
  141.     if (nobuf != 0) {
  142.         write(1, obuf, nobuf);
  143.         nobuf = 0;
  144.     }
  145. }
  146.  
  147. /*
  148.  * Read character from terminal.
  149.  * All 8 bits are returned, so that you can use
  150.  * a multi-national terminal.
  151.  */
  152. ttgetc()
  153. {
  154.     char    buf[1];
  155.  
  156.     while (read(0, &buf[0], 1) != 1)
  157.         ;
  158.     return (buf[0] & 0xFF);
  159. }
  160.