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