home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / beav1402.zip / termio.c < prev    next >
Text File  |  1993-04-16  |  8KB  |  376 lines

  1. /*
  2.  * The functions in this file negotiate with the operating system for
  3.  * characters, and write characters in a barely buffered fashion on the display.
  4.  * All operating systems.
  5.  */
  6.  
  7. #include    <sys/types.h>    /* 1.13 */
  8.  
  9. #ifdef UNIX            /* System V */
  10.  
  11. #include    <stdio.h>
  12. #include    <signal.h>
  13. #ifdef BSD
  14. #include    <sys/ioctl.h>
  15. #else
  16. #ifdef OS2
  17. #ifndef __EMX__
  18. #define INCL_NOPM
  19. #define INCL_DOS
  20. #define INCL_KBD
  21. #include    <os2.h>
  22. #endif
  23. #include    <io.h>
  24. #else
  25. #ifdef MINIX
  26. #include    <sgtty.h>
  27. #define O_NDELAY O_NONBLOCK
  28. #else
  29. #include    <termio.h>
  30. #endif /* MINIX */
  31. #endif /* OS2 */
  32. #endif /* BSD */
  33. #include    <errno.h>
  34. #include    <fcntl.h>
  35. #include    "def.h"
  36. int kbdflgs;            /* saved keyboard fd flags  */
  37. int kbdpoll;            /* in O_NDELAY mode         */
  38. int kbdqp;            /* there is a char in kbdq  */
  39. char kbdq;            /* char we've already read  */
  40.  
  41. #ifdef BSD
  42. struct sgttyb otermb;
  43. struct sgttyb ntermb;
  44. #else
  45. #ifdef OS2
  46. #ifndef __EMX__
  47. KBDINFO kbst, kbst_std;
  48. #endif
  49. #else
  50. #ifdef MINIX
  51. struct sgttyb otermio;        /* original terminal characteristics */
  52. struct sgttyb ntermio;        /* charactoristics to use inside */
  53. struct tchars tchars, tcharsorig;
  54. #else
  55. struct termio otermio;        /* original terminal characteristics */
  56. struct termio ntermio;        /* charactoristics to use inside */
  57. #endif /* MINIX */
  58. #endif /* OS2 */
  59. #endif /* BSD */
  60.  
  61. #ifndef OS2
  62. extern errno;            /* System error number -- Necessary when compiling in BSD 1.13 */
  63. #endif
  64.  
  65. int nrow;            /* Terminal size, rows.         */
  66. int ncol;            /* Terminal size, columns.      */
  67.  
  68. /*
  69.  * This function is called once to set up the terminal device streams.
  70.  * On VMS, it translates TT until it finds the terminal, then assigns
  71.  * a channel to it and sets it raw. On CPM it is a no-op.
  72.  */
  73.  
  74. void
  75. ttopen ()
  76. {
  77. #ifdef BSD
  78. #ifdef ULTRIX
  79.     struct winsize ttysize;
  80. #else
  81.     struct ttysize ttysize;
  82. #endif
  83.  
  84.     ioctl (0, TIOCGETP, &otermb);    /* save settings    */
  85.     ntermb = otermb;        /* setup new settings    */
  86.     ntermb.sg_flags &= ~ECHO;
  87.     ntermb.sg_flags |= RAW;
  88.     ioctl (0, TIOCSETP, &ntermb);    /* and activate them    */
  89.     kbdpoll = FALSE;
  90.  
  91.     /* on all screens we are not sure of the initial position
  92.    of the cursor                    */
  93.     ttrow = 999;
  94.     ttcol = 999;
  95. #ifdef ULTRIX
  96.     if (ioctl (0, TIOCGWINSZ, &ttysize) == 0)
  97.     {
  98.     nrow = ttysize.ws_row;
  99.     ncol = ttysize.ws_col;
  100. #else
  101.     if (ioctl (0, TIOCGSIZE, &ttysize) == 0)
  102.     {
  103.     nrow = ttysize.ts_lines;
  104.     ncol = ttysize.ts_cols;
  105. #endif
  106.     }
  107.     else
  108.     {
  109.     nrow = NROW;
  110.     ncol = NCOL;
  111.     }
  112. #else
  113. #ifdef OS2
  114.     setmode (1, O_BINARY);
  115. #else
  116. #ifdef MINIX
  117.     ioctl (0, TIOCGETP, &otermio);
  118.     ntermio = otermio;
  119.     ntermio.sg_flags &= ~ECHO;
  120.     ntermio.sg_flags |= RAW;
  121.     ioctl (0, TIOCSETP, &ntermio);
  122.     ioctl (0, TIOCGETC, &tcharsorig);
  123.     tchars = tcharsorig;
  124.     tchars.t_intrc = tchars.t_quitc = tchars.t_startc =
  125.     tchars.t_stopc = tchars.t_eofc = tchars.t_brkc = -1;
  126.     ioctl (0, TIOCSETC, &tchars);
  127. #else
  128.     ioctl (0, TCGETA, &otermio);/* save old settings */
  129.     ntermio.c_iflag = 0;    /* setup new settings */
  130.     ntermio.c_oflag = 0;
  131.     ntermio.c_cflag = otermio.c_cflag;
  132.     ntermio.c_lflag = 0;
  133.     ntermio.c_line = otermio.c_line;
  134.     ntermio.c_cc[VMIN] = 1;
  135.     ntermio.c_cc[VTIME] = 0;
  136.     ioctl (0, TCSETAW, &ntermio);    /* and activate them */
  137. #endif /* MINIX */
  138.     kbdflgs = fcntl (0, F_GETFL, 0);
  139.     kbdpoll = FALSE;
  140. #endif /* OS2 */
  141.     /* on all screens we are not sure of the initial position of the cursor */
  142.     ttrow = 999;
  143.     ttcol = 999;
  144.     nrow = NROW;
  145.     ncol = NCOL;
  146. #endif /* BSD */
  147. }
  148.  
  149.  /*
  150. * This function gets called just before we go back home to the command
  151. * interpreter. On VMS it puts the terminal back in a reasonable state.
  152. * Another no-operation on CPM.
  153. */
  154. void
  155. ttclose ()
  156. {
  157. #ifdef BSD
  158.     if (ioctl (0, TIOCSETP, &otermb) == -1)    /* restore terminal settings */
  159.     printf ("closing ioctl on dev 0 failure, error = %d\n", errno);
  160. #else
  161. #ifdef OS2
  162.     setmode (1, O_TEXT);
  163. #else
  164. #ifdef MINIX
  165.     if (ioctl (0, TIOCSETP, &otermio) == -1 ||
  166.     ioctl (0, TIOCSETC, &tcharsorig) == -1)
  167.     printf ("closing ioctl on dev 0 failure, error = %d\n", errno);
  168. #else
  169.     if (ioctl (0, TCSETAW, &otermio) == -1)    /* restore terminal settings */
  170.     printf ("closing ioctl on dev 0 failure, error = %d\n", errno);
  171. #endif /* MINIX */
  172.     if (fcntl (0, F_SETFL, kbdflgs) == -1)
  173.     printf ("closing fcntl on dev 0 failure, error = %d\n", errno);
  174. #endif /* OS2 */
  175. #endif /* BSD */
  176. }
  177.  
  178. #ifdef OS2
  179. void 
  180. ttraw (void)
  181. {
  182. #ifdef __32BIT__
  183.     signal (SIGINT, SIG_IGN);
  184.     signal (SIGBREAK, SIG_IGN);
  185. #else
  186.     PFNSIGHANDLER oldhandler;
  187.     USHORT oldact;
  188.  
  189.     DosSetSigHandler ((PFNSIGHANDLER) NULL, &oldhandler, &oldact,
  190.               SIGA_IGNORE, SIG_CTRLBREAK);
  191.     DosSetSigHandler ((PFNSIGHANDLER) NULL, &oldhandler, &oldact,
  192.               SIGA_IGNORE, SIG_CTRLC);
  193. #endif
  194.  
  195. #ifndef __EMX__
  196.     kbst_std.cb = sizeof (kbst_std);
  197.     KbdGetStatus (&kbst_std, 0);
  198.     kbst = kbst_std;
  199.     kbst.fsMask &= ~(KEYBOARD_ECHO_ON | KEYBOARD_ASCII_MODE |
  200.              KEYBOARD_SHIFT_REPORT);
  201.     kbst.fsMask |= (KEYBOARD_ECHO_OFF | KEYBOARD_BINARY_MODE);
  202.     KbdSetStatus (&kbst, 0);
  203. #endif
  204. }
  205.  
  206. void 
  207. ttcooked (void)
  208. {
  209. #ifndef __EMX__
  210.     KbdSetStatus (&kbst_std, 0);
  211. #endif
  212. }
  213.  
  214. #endif
  215.  
  216.  /*
  217. * Write a character to the display. On VMS, terminal output is buffered, and
  218. * we just put the characters in the big array, after checking for overflow.
  219. * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  220. * MS-DOS (use the very very raw console output routine).
  221. */
  222.  
  223. #ifdef OS2
  224. int tty_io_size = 0;
  225. char tty_io_buffer[2048];
  226. #endif
  227.  
  228. int
  229. ttputc (c)
  230. {
  231. #ifdef OS2
  232.     if (tty_io_size == sizeof (tty_io_buffer))
  233.     {
  234.     write (1, tty_io_buffer, tty_io_size);
  235.     tty_io_size = 0;
  236.     }
  237.     tty_io_buffer[tty_io_size++] = c;
  238. #else
  239.     fputc (c, stdout);
  240. #endif
  241.     return c;
  242. }
  243.  
  244.  /*
  245. * Flush terminal buffer. Does real work where the terminal output is buffered
  246. * up. A no-operation on systems where byte at a time terminal I/O is done.
  247. */
  248. void
  249. ttflush ()
  250. {
  251. #ifdef OS2
  252.     if (tty_io_size)
  253.     {
  254.     write (1, tty_io_buffer, tty_io_size);
  255.     tty_io_size = 0;
  256.     }
  257. #else
  258.     fflush (stdout);
  259. #endif
  260. }
  261.  
  262.  /*
  263. * Read a character from the terminal, performing no editing and doing no echo
  264. * at all. More complex in VMS that almost anyplace else, which figures. Very
  265. * simple on CPM, because the system can do exactly what you want.
  266. */
  267.  
  268. #ifdef OS2
  269. #ifdef __EMX__
  270. static int chr = -1;
  271. #endif
  272. #endif
  273.  
  274. ttgetc ()
  275. {
  276. #ifdef OS2
  277. #ifdef __EMX__
  278.     if (chr != -1)
  279.     {
  280.     int c = chr;
  281.     chr = -1;
  282.     return c;
  283.     }
  284.     else
  285.     return _read_kbd (0, 1, 0);
  286. #else
  287.     static int ext, scan, chr;
  288.     KBDKEYINFO ki;
  289.  
  290.     if (ext)
  291.     {
  292.     ext = 0;
  293.     return scan;
  294.     }
  295.     else
  296.     {
  297.     ttflush ();
  298.     KbdCharIn (&ki, IO_WAIT, 0);
  299.  
  300.     if (ki.chChar == 0 || ki.chChar == 0xE0)
  301.     {
  302.         ext = 1;
  303.         scan = ki.chScan;
  304.         return 0xE0;
  305.     }
  306.     else
  307.         return ki.chChar;
  308.     }
  309. #endif
  310. #else
  311.     if (kbdqp)
  312.     kbdqp = FALSE;
  313.     else
  314.     {
  315. #ifdef BSD
  316.     int count;
  317.  
  318.     if (kbdpoll && (ioctl (0, FIONREAD, &count), count == 0))
  319.         return FALSE;
  320.     read (0, &kbdq, 1);
  321. #else
  322.     if (kbdpoll && fcntl (0, F_SETFL, kbdflgs) < 0)
  323.         return FALSE;
  324.     kbdpoll = FALSE;
  325.     while (read (0, &kbdq, 1) != 1)
  326.         ;
  327. #endif
  328.     }
  329.     return (kbdq & 127);
  330. #endif /* OS2 */
  331. }
  332.  
  333.  /* typahead():    Check to see if any characters are already in the
  334.  keyboard buffer
  335. */
  336. ttkeyready ()
  337. {
  338. #ifdef OS2
  339. #ifdef __EMX__
  340.     chr = _read_kbd (0, 0, 0);
  341.     return (chr != -1);
  342. #else
  343.     KBDKEYINFO ki;
  344.  
  345.     KbdPeek (&ki, 0);
  346.     return (ki.fbStatus != 0);
  347. #endif
  348. #else
  349.     if (!kbdqp)
  350.     {
  351. #ifdef BSD
  352.     int count;
  353.  
  354.     if (!kbdpoll && (ioctl (0, FIONREAD, &count), count == 0))
  355.         return FALSE;
  356.     kbdpoll = TRUE;        /*  fix in 1.13 */
  357.     kbdqp = TRUE;
  358. #else
  359. #ifdef X_MINIX
  360.     /* MINIX has non-blocking mode but it doesn't work !?!? */
  361.     return FALSE;
  362. #else
  363.     if (!kbdpoll && fcntl (0, F_SETFL, kbdflgs | O_NDELAY) < 0)
  364.         return (FALSE);
  365.     kbdpoll = TRUE;        /*  fix in 1.13 */
  366.     kbdqp = (1 == read (0, &kbdq, 1));
  367. #endif /* MINIX */
  368. #endif /* BSD */
  369.  
  370.     }
  371.     return (kbdqp);
  372. #endif /* OS2 */
  373. }
  374.  
  375. #endif
  376.