home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 198_02 / termio.c < prev    next >
C/C++ Source or Header  |  1990-01-23  |  19KB  |  731 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. #include        <stdio.h>
  7. #include    "estruct.h"
  8. #include        "edef.h"
  9.  
  10. #if   MSDOS & TURBO
  11. #include <conio.h>
  12. #endif
  13.  
  14. #if     AMIGA
  15. #define NEW 1006L
  16. #define AMG_MAXBUF      1024L
  17. static long terminal;
  18. static char     scrn_tmp[AMG_MAXBUF+1];
  19. static long     scrn_tmp_p = 0;
  20. #endif
  21.  
  22. #if ST520 & MEGAMAX
  23. #include <osbind.h>
  24.     int STscancode = 0;    
  25. #endif
  26.  
  27. #if     VMS
  28. #include        <stsdef.h>
  29. #include        <ssdef.h>
  30. #include        <descrip.h>
  31. #include        <iodef.h>
  32. #include        <ttdef.h>
  33. #include    <tt2def.h>
  34.  
  35. #define EFN     0                       /* Event flag                   */
  36.  
  37. char    obuf[NOBUF];                    /* Output buffer                */
  38. int     nobuf;                  /* # of bytes in above    */
  39. char    ibuf[NIBUF];                    /* Input buffer          */
  40. int     nibuf;                  /* # of bytes in above  */
  41. int     ibufi;                  /* Read index                   */
  42. int     oldmode[3];                     /* Old TTY mode bits            */
  43. int     newmode[3];                     /* New TTY mode bits            */
  44. short   iochan;                  /* TTY I/O channel             */
  45. #endif
  46.  
  47. #if     CPM
  48. #include        <bdos.h>
  49. #endif
  50.  
  51. #if     MSDOS & (LATTICE | MSC | TURBO | AZTEC | MWC86 | C86)
  52. union REGS rg;        /* cpu register for use of DOS calls */
  53. int nxtchar = -1;    /* character held from type ahead    */
  54. #endif
  55.  
  56. #if RAINBOW
  57. #include "rainbow.h"
  58. #endif
  59.  
  60. #if    USG            /* System V */
  61. #include    <signal.h>
  62. #include    <termio.h>
  63. #include    <fcntl.h>
  64. struct    termio    otermio;    /* original terminal characteristics */
  65. struct    termio    ntermio;    /* charactoristics to use inside */
  66.  
  67. #if MSC
  68. /* #include <sgtty.h> */    /* not needed */
  69. #undef FIOCLEX
  70. #undef FIONCLEX
  71. #include <sys/ioctl.h>
  72.  
  73. int tafd;            /* extra fd opened with no wait    */
  74. int fcstat;            /* saved fcntl status        */
  75. #define    NIBUF    63
  76. char    ibuf[NIBUF];            /* Input buffer          */
  77. int     nibuf = 0;              /* # of bytes in above  */
  78. int     ibufi = 0;              /* Read index                   */
  79. #else
  80. int kbdflgs;            /* saved keyboard fd flags    */
  81. int kbdpoll;            /* in O_NDELAY mode            */
  82. int kbdqp;            /* there is a char in kbdq    */
  83. char kbdq;            /* char we've already read    */
  84. #endif
  85. #endif
  86.  
  87. #if V7 | BSD
  88. #undef    CTRL
  89. #include        <sgtty.h>        /* for stty/gtty functions */
  90. #include    <signal.h>
  91. struct  sgttyb  ostate;          /* saved tty state */
  92. struct  sgttyb  nstate;          /* values for editor mode */
  93. struct tchars    otchars;    /* Saved terminal special character set */
  94. struct tchars    ntchars = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  95. #endif
  96.                 /* A lot of nothing */
  97. #if BSD
  98. #include <sys/ioctl.h>        /* to get at the typeahead */
  99. extern    int rtfrmshell();    /* return from suspended shell */
  100. #if BSD29
  101. #else
  102. #define    TBUFSIZ    128
  103. char tobuf[TBUFSIZ];        /* terminal output buffer */
  104. #endif
  105. #endif
  106.  
  107. extern int termflag;
  108.  
  109. /*
  110.  * This function is called once to set up the terminal device streams.
  111.  * On VMS, it translates TT until it finds the terminal, then assigns
  112.  * a channel to it and sets it raw. On CPM it is a no-op.
  113.  */
  114. ttopen()
  115. {
  116. #if     AMIGA
  117.     char oline[NSTRING];
  118. #if    AZTEC
  119.     extern    Enable_Abort;    /* Turn off ctrl-C interrupt */
  120.  
  121.     Enable_Abort = 0;    /* for the Manx compiler */
  122. #endif
  123.     strcpy(oline, "RAW:0/0/640/200/");
  124.     strcat(oline, PROGNAME);
  125.     strcat(oline, " ");
  126.     strcat(oline, VERSION);
  127.     strcat(oline, "/Amiga");
  128.         terminal = Open(oline, NEW);
  129. #endif
  130. #if     VMS
  131.         struct  dsc$descriptor  idsc;
  132.         struct  dsc$descriptor  odsc;
  133.         char    oname[40];
  134.         int     iosb[2];
  135.         int     status;
  136.  
  137.         odsc.dsc$a_pointer = "TT";
  138.         odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  139.         odsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  140.         odsc.dsc$b_class        = DSC$K_CLASS_S;
  141.         idsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  142.         idsc.dsc$b_class        = DSC$K_CLASS_S;
  143.         do {
  144.                 idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  145.                 idsc.dsc$w_length  = odsc.dsc$w_length;
  146.                 odsc.dsc$a_pointer = &oname[0];
  147.                 odsc.dsc$w_length  = sizeof(oname);
  148.                 status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  149.                 if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  150.                         exit(status);
  151.                 if (oname[0] == 0x1B) {
  152.                         odsc.dsc$a_pointer += 4;
  153.                         odsc.dsc$w_length  -= 4;
  154.                 }
  155.         } while (status == SS$_NORMAL);
  156.         status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  157.         if (status != SS$_NORMAL)
  158.                 exit(status);
  159.  
  160.     /* sense mode returns:
  161.      *    mode[0] :0-7 = class, :8-15 = type, :16-31 = width
  162.      *    mode[1] :0-23 = characteristics, :24-31 = length
  163.      */
  164.  
  165.         status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  166.                           oldmode, sizeof(oldmode), 0, 0, 0, 0);
  167.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  168.                 exit(status);
  169.         newmode[0] = oldmode[0];
  170.         newmode[1] = oldmode[1] /* | TT$M_NOECHO */ ;
  171.         newmode[2] = oldmode[2];
  172.     if (!termflag) {
  173.             newmode[1] &= ~(TT$M_TTSYNC|TT$M_HOSTSYNC);
  174.             newmode[2] |= TT2$M_PASTHRU;
  175.     }
  176.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  177.                           newmode, sizeof(newmode), 0, 0, 0, 0);
  178.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  179.                 exit(status);
  180.         term.t_nrow = (newmode[1]>>24) - 1;
  181.     if (term.t_nrow > term.t_mrow) term.t_mrow = term.t_nrow;
  182.         term.t_ncol = newmode[0]>>16;
  183.     if (term.t_ncol > term.t_mcol) term.t_mcol = term.t_ncol;
  184. #endif
  185. #if     CPM
  186. #endif
  187.  
  188. #if     MSDOS & (HP150 == 0) & LATTICE
  189.     /* kill the ctrl-break interupt */
  190.     rg.h.ah = 0x33;        /* control-break check dos call */
  191.     rg.h.al = 1;        /* set the current state */
  192.     rg.h.dl = 0;        /* set it OFF */
  193.     intdos(&rg, &rg);    /* go for it! */
  194. #endif
  195.  
  196. #if    USG
  197.     ioctl(0, TCGETA, &otermio);    /* save old settings */
  198.     ntermio.c_oflag = 0;        /* setup new settings */
  199.     if (termflag)
  200.         ntermio.c_iflag = otermio.c_iflag & (IXON|IXANY|IXOFF);
  201.     else
  202.         ntermio.c_iflag = 0;
  203.     ntermio.c_cflag = otermio.c_cflag;
  204.     ntermio.c_lflag = 0;
  205.     ntermio.c_line = otermio.c_line;
  206.     ntermio.c_cc[VMIN] = 1;
  207.     ntermio.c_cc[VTIME] = 0;
  208.     ioctl(0, TCSETAW, &ntermio);    /* and activate them */
  209. #ifdef    TCXONC
  210.     /* ioctl(0, TCXONC, 1);    */    /* restart suspended (^S'ed) output */
  211. #endif
  212. #if    MSC
  213.     tafd = open("/dev/tty", O_RDONLY, 0);
  214.     ioctl(tafd, TCSETA, &ntermio);    /* and activate them */
  215.     fcstat = fcntl(tafd, F_GETFL, 0);
  216.     fcntl(tafd, F_SETFL, fcstat | O_NDELAY);
  217. #else
  218.     kbdflgs = fcntl( 0, F_GETFL, 0 );
  219.     kbdpoll = FALSE;
  220. #endif
  221. #endif
  222.  
  223. #if     V7 | BSD
  224.         gtty(0, &ostate);                       /* save old state */
  225.         gtty(0, &nstate);                       /* get base of new state */
  226.         nstate.sg_flags |= RAW;
  227.         nstate.sg_flags &= ~(ECHO|CRMOD);       /* no echo for now... */
  228.         stty(0, &nstate);                       /* set mode */
  229.     ioctl(0, TIOCGETC, &otchars);        /* Save old characters */
  230.     ioctl(0, TIOCSETC, &ntchars);        /* Place new character into K */
  231. #endif
  232. #if    BSD
  233. #if    BSD29
  234. #else
  235.     /* provide a smaller terminal output buffer so that
  236.        the type ahead detection works better (more often) */
  237.     setbuffer(stdout, &tobuf[0], TBUFSIZ);
  238. #ifdef    _IONBF
  239.     setvbuf(stdin, NULL, _IONBF, 0);
  240. #endif
  241. #endif
  242.     signal(SIGTSTP,SIG_DFL);    /* set signals so that we can */
  243.     signal(SIGCONT,rtfrmshell);    /* suspend & restart emacs */
  244. #endif
  245.     /* on all screens we are not sure of the initial position
  246.        of the cursor                    */
  247.     ttrow = 999;
  248.     ttcol = 999;
  249. }
  250.  
  251. /*
  252.  * This function gets called just before we go back home to the command
  253.  * interpreter. On VMS it puts the terminal back in a reasonable state.
  254.  * Another no-operation on CPM.
  255.  */
  256. ttclose()
  257. {
  258. #if     AMIGA
  259. #if    LATTICE
  260.         amg_flush();
  261.         Close(terminal);
  262. #endif
  263. #if    AZTEC
  264.         amg_flush();
  265.     Enable_Abort = 1;    /* Fix for Manx */
  266.         Close(terminal);
  267. #endif
  268. #endif
  269.  
  270. #if     VMS
  271.         int     status;
  272.         int     iosb[2];
  273.  
  274.         ttflush();
  275. #if    1
  276. #else
  277.     SYS$QIOW(EFN+1, iochan, IO$_WRITELBLK | IO$M_NOFORMAT,
  278.         0, 0, 0, "", 1, 0, 0, 0, 0);
  279. #endif
  280.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  281.                  oldmode, sizeof(oldmode), 0, 0, 0, 0);
  282.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  283.                 exit(status);
  284.         status = SYS$DASSGN(iochan);
  285.         if (status != SS$_NORMAL)
  286.                 exit(status);
  287. #endif
  288. #if     CPM
  289. #endif
  290. #if     MSDOS & (HP150 == 0) & LATTICE
  291.     /* restore the ctrl-break interupt */
  292.     rg.h.ah = 0x33;        /* control-break check dos call */
  293.     rg.h.al = 1;        /* set the current state */
  294.     rg.h.dl = 1;        /* set it ON */
  295.     intdos(&rg, &rg);    /* go for it! */
  296. #endif
  297.  
  298. #if    USG
  299. #if    MSC
  300.     fcntl(tafd, F_SETFL, fcstat);
  301.     ioctl(tafd, TCSETA, &otermio);    /* restore terminal settings */
  302. #else
  303.     fcntl(0, F_SETFL, kbdflgs);
  304. #endif
  305.  
  306.     ioctl(0, TCSETA, &otermio);    /* restore terminal settings */
  307. #endif
  308.  
  309. #if     V7 | BSD
  310.         stty(0, &ostate);
  311.     ioctl(0, TIOCSETC, &otchars);    /* Place old character into K */
  312. #endif
  313. }
  314.  
  315. /*
  316.  * Write a character to the display. On VMS, terminal output is buffered, and
  317.  * we just put the characters in the big array, after checking for overflow.
  318.  * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  319.  * MS-DOS (use the very very raw console output routine).
  320.  */
  321. ttputc(c)
  322. #if     AMIGA | (ST520 & MEGAMAX)
  323.         char c;
  324. #endif
  325. {
  326. #if     AMIGA
  327.         scrn_tmp[scrn_tmp_p++] = c;
  328.         if(scrn_tmp_p>=AMG_MAXBUF)
  329.                 amg_flush();
  330. #endif
  331. #if    ST520 & MEGAMAX
  332.     Bconout(2,c);
  333. #endif
  334. #if     VMS
  335.         if (nobuf >= NOBUF)
  336.                 ttflush();
  337.         obuf[nobuf++] = c;
  338. #endif
  339.  
  340. #if     CPM
  341.         bios(BCONOUT, c, 0);
  342. #endif
  343.  
  344. #if     MSDOS & MWC86
  345.         putcnb(c);
  346. #endif
  347.  
  348. #if    MSDOS & (LATTICE | AZTEC | MSC | TURBO) /* & ~IBMPC */
  349.     bdos(6, c, 0);
  350. #endif
  351.  
  352. #if    MSDOS & C86
  353.     bdos(6, (long) c);
  354. #endif
  355.  
  356. #if RAINBOW
  357.         Put_Char(c);                    /* fast video */
  358. #endif
  359.  
  360.  
  361. #if     V7 | USG | BSD | DECUSC
  362.         putc(c, stdout);
  363. #endif
  364.  
  365. }
  366.  
  367. #if    AMIGA
  368. amg_flush()
  369. {
  370.         if(scrn_tmp_p)
  371.                 Write(terminal,scrn_tmp,scrn_tmp_p);
  372.         scrn_tmp_p = 0;
  373. }
  374. #endif
  375.  
  376. /*
  377.  * Flush terminal buffer. Does real work where the terminal output is buffered
  378.  * up. A no-operation on systems where byte at a time terminal I/O is done.
  379.  */
  380. ttflush()
  381. {
  382. #if     AMIGA
  383.         amg_flush();
  384. #endif
  385. #if     VMS
  386.         int     status;
  387.         int     iosb[2];
  388.  
  389.         status = SS$_NORMAL;
  390.         if (nobuf != 0) {
  391. #if 1
  392.                 status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  393.                          iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  394.                 if (status == SS$_NORMAL)
  395.                         status = iosb[0] & 0xFFFF;
  396. #else
  397.                 status = SYS$QIO(EFN+1, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  398.                          0, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  399. #endif
  400.                 nobuf = 0;
  401.         }
  402.         return (status);
  403. #endif
  404.  
  405. #if     CPM
  406. #endif
  407.  
  408. #if     MSDOS
  409. #endif
  410.  
  411. #if     V7 | USG | BSD | DECUSC
  412.         fflush(stdout);
  413. #endif
  414. }
  415.  
  416. /*
  417.  * Read a character from the terminal, performing no editing and doing no echo
  418.  * at all. More complex in VMS that almost anyplace else, which figures. Very
  419.  * simple on CPM, because the system can do exactly what you want.
  420.  */
  421. ttgetc()
  422. {
  423. #if     AMIGA
  424.         char ch;
  425.         amg_flush();
  426.         Read(terminal, &ch, 1L);
  427.         return(255 & (int)ch);
  428. #endif
  429. #if    ST520 & MEGAMAX
  430.     long ch;
  431. /*
  432.  * blink the cursor only if nothing is happening, this keeps the
  433.  * cursor on steadily during movement making it easier to track
  434.  */
  435.     STcurblink(TRUE);  /* the cursor blinks while we wait */
  436.     ch = Bconin(2);
  437.     STcurblink(FALSE); /* the cursor is steady while we work */
  438.     STscancode = (ch >> 16) & 0xff;
  439.            return(255 & (int)ch);
  440. #endif
  441. #if     VMS
  442.         int     status;
  443.         int     iosb[2];
  444.         int     term[2];
  445.  
  446.         while (ibufi >= nibuf) {
  447.                 ibufi = 0;
  448.                 term[0] = 0;
  449.                 term[1] = 0;
  450.                 status = SYS$QIOW(EFN, iochan,
  451.              IO$_READLBLK|IO$M_TIMED|IO$M_NOFILTR|IO$M_NOECHO,
  452.                          iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  453.                 if (status != SS$_NORMAL && status != SS$_DATAOVERUN)
  454.                         if (!termflag) exit(status);
  455.                 status = iosb[0] & 0xFFFF;
  456.                 if (status!=SS$_NORMAL && status!=SS$_DATAOVERUN &&
  457.             status!=SS$_TIMEOUT)
  458.                         if (!termflag) exit(status);
  459.                 nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  460.                 if (nibuf == 0) {
  461.                         status = SYS$QIOW(EFN, iochan,
  462.                  IO$_READLBLK|IO$M_NOFILTR|IO$M_NOECHO,
  463.                                  iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  464.                         if ((status != SS$_NORMAL && status != SS$_DATAOVERUN)
  465.                         || (((status = (iosb[0]&0xFFFF)) != SS$_NORMAL) &&
  466.                 (status != SS$_DATAOVERUN)))
  467.                                 if (!termflag) exit(status);
  468.                         nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  469.                 }
  470.         }
  471.         return (ibuf[ibufi++] & 0xFF);    /* Allow multinational  */
  472. #endif
  473.  
  474. #if     CPM
  475.         return (biosb(BCONIN, 0, 0));
  476. #endif
  477.  
  478. #if RAINBOW
  479.         int Ch;
  480.  
  481.         while ((Ch = Read_Keyboard()) < 0);
  482.  
  483.         if ((Ch & Function_Key) == 0)
  484.                 if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177))
  485.                         Ch &= 0xFF;
  486.  
  487.         return Ch;
  488. #endif
  489.  
  490. #if     MSDOS & MWC86
  491.         return (getcnb());
  492. #endif
  493.  
  494. #if    MSDOS & (LATTICE | MSC | TURBO | AZTEC | C86)
  495.     int c;        /* character read */
  496.  
  497.     /* if a char already is ready, return it */
  498.     if (nxtchar >= 0) {
  499.         c = nxtchar;
  500.         nxtchar = -1;
  501.         return(c);
  502.     }
  503.  
  504.     /* call the dos to get a char */
  505.     rg.h.ah = 7;        /* dos Direct Console Input call */
  506.     intdos(&rg, &rg);
  507.     c = rg.h.al;        /* grab the char */
  508.     return(c & 255);
  509. #endif
  510.  
  511. #if     V7 | BSD
  512.         return(127 & fgetc(stdin));
  513. #endif
  514.  
  515. #if    USG
  516. #if    MSC
  517.         /* 
  518.          * if (nxtchar >= 0) {c = nxtchar; nxtchar = -1;}
  519.          * else read(0, &c, sizeof(c));
  520.          */
  521.         int count;
  522.     if (ibufi >= nibuf) {
  523.         ibufi = nibuf = 0;
  524.         while(nibuf < NIBUF &&
  525.               (count = read(tafd, &ibuf[nibuf], NIBUF-nibuf)) > 0)
  526.             nibuf += count;
  527.         if (nibuf <= 0)
  528.             read(0, ibuf, sizeof(char));
  529.     }
  530.     return (ibuf[ibufi++] & 0xFF);
  531. #else
  532.     if( kbdqp )
  533.         kbdqp = FALSE;
  534.     else
  535.     {
  536.         /* reset mode */
  537.         if( fcntl( 0, F_SETFL, kbdflgs ) < 0 && kbdpoll )
  538.             return FALSE;
  539.         kbdpoll = FALSE;        /* no polling */
  540.         read(0, &kbdq, 1) != 1;        /* wait until it gets a char */
  541.     }
  542.     return ( kbdq & 127 );
  543. #endif
  544. #endif
  545.  
  546. #if    DECUSC
  547.     return( kbin() );
  548. #endif
  549. }
  550.  
  551. #if    TYPEAH
  552.         /* & (~ST520 | ~LATTICE) */
  553. /* typahead:    Check to see if any characters are already in the
  554.         keyboard buffer
  555. */
  556.  
  557. #if    VMS
  558. int tacnt = 0;
  559. #endif
  560.  
  561. typahead()
  562.  
  563. {
  564. #if    MSDOS & (MSC | TURBO)
  565.     if (kbhit() != 0)
  566.         return(TRUE);
  567.     else
  568.         return(FALSE);
  569. #endif
  570.  
  571. #if    MSDOS & (LATTICE | AZTEC | MWC86 | C86)
  572.     int c;        /* character read */
  573.     int flags;    /* cpu flags from dos call */
  574.  
  575.     if (nxtchar >= 0)
  576.         return(TRUE);
  577.  
  578.     rg.h.ah = 6;    /* Direct Console I/O call */
  579.     rg.h.dl = 255;    /*         does console input */
  580. #if    LATTICE | AZTEC | C86
  581.     flags = intdos(&rg, &rg);
  582. #else
  583.     intcall(&rg, &rg, 0x21);
  584.     flags = rg.x.flags;
  585. #endif
  586.     c = rg.h.al;    /* grab the character */
  587.  
  588.     /* no character pending */
  589.     if ((flags & 64) != 0)
  590.         return(FALSE);
  591.  
  592.     /* save the character and return true */
  593.     nxtchar = c;
  594.     return(TRUE);
  595. #endif
  596.  
  597. #if    BSD
  598.     int x;    /* holds # of pending chars */
  599.  
  600.     return((ioctl(0,FIONREAD,&x) < 0) ? 0 : x);
  601. #endif
  602.  
  603. #if    USG
  604. #if    MSC
  605.     int count;
  606.  
  607.     /* if (nxtchar >= 0) return(TRUE);
  608.      * if (read(tafd, &c, sizeof(c)) == sizeof(c)) {
  609.      *    nxtchar = c & 127;
  610.      *    return(TRUE);
  611.      * }
  612.      */
  613.      
  614.     if (ibufi >= nibuf) {
  615.         ibufi = nibuf = 0;
  616.         while(nibuf < NIBUF &&
  617.               (count = read(tafd, &ibuf[nibuf], NIBUF-nibuf)) > 0)
  618.             nibuf += count;
  619.     }
  620.     return(ibufi < nibuf);
  621. #else
  622.     if( !kbdqp )
  623.     {
  624.         /* set O_NDELAY mode */
  625.         if( fcntl( 0, F_SETFL, kbdflgs | O_NDELAY ) < 0 && !kbdpoll)
  626.             return(FALSE);
  627.         kbdqp = (1 == read( 0, &kbdq, 1 ));
  628.         kbdpoll = TRUE;    /* polling */
  629.     }
  630.     return ( kbdqp );
  631. #endif
  632. #endif
  633.  
  634. #if    VMS
  635.     int    iosb[2], tabuffer[2], term[2], status;
  636.  
  637.     /* check for unread chars in input buffer */
  638.  
  639.         if (ibufi < nibuf) return(TRUE);
  640.  
  641.     /* only do inquire every few times because of how slow it is */
  642.  
  643.     if (tacnt-- > 0) return(FALSE);
  644.  
  645.     tacnt = 5;
  646.  
  647.     /* type ahead count returns:
  648.      *    buffer[0] :0-15 = count :16-23 = first char :24-31 reserved
  649.      *    buffer[1] reserved
  650.      */
  651.  
  652.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE|IO$M_TYPEAHDCNT,
  653.             iosb, 0, 0, tabuffer, 0, 0, 0, 0, 0);
  654.  
  655.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  656.         return(FALSE);
  657.  
  658.     if ((tabuffer[0] & 0xFFFF) == 0) return(FALSE);
  659.  
  660.     ibufi = 0;
  661.     term[0] = 0;
  662.     term[1] = 0;
  663.     status = SYS$QIOW(EFN, iochan,
  664.             IO$_READLBLK|IO$M_TIMED|IO$M_NOFILTR|IO$M_NOECHO,
  665.             iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  666.     if (status != SS$_NORMAL && status != SS$_DATAOVERUN)
  667.         if (!termflag) exit(status);
  668.     status = iosb[0] & 0xFFFF;
  669.     if (status!=SS$_NORMAL && status!=SS$_DATAOVERUN &&
  670.         status!=SS$_TIMEOUT)
  671.         if (!termflag) exit(status);
  672.     nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  673.  
  674.     return( (nibuf > 0) ? TRUE : FALSE );
  675. #endif
  676.     return(FALSE);
  677. }
  678. #endif
  679.  
  680. #if    VMSVT | TERMCAP
  681. ttsetwid(n)
  682. int n; {
  683.     if (isvt100 == TRUE) {
  684.         ttputc('\033'); ttputc('['); ttputc('?'); ttputc('3');
  685.         if (n > 80) ttputc('h'); else ttputc('l');
  686.     }
  687. }
  688.  
  689. ttscroll(rowa, rowb, lines)
  690. int rowa, rowb, lines;
  691. {
  692.     if (isvt100 == TRUE) {
  693.         ++rowa; ++rowb;
  694.         if (lines == 0 || rowa != scrltop || rowb != scrlbot) {
  695.             scrltop = rowa;
  696.             scrlbot = rowb;
  697.  
  698.             /* define scrolling region: CSI top ; bot r */
  699.             ttputc(27); ttputc('[');
  700.             if (rowa >= 10) ttputc('0' + rowa / 10);
  701.             ttputc('0' + rowa % 10); ttputc(';');
  702.             if (rowb >= 10) ttputc('0' + rowb / 10);
  703.             ttputc('0' + rowb % 10); ttputc('r');
  704.             phrow = 1000;
  705.         }
  706.  
  707.         if (lines > 0) {
  708.             /* scroll up: CSI bot H, and then n X nl */
  709.             if (rowb != phrow+1) {
  710.                 ttputc(27); ttputc('[');
  711.                 if (rowb >= 10) ttputc('0' + rowb / 10);
  712.                 ttputc('0' + rowb % 10); ttputc('H');
  713.                 phrow = rowb-1;
  714.             }
  715.             while (lines-- > 0) ttputc(10);
  716.         }
  717.         else if (lines < 0) {
  718.             /* scroll down: CSI top H, and then n X ESC M */
  719.             if (rowa != phrow+1) {
  720.                 ttputc(27); ttputc('[');
  721.                 if (rowa >= 10) ttputc('0' + rowa / 10);
  722.                 ttputc('0' + rowa % 10); ttputc('H');
  723.                 phrow = rowa-1;
  724.             }
  725.             while (lines++ < 0) {ttputc(27); ttputc('M');}
  726.         }
  727.         ttrow = 1000;
  728.     }
  729. }
  730. #endif
  731.