home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume1 / rogue / patch3 / vmsterm.c < prev    next >
C/C++ Source or Header  |  1992-01-13  |  6KB  |  357 lines

  1. #ifdef VMS
  2.  
  3.  
  4. /*
  5.  *    VMSTERM.C
  6.  *
  7.  *    Copyright (c) 1991 by Michael S Zraly.
  8.  *
  9.  *    Some of the details in this code were derived from code
  10.  *    for the games larn, copyright 1986 by Noah Morgan (as
  11.  *    adapted by Kevin Routley), and nethack, copyright 1985
  12.  *    by the Stichting Mathematisch centrum, Amsterdam.
  13.  *
  14.  *    Permission is granted to distribute and modify this source
  15.  *    Permission is granted to distribute and modify this source
  16.  *    freely, provided that no charge is made for doing so and
  17.  *    that this comment remains untouched.
  18.  *
  19.  *    Last Modified:    21 August 1991
  20.  */
  21.  
  22.  
  23. #include    <descrip.h>
  24. #include    "vmsterm.h"
  25.  
  26.  
  27. #define    TT_BUFSIZ    80
  28.  
  29.  
  30. /*
  31.  *    I/o func codes passed to SYS$QIO() or SYS$QIOW():
  32.  */
  33. #define    TT_NOPURGE    (IO$_READLBLK|IO$M_NOFILTR|IO$M_TIMED|IO$M_NOECHO)
  34. #define    TT_PURGE    ((TT_NOPURGE)|(IO$M_PURGE))
  35.  
  36.  
  37. /*
  38.  *    Default terminal characteristics
  39.  */
  40. #define    TT_TTDEFS    (TT$M_MECHTAB|TT$M_MECHFORM|TT$M_NOECHO)
  41. #define    TT_TT2DEFS    (TT2$M_PASTHRU)
  42.  
  43.  
  44. /*
  45.  *    Macro functions to get and
  46.  *    set terminal characteristics
  47.  */
  48. #define    tt_getmode(iosb_s,ttbuf)                \
  49.     ( ((SYS$QIOW(0, tt_chan(), IO$_SENSEMODE, &(iosb_s),    \
  50.     (void(*)())0, 0, &(ttbuf), sizeof(ttbuf), 0, 0, 0, 0)    \
  51.     & SS$_NORMAL) == 0) ? TT_FAILURE : TT_SUCCESS )
  52.  
  53. #define    tt_setmode(iosb_s,ttbuf)                \
  54.     ( ((SYS$QIOW(0, tt_chan(), IO$_SETMODE, &(iosb_s),    \
  55.     (void(*)())0, 0, &(ttbuf), sizeof(ttbuf), 0, 0, 0, 0)    \
  56.     & SS$_NORMAL) == 0) ? TT_FAILURE : TT_SUCCESS )
  57.  
  58.  
  59. /*
  60.  *    Private (static) variables
  61.  */
  62. static    int        _io_on = 0;    /* between tt_init & tt_fini */
  63. static    int        _io_pu = 0;    /* purge typeahead on next read */
  64. static    int        _iochan = 0;    /* channel for i/o */
  65. static    IOSB_S        _iosb;
  66. static    TTBUF        _ttbuf_old;
  67. static    TTBUF        _ttbuf_new;
  68.  
  69.  
  70. /*
  71.  -    (static) tt_getchannel :
  72.  */
  73. static int tt_getchannel ()
  74. {
  75.     struct dsc$descriptor_s    iodsc;
  76.  
  77.     if (_iochan > 0)
  78.         return TT_SUCCESS;    /* already assigned channel */
  79.  
  80.     iodsc.dsc$w_length    = sizeof("TT:")-1;
  81.     iodsc.dsc$b_dtype    = DSC$K_DTYPE_T;
  82.     iodsc.dsc$b_class    = DSC$K_CLASS_S;
  83.     iodsc.dsc$a_pointer    = "TT:";
  84.  
  85.     if ((SYS$ASSIGN (&iodsc, &_iochan, 0, 0) & SS$_NORMAL) == 0)
  86.         return TT_FAILURE;
  87.  
  88.     return TT_SUCCESS;
  89. }
  90.  
  91.  
  92. /*
  93.  -    (static) tt_freechannel :
  94.  */
  95. static int tt_freechannel ()
  96. {
  97.     int    status;
  98.  
  99.     if (_iochan == 0)
  100.         return TT_SUCCESS;    /* channel not assigned */
  101.  
  102.     status = SYS$DASSGN (_iochan);
  103.  
  104.     _iochan = 0;
  105.  
  106.     if ((status & SS$_NORMAL) == 0)
  107.         return TT_FAILURE;
  108.  
  109.     return TT_SUCCESS;
  110. }
  111.  
  112.  
  113. /*
  114.  -    (static) vms_read :
  115.  */
  116. static int vms_read (char *buffer, int size, int timeout)
  117. {
  118.     int        code;
  119.     int        status;
  120.     IOSB_R        iostab;
  121.     static int    tt_terms[2] = { 0, 0 };
  122.  
  123.     if (_io_pu == 1)
  124.         code = TT_PURGE;
  125.     else
  126.         code = TT_NOPURGE;
  127.  
  128.     _io_pu = 0;
  129.  
  130.     status = SYS$QIOW (0, _iochan, code,
  131.         &iostab, (void(*)())0, 0,
  132.         buffer, size, timeout, tt_terms, 0, 0);
  133.  
  134.     if (status == SS$_TIMEOUT)
  135.         return TT_TIMEOUT;
  136.  
  137.     if (status != SS$_NORMAL)
  138.         return TT_ERROR;
  139.  
  140.     if ((status = iostab.term_offset + iostab.term_size) > 0)
  141.         return status;
  142.  
  143.     return TT_TIMEOUT;
  144. }
  145.  
  146.  
  147. /*
  148.  -    tt_chan :
  149.  */
  150. int tt_chan ()
  151. {
  152.     if (_iochan == 0)
  153.         (void) tt_getchannel();
  154.  
  155.     return _iochan;
  156. }
  157.  
  158.  
  159. /*
  160.  -    tt_init :
  161.  */
  162. int tt_init ()
  163. {
  164.     if (_io_on == 1)
  165.         return TT_SUCCESS;
  166.  
  167.     if (tt_getchannel() == TT_FAILURE)
  168.         return TT_FAILURE;
  169.  
  170.     if (tt_getmode(_iosb, _ttbuf_old) == TT_FAILURE)
  171.         return TT_FAILURE;
  172.  
  173.     if (tt_getmode(_iosb, _ttbuf_new) == TT_FAILURE)
  174.         return TT_FAILURE;
  175.  
  176.     _ttbuf_new.ttchar |= TT_TTDEFS;
  177.     _ttbuf_new.tt2char |= TT_TT2DEFS;
  178.  
  179.     if (tt_setmode(_iosb, _ttbuf_new) == TT_FAILURE) {
  180.         (void) tt_fini ();
  181.         return TT_FAILURE;
  182.     }
  183.  
  184.     if (atexit(tt_fini) != 0) {
  185.         (void) tt_fini ();
  186.         return TT_FAILURE;
  187.     }
  188.  
  189.     _io_on = 1;
  190.     return TT_SUCCESS;
  191. }
  192.  
  193.  
  194. /*
  195.  -    tt_getc :
  196.  */
  197. int tt_getc ()
  198. {
  199.     int        incount;
  200.     static char    buffer[TT_BUFSIZ];
  201.     static char    *bufptr = buffer;
  202.     static char    *bufend = buffer;
  203.  
  204.     /*
  205.      *    If io not initialized, do so.
  206.      */
  207.  
  208.     if (_io_on == 0)
  209.         if (tt_init() == TT_FAILURE)
  210.             return TT_ERROR;
  211.  
  212.     /*
  213.      *    First call to vms_read reads any leftover
  214.      *    characters from operating system's read
  215.      *    buffer -- it should return TIMEOUT.  Then
  216.      *    call again and again until a character
  217.      *    is successfully read.
  218.      */
  219.  
  220.     if (bufptr >= bufend) {
  221.         bufptr = bufend = buffer;
  222.         incount = vms_read (buffer, TT_BUFSIZ, 0);
  223.         while (incount < TT_SUCCESS)
  224.             incount = vms_read (buffer, 1, 2);
  225.         bufend = &buffer[incount];
  226.     }
  227.  
  228.     /*
  229.      *    If escape was read, call vms_read with
  230.      *    timeout 0 to read all characters in the
  231.      *    escape sequence.
  232.      */
  233.  
  234.     if (*bufptr == '\033') {
  235.         char    junk[80];
  236.  
  237.         (void) vms_read(junk, 80, 0);
  238.         bufptr = bufend = buffer;
  239.  
  240.         return    '\033';
  241.     }
  242.  
  243.     *bufend = '\0';
  244.  
  245.     return (*bufptr++ & 0177);
  246. }
  247.  
  248.  
  249. /*
  250.  -    tt_flush :
  251.  */
  252. void tt_flush ()
  253. {
  254.     /*
  255.      * Alternatively we could call vms_read with 0 timeout
  256.      * until no more characters are available, i.e.
  257.      *
  258.      *    char    ch;
  259.      *
  260.      *    while (vms_read(&ch, 1, 0) > TT_FAILURE)
  261.      *        ;
  262.      *
  263.      * Hopefully the final vms_read() will return TT_TIMEOUT
  264.      */
  265.     _io_pu = 1;
  266.     return;
  267. }
  268.  
  269.  
  270. /*
  271.  -    tt_fini :
  272.  */
  273. void tt_fini ()
  274. {
  275.     if (_io_on == 0)
  276.         return;
  277.  
  278.     (void) tt_setmode (_iosb, _ttbuf_old);
  279.  
  280.     /*
  281.      *    De-assign io channel.
  282.      */
  283.  
  284.     (void) tt_freechannel ();
  285.  
  286.     _io_on = 0;
  287.     return;
  288. }
  289.  
  290.  
  291. /*
  292.  -    tt_speed :
  293.  */
  294. int tt_speed ()
  295. {
  296.     if (_io_on == 0)
  297.         if (tt_init() == TT_FAILURE)
  298.             return TT_ERROR;
  299.  
  300.     if (_iosb.ospeed < BAUD_MIN || _iosb.ospeed > BAUD_MAX)
  301.         return TT_FAILURE;
  302.     else
  303.         return _iosb.ospeed;
  304. }
  305.  
  306.  
  307. /*
  308.  -    tt_cols :
  309.  */
  310. int tt_cols ()
  311. {
  312.     if (_io_on == 0)
  313.         if (tt_init() == TT_FAILURE)
  314.             return TT_ERROR;
  315.  
  316.     if (_ttbuf_new.cols > 0)
  317.         return _ttbuf_new.cols;
  318.  
  319.     return TT_ERROR;
  320. }
  321.  
  322.  
  323. /*
  324.  -    tt_rows :
  325.  */
  326. int tt_rows ()
  327. {
  328.     if (_io_on == 0)
  329.         if (tt_init() == TT_FAILURE)
  330.             return TT_ERROR;
  331.  
  332.     if (_ttbuf_new.rows > 0)
  333.         return _ttbuf_new.rows;
  334.  
  335.     return TT_ERROR;
  336. }
  337.  
  338.  
  339. /*
  340.  -    tt_shell :
  341.  */
  342. void tt_shell ()
  343. {
  344.     long            status;
  345.     struct dsc$descriptor_s    dsc;
  346.  
  347.     dsc.dsc$w_length    = sizeof("")-1;
  348.     dsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  349.     dsc.dsc$b_class        = DSC$K_CLASS_S;
  350.     dsc.dsc$a_pointer    = "";
  351.  
  352.     (void) LIB$SPAWN (&dsc, 0, 0, 0, 0, 0, &status, 0, 0, 0, 0, 0);
  353.  
  354.     return;
  355. }
  356. #endif                    /* VMS */
  357.