home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / uemacs / part4 / sys / vms / ttyio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  4.5 KB  |  177 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *        VAX/VMS terminal I/O.
  4.  * Version:    29
  5.  * Last edit:    05-Feb-86
  6.  * By:        rex::conroy
  7.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  8.  */
  9. #include    "def.h"
  10.  
  11. #include    <stsdef.h>
  12. #include    <ssdef.h>
  13. #include    <descrip.h>
  14. #include    <iodef.h>
  15. #include    <ttdef.h>
  16. #include    <tt2def.h>
  17.  
  18. #define    NIBUF    128            /* Probably excessive.        */
  19. #define    NOBUF    512            /* Not too big for 750/730.    */
  20. #define    EFN    0            /* Event flag            */
  21.  
  22. char    obuf[NOBUF];            /* Output buffer        */
  23. int    nobuf;                /* # of bytes in above        */
  24. char    ibuf[NIBUF];            /* Input buffer            */
  25. int    nibuf;                /* # of bytes in above        */
  26. int    ibufi;                /* Read index            */
  27. int    oldmode[3];            /* Old TTY mode bits        */
  28. int    newmode[3];            /* New TTY mode bits        */
  29. short    iochan;                /* TTY I/O channel        */
  30. int    nrow;                /* Terminal size, rows.        */
  31. int    ncol;                /* Terminal size, columns.    */
  32.  
  33. /*
  34.  * This routines gets called once, to set up the
  35.  * terminal channel.
  36.  * On VMS we find the translation of the SYS$COMMAND: logical name,
  37.  * assign a channel to it, and set it raw. Let VMS handle the flow
  38.  * control.
  39.  */
  40. ttopen()
  41. {
  42.     struct    dsc$descriptor    idsc;
  43.     struct    dsc$descriptor    odsc;
  44.     char    oname[40];
  45.     int    iosb[2];
  46.     int    status;
  47.  
  48.     odsc.dsc$a_pointer = "SYS$COMMAND";
  49.     odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  50.     odsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  51.     odsc.dsc$b_class   = DSC$K_CLASS_S;
  52.     idsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  53.     idsc.dsc$b_class   = DSC$K_CLASS_S;
  54.     do {
  55.         idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  56.         idsc.dsc$w_length  = odsc.dsc$w_length;
  57.         odsc.dsc$a_pointer = &oname[0];
  58.         odsc.dsc$w_length  = sizeof(oname);
  59.         status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  60.         if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  61.             exit(status);
  62.         if (oname[0] == 0x1B) {
  63.             odsc.dsc$a_pointer += 4;
  64.             odsc.dsc$w_length  -= 4;
  65.         }
  66.     } while (status == SS$_NORMAL);
  67.     status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  68.     if (status != SS$_NORMAL)
  69.         exit(status);
  70.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  71.               oldmode, sizeof(oldmode), 0, 0, 0, 0);
  72.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  73.         exit(status);
  74.     nrow = (oldmode[1]>>24) & 0xFF;        /* Length.        */
  75.     if (nrow > NROW)
  76.         nrow = NROW;
  77.     ncol = (oldmode[0]>>16) & 0xFFFF;    /* Width.        */
  78.     if (ncol > NCOL)
  79.         ncol = NCOL;
  80.     newmode[0] = oldmode[0];        /* Only in version 4.    */
  81.     newmode[1] = oldmode[1] | TT$M_NOECHO | TT$M_TTSYNC;
  82.     newmode[2] = oldmode[2] | TT2$M_PASTHRU;
  83.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  84.               newmode, sizeof(newmode), 0, 0, 0, 0);
  85.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  86.         exit(status);
  87. }
  88.  
  89. /*
  90.  * This function gets called just
  91.  * before we go back home to the command interpreter.
  92.  * On VMS it puts the terminal back in a reasonable state.
  93.  */
  94. ttclose()
  95. {
  96.     int    status;
  97.     int    iosb[1];
  98.  
  99.     ttflush();
  100.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  101.              oldmode, sizeof(oldmode), 0, 0, 0, 0);
  102.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  103.         exit(status);
  104.     status = SYS$DASSGN(iochan);
  105.     if (status != SS$_NORMAL)
  106.         exit(status);
  107. }
  108.  
  109. /*
  110.  * Write a character to the display.
  111.  * On VMS, terminal output is buffered, and
  112.  * we just put the characters in the big array,
  113.  * after cheching for overflow.
  114.  */
  115. ttputc(c)
  116. {
  117.     if (nobuf >= NOBUF)
  118.         ttflush();
  119.     obuf[nobuf++] = c;
  120. }
  121.  
  122. /*
  123.  * This function does the real work of
  124.  * flushing out buffered I/O on VMS. All
  125.  * we do is blast out the block with a write call. No status
  126.  * checking is done on the write, because there isn't anything
  127.  * clever that can be done, and because you will see the
  128.  * error as a messed up screen.
  129.  */
  130. ttflush()
  131. {
  132.     int    iosb[2];
  133.  
  134.     if (nobuf != 0) {
  135.         SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  136.         iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  137.         nobuf = 0;
  138.     }
  139. }
  140.  
  141. /*
  142.  * Read a character from the terminal,
  143.  * performing no editing and doing no echo at all.
  144.  * More complex in VMS that almost anyplace else, which
  145.  * figures.
  146.  */
  147. ttgetc()
  148. {
  149.     int    status;
  150.     int    iosb[2];
  151.     int    term[2];
  152.  
  153.     term[0] = 0;
  154.     term[1] = 0;
  155.     while (ibufi >= nibuf) {
  156.         ibufi   = 0;
  157.         status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  158.              iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  159.         if (status != SS$_NORMAL)
  160.             continue;
  161.         status = iosb[0] & 0xFFFF;
  162.         if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  163.             continue;
  164.         nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  165.         if (nibuf == 0) {
  166.             status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
  167.                 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  168.             if (status != SS$_NORMAL)
  169.                 continue;
  170.             if ((iosb[0]&0xFFFF) != SS$_NORMAL)
  171.                 continue;
  172.             nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  173.         }
  174.     }
  175.     return (ibuf[ibufi++] & 0xFF);
  176. }
  177.