home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Communications / pcomm / Source / tty_att.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  5.3 KB  |  309 lines

  1. /*
  2.  * System V specific routines for manipulating the TTY
  3.  */
  4.  
  5. #include <stdio.h>
  6. #ifdef XENIX_3
  7. #include <sys/types.h>
  8. #include <sys/ioctl.h>
  9. #endif /* XENIX_3 */
  10. #include <termio.h>
  11. #include <fcntl.h>
  12. #include "dial_dir.h"
  13. #include "modem.h"
  14. #include "param.h"
  15.  
  16. static struct termio hold;
  17.  
  18. /*
  19.  * Change the communication line settings to the new values.
  20.  */
  21.  
  22. void
  23. line_set()
  24. {
  25.     static int first = 1;
  26.     extern int fd;
  27.     struct termio tbuf;
  28.     int baud;
  29.  
  30.     if (first) {
  31.         ioctl(fd, TCGETA, &hold);
  32.         first = 0;
  33.     }
  34.  
  35.     /*
  36.      * The manual dial entry also serves to store the previous
  37.      * line settings.  How else would the manual dial entry
  38.      * know what line setting to use?
  39.      */
  40.     if (dir->d_cur != 0) {
  41.         dir->baud[0] = dir->baud[dir->d_cur];
  42.         dir->parity[0] = dir->parity[dir->d_cur];
  43.         dir->dbits[0] = dir->dbits[dir->d_cur];
  44.         dir->sbits[0] = dir->sbits[dir->d_cur];
  45.     }
  46.                     /* nothing to do! */
  47.     if (fd == -1)
  48.         return;
  49.                     /* get the current settings */
  50.     ioctl(fd, TCGETA, &tbuf);
  51.                     /* set some beginning values */
  52.     tbuf.c_cc[4] = 1;        /* VMIN */
  53.     tbuf.c_cc[5] = 0;        /* VTIME */
  54.     tbuf.c_oflag = 0;
  55.     tbuf.c_iflag = 0;
  56.     tbuf.c_cflag = (CREAD|HUPCL|CLOCAL);
  57.     tbuf.c_lflag = 0;
  58.  
  59.     if (*param->flow == 'X')
  60.         tbuf.c_iflag |= (IXON|IXOFF);
  61.                     /* strip high bit? */
  62.     if (*param->strip == 'Y')
  63.         tbuf.c_iflag |= ISTRIP;
  64.  
  65.                     /* the baud rate */
  66.     baud = modem->init_sp[modem->m_cur];
  67.     if (baud == 0)
  68.         baud = dir->baud[dir->d_cur];
  69.  
  70.     switch (baud) {
  71.         case 300:
  72.             tbuf.c_cflag |= B300;
  73.             break;
  74.         case 1200:
  75.             tbuf.c_cflag |= B1200;
  76.             break;
  77.         case 2400:
  78.             tbuf.c_cflag |= B2400;
  79.             break;
  80.         case 4800:
  81.             tbuf.c_cflag |= B4800;
  82.             break;
  83.         case 9600:
  84.             tbuf.c_cflag |= B9600;
  85.             break;
  86.         case 19200:
  87. #ifdef B19200
  88.             tbuf.c_cflag |= B19200;
  89. #else /* B19200 */
  90. #ifdef EXTA
  91.             tbuf.c_cflag |= EXTA;
  92. #endif /* EXTA */
  93. #endif /* B19200 */
  94.             break;
  95.     }
  96.                     /* the parity */
  97.     switch (dir->parity[dir->d_cur]) {
  98.         case 'N':
  99.             break;
  100.         case 'O':
  101.             tbuf.c_cflag |= (PARENB|PARODD);
  102.             break;
  103.         case 'E':
  104.             tbuf.c_cflag |= PARENB;
  105.             break;
  106.     }
  107.                     /* the data bits */
  108.     if (dir->dbits[dir->d_cur] == 8)
  109.         tbuf.c_cflag |= CS8;
  110.     else
  111.         tbuf.c_cflag |= CS7;
  112.                     /* the stop bits */
  113.     if (dir->sbits[dir->d_cur] == 2)
  114.         tbuf.c_cflag |= CSTOPB;
  115.  
  116.                     /* now set 'em! */
  117.     ioctl(fd, TCSETAF, &tbuf);
  118.     return;
  119. }
  120.  
  121. /*
  122.  * Put things back the way they were.
  123.  */
  124.  
  125. void
  126. reset_line()
  127. {
  128.     extern int fd;
  129.  
  130.     ioctl(fd, TCSETAF, &hold);
  131.     return;
  132. }
  133.  
  134. /*
  135.  * Put the stdin/stdout in terminal mode.  We've divided up the
  136.  * responsibility for the line settings options between the serial port
  137.  * and the stdin and stdout.
  138.  */
  139.  
  140. void
  141. term_mode()
  142. {
  143.     struct termio tbuf;
  144.  
  145.     ioctl(0, TCGETA, &tbuf);
  146.  
  147.     tbuf.c_cc[4] = 1;        /* VMIN */
  148.     tbuf.c_cc[5] = 0;        /* VTIME */
  149.     tbuf.c_iflag = 0;
  150.     tbuf.c_oflag = 0;
  151.     tbuf.c_lflag = 0;
  152.                     /* duplex */
  153.     if (dir->duplex[dir->d_cur] == 'H')
  154.         tbuf.c_lflag = ECHO;
  155.  
  156.     ioctl(0, TCSETAF, &tbuf);
  157.     return;
  158. }
  159.  
  160. /*
  161.  * Put the TTY driver in the mode suitable for xmodem transfers.
  162.  */
  163.  
  164. void
  165. xmodem_mode(fds)
  166. int fds;
  167. {
  168.     struct termio tbuf;
  169.  
  170.     ioctl(fds, TCGETA, &tbuf);
  171.     /*
  172.      * Turn off the XON/XOFF flow control, turn off echoing, and
  173.      * switch to 8 bit no parity.
  174.      */
  175.     tbuf.c_cc[4] = 1;        /* VMIN */
  176.     tbuf.c_cc[5] = 0;        /* VTIME */
  177.     tbuf.c_iflag = 0;        /* no flow control or mapping */
  178.     tbuf.c_oflag = 0;        /* no char mapping or delays */
  179.     tbuf.c_lflag = 0;        /* no echo or signals */
  180.     tbuf.c_cflag &= ~(PARENB|CSIZE);/* no parity */
  181.     tbuf.c_cflag |= CS8;        /* 8 bit */
  182.  
  183.     ioctl(fds, TCSETAF, &tbuf);
  184.     return;
  185. }
  186.  
  187. /*
  188.  * Put the TTY line in a mode suitable for the ASCII transfer.  Puts the
  189.  * terminal in the raw, non-blocking mode.
  190.  */
  191.  
  192. void
  193. ascii_mode(up)
  194. int up;
  195. {
  196.     extern int fd;
  197.     struct termio tbuf;
  198.  
  199.     ioctl(fd, TCGETA, &tbuf);
  200.     tbuf.c_oflag = 0;
  201.                     /* flow control & 8th bit stripping */
  202.     if (up) {
  203.         tbuf.c_iflag = (ISTRIP|IXON);
  204.  
  205.                     /* if no CR's, use NL delays */
  206.         if (!strcmp(param->cr_up, "STRIP"))
  207.             tbuf.c_oflag = (OPOST|ONLRET);
  208.  
  209.                     /* CR delay times */
  210.         switch (param->cr_delay) {
  211.             case 0:
  212.                 break;
  213.             case 100:
  214.                 tbuf.c_oflag |= (OPOST|CR2);
  215.                 break;
  216.             case 150:
  217.                 tbuf.c_oflag |= (OPOST|CR3);
  218.                 break;
  219.         }
  220.     }
  221.                     /* if down loading */
  222.     else
  223.         tbuf.c_iflag = (ISTRIP|IXOFF);
  224.  
  225.     ioctl(fd, TCSETAF, &tbuf);
  226.     return;
  227. }
  228.  
  229. /*
  230.  * Flush the file descriptor
  231.  */
  232.  
  233. int
  234. tty_flush(fds, mode)
  235. int fds, mode;
  236. {
  237.     return(ioctl(fds, TCFLSH, mode));
  238. }
  239.  
  240. /*
  241.  * Wait for the output to drain
  242.  */
  243.  
  244. int
  245. tty_drain(fds)
  246. int fds;
  247. {
  248.     return(ioctl(fds, TCSBRK, 1));
  249. }
  250.  
  251. /*
  252.  * Send a modem break
  253.  */
  254.  
  255. int
  256. tty_break(fds)
  257. int fds;
  258. {
  259.     return(ioctl(fds, TCSBRK, 0));
  260. }
  261.  
  262. /*
  263.  * Fix the file descriptor so that a read is satisfied immediately.  When
  264.  * read() is called it returns the character in the queue, or an error if
  265.  * no key was pressed.
  266.  */
  267.  
  268. int
  269. tty_noblock(fds, on)
  270. int fds, on;
  271. {
  272.     int current;
  273.  
  274.     current = fcntl(fds, F_GETFL, 0);
  275.     if (on)
  276.         return(fcntl(fds, F_SETFL, current | O_NDELAY));
  277.     else
  278.         return(fcntl(fds, F_SETFL, current & ~O_NDELAY));
  279. }
  280.  
  281. /*
  282.  * Get the current baud rate of the terminal
  283.  */
  284.  
  285. int
  286. my_speed()
  287. {
  288.     static int speed[15] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
  289.      1200, 1800, 2400, 4800, 9600, 19200};
  290.     struct termio tbuf;
  291.  
  292.     ioctl(0, TCGETA, &tbuf);
  293.     return(speed[tbuf.c_cflag & CBAUD]);
  294. }
  295.  
  296. /*
  297.  * Restart any XON/XOFF flow control that may have stopped the tty 
  298.  */
  299.  
  300. void
  301. tty_restart()
  302. {
  303.     extern int fd;
  304.  
  305.     if (fd != -1 && *param->flow == 'X') 
  306.         ioctl(fd, TCXONC, 1);
  307.     return;
  308. }
  309.