home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / editor / beav / termio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-30  |  8.3 KB  |  372 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 ttraw(void)
  180. {
  181. #ifdef __32BIT__
  182.     signal(SIGINT, SIG_IGN);
  183.     signal(SIGBREAK, SIG_IGN);
  184. #else
  185.     PFNSIGHANDLER oldhandler;
  186.     USHORT oldact;
  187.  
  188.     DosSetSigHandler((PFNSIGHANDLER) NULL, &oldhandler, &oldact,
  189.                      SIGA_IGNORE, SIG_CTRLBREAK);
  190.     DosSetSigHandler((PFNSIGHANDLER) NULL, &oldhandler, &oldact,
  191.                      SIGA_IGNORE, SIG_CTRLC);
  192. #endif
  193.  
  194. #ifndef __EMX__
  195.     kbst_std.cb = sizeof(kbst_std);
  196.     KbdGetStatus(&kbst_std, 0);
  197.     kbst = kbst_std;
  198.     kbst.fsMask &= ~(KEYBOARD_ECHO_ON  | KEYBOARD_ASCII_MODE | 
  199.              KEYBOARD_SHIFT_REPORT);
  200.     kbst.fsMask |=  (KEYBOARD_ECHO_OFF | KEYBOARD_BINARY_MODE);
  201.     KbdSetStatus(&kbst, 0);
  202. #endif
  203. }
  204. void ttcooked(void)
  205. {
  206. #ifndef __EMX__
  207.     KbdSetStatus(&kbst_std, 0);
  208. #endif
  209. }
  210. #endif
  211.     
  212.  /*
  213. * Write a character to the display. On VMS, terminal output is buffered, and
  214. * we just put the characters in the big array, after checking for overflow.
  215. * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  216. * MS-DOS (use the very very raw console output routine).
  217. */
  218.  
  219. #ifdef OS2
  220. int tty_io_size = 0;
  221. char tty_io_buffer[2048];
  222. #endif
  223.  
  224. int
  225. ttputc (c)
  226. {
  227. #ifdef OS2
  228.     if ( tty_io_size == sizeof(tty_io_buffer) )
  229.     {
  230.         write(1, tty_io_buffer, tty_io_size);
  231.         tty_io_size = 0;
  232.     }
  233.     tty_io_buffer[tty_io_size++] = c;
  234. #else
  235.     fputc (c, stdout);
  236. #endif
  237.     return c;
  238. }
  239.  
  240.  /*
  241. * Flush terminal buffer. Does real work where the terminal output is buffered
  242. * up. A no-operation on systems where byte at a time terminal I/O is done.
  243. */
  244. void
  245. ttflush ()
  246. {
  247. #ifdef OS2
  248.     if ( tty_io_size )
  249.     {
  250.         write(1, tty_io_buffer, tty_io_size);
  251.         tty_io_size = 0;
  252.     }
  253. #else
  254.     fflush (stdout);
  255. #endif
  256. }
  257.  
  258.  /*
  259. * Read a character from the terminal, performing no editing and doing no echo
  260. * at all. More complex in VMS that almost anyplace else, which figures. Very
  261. * simple on CPM, because the system can do exactly what you want.
  262. */
  263.  
  264. #ifdef OS2
  265. #ifdef __EMX__
  266. static int chr = -1;
  267. #endif
  268. #endif
  269.  
  270. ttgetc ()
  271. {
  272. #ifdef OS2
  273. #ifdef __EMX__
  274.     if ( chr != -1 )
  275.     {
  276.     int c = chr;
  277.     chr = -1;
  278.     return c;
  279.     }
  280.     else
  281.         return _read_kbd(0, 1, 0);
  282. #else
  283.     static int ext, scan, chr;
  284.     KBDKEYINFO ki;
  285.  
  286.     if ( ext )
  287.     {
  288.     ext = 0;
  289.     return scan;
  290.     }
  291.     else
  292.     {
  293.     ttflush();
  294.     KbdCharIn(&ki, IO_WAIT, 0);
  295.  
  296.     if ( ki.chChar == 0 || ki.chChar == 0xE0 )
  297.     {
  298.         ext = 1;
  299.         scan = ki.chScan;
  300.         return 0xE0;
  301.     }
  302.     else
  303.       return ki.chChar;
  304.     }
  305. #endif
  306. #else
  307.     if (kbdqp)
  308.     kbdqp = FALSE;
  309.     else
  310.     {
  311. #ifdef BSD
  312.     int count;
  313.  
  314.     if (kbdpoll && (ioctl (0, FIONREAD, &count), count == 0))
  315.         return FALSE;
  316.     read (0, &kbdq, 1);
  317. #else
  318.     if (kbdpoll && fcntl (0, F_SETFL, kbdflgs) < 0)
  319.         return FALSE;
  320.     kbdpoll = FALSE;
  321.     while (read (0, &kbdq, 1) != 1)
  322.         ;
  323. #endif
  324.     }
  325.     return (kbdq & 127);
  326. #endif /* OS2 */
  327. }
  328.  
  329.  /* typahead():    Check to see if any characters are already in the
  330.  keyboard buffer
  331. */
  332. ttkeyready ()
  333. {
  334. #ifdef OS2
  335. #ifdef __EMX__
  336.     chr = _read_kbd(0, 0, 0);
  337.     return (chr != -1);
  338. #else
  339.     KBDKEYINFO ki;
  340.  
  341.     KbdPeek(&ki, 0);
  342.     return (ki.fbStatus != 0);
  343. #endif
  344. #else
  345.     if (!kbdqp)
  346.     {
  347. #ifdef BSD
  348.     int count;
  349.  
  350.     if (!kbdpoll && (ioctl (0, FIONREAD, &count), count == 0))
  351.         return FALSE;
  352.     kbdpoll = TRUE;        /*  fix in 1.13 */
  353.     kbdqp = TRUE;
  354. #else
  355. #ifdef X_MINIX
  356.     /* MINIX has non-blocking mode but it doesn't work !?!? */
  357.         return FALSE;
  358. #else
  359.     if (!kbdpoll && fcntl (0, F_SETFL, kbdflgs | O_NDELAY) < 0)
  360.         return (FALSE);
  361.     kbdpoll = TRUE;        /*  fix in 1.13 */
  362.     kbdqp = (1 == read (0, &kbdq, 1));
  363. #endif /* MINIX */
  364. #endif /* BSD */
  365.  
  366.     }
  367.     return (kbdqp);
  368. #endif /* OS2 */
  369. }
  370.  
  371. #endif
  372.