home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume1
/
rogue
/
patch3
/
vmsterm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-13
|
6KB
|
357 lines
#ifdef VMS
/*
* VMSTERM.C
*
* Copyright (c) 1991 by Michael S Zraly.
*
* Some of the details in this code were derived from code
* for the games larn, copyright 1986 by Noah Morgan (as
* adapted by Kevin Routley), and nethack, copyright 1985
* by the Stichting Mathematisch centrum, Amsterdam.
*
* Permission is granted to distribute and modify this source
* Permission is granted to distribute and modify this source
* freely, provided that no charge is made for doing so and
* that this comment remains untouched.
*
* Last Modified: 21 August 1991
*/
#include <descrip.h>
#include "vmsterm.h"
#define TT_BUFSIZ 80
/*
* I/o func codes passed to SYS$QIO() or SYS$QIOW():
*/
#define TT_NOPURGE (IO$_READLBLK|IO$M_NOFILTR|IO$M_TIMED|IO$M_NOECHO)
#define TT_PURGE ((TT_NOPURGE)|(IO$M_PURGE))
/*
* Default terminal characteristics
*/
#define TT_TTDEFS (TT$M_MECHTAB|TT$M_MECHFORM|TT$M_NOECHO)
#define TT_TT2DEFS (TT2$M_PASTHRU)
/*
* Macro functions to get and
* set terminal characteristics
*/
#define tt_getmode(iosb_s,ttbuf) \
( ((SYS$QIOW(0, tt_chan(), IO$_SENSEMODE, &(iosb_s), \
(void(*)())0, 0, &(ttbuf), sizeof(ttbuf), 0, 0, 0, 0) \
& SS$_NORMAL) == 0) ? TT_FAILURE : TT_SUCCESS )
#define tt_setmode(iosb_s,ttbuf) \
( ((SYS$QIOW(0, tt_chan(), IO$_SETMODE, &(iosb_s), \
(void(*)())0, 0, &(ttbuf), sizeof(ttbuf), 0, 0, 0, 0) \
& SS$_NORMAL) == 0) ? TT_FAILURE : TT_SUCCESS )
/*
* Private (static) variables
*/
static int _io_on = 0; /* between tt_init & tt_fini */
static int _io_pu = 0; /* purge typeahead on next read */
static int _iochan = 0; /* channel for i/o */
static IOSB_S _iosb;
static TTBUF _ttbuf_old;
static TTBUF _ttbuf_new;
/*
- (static) tt_getchannel :
*/
static int tt_getchannel ()
{
struct dsc$descriptor_s iodsc;
if (_iochan > 0)
return TT_SUCCESS; /* already assigned channel */
iodsc.dsc$w_length = sizeof("TT:")-1;
iodsc.dsc$b_dtype = DSC$K_DTYPE_T;
iodsc.dsc$b_class = DSC$K_CLASS_S;
iodsc.dsc$a_pointer = "TT:";
if ((SYS$ASSIGN (&iodsc, &_iochan, 0, 0) & SS$_NORMAL) == 0)
return TT_FAILURE;
return TT_SUCCESS;
}
/*
- (static) tt_freechannel :
*/
static int tt_freechannel ()
{
int status;
if (_iochan == 0)
return TT_SUCCESS; /* channel not assigned */
status = SYS$DASSGN (_iochan);
_iochan = 0;
if ((status & SS$_NORMAL) == 0)
return TT_FAILURE;
return TT_SUCCESS;
}
/*
- (static) vms_read :
*/
static int vms_read (char *buffer, int size, int timeout)
{
int code;
int status;
IOSB_R iostab;
static int tt_terms[2] = { 0, 0 };
if (_io_pu == 1)
code = TT_PURGE;
else
code = TT_NOPURGE;
_io_pu = 0;
status = SYS$QIOW (0, _iochan, code,
&iostab, (void(*)())0, 0,
buffer, size, timeout, tt_terms, 0, 0);
if (status == SS$_TIMEOUT)
return TT_TIMEOUT;
if (status != SS$_NORMAL)
return TT_ERROR;
if ((status = iostab.term_offset + iostab.term_size) > 0)
return status;
return TT_TIMEOUT;
}
/*
- tt_chan :
*/
int tt_chan ()
{
if (_iochan == 0)
(void) tt_getchannel();
return _iochan;
}
/*
- tt_init :
*/
int tt_init ()
{
if (_io_on == 1)
return TT_SUCCESS;
if (tt_getchannel() == TT_FAILURE)
return TT_FAILURE;
if (tt_getmode(_iosb, _ttbuf_old) == TT_FAILURE)
return TT_FAILURE;
if (tt_getmode(_iosb, _ttbuf_new) == TT_FAILURE)
return TT_FAILURE;
_ttbuf_new.ttchar |= TT_TTDEFS;
_ttbuf_new.tt2char |= TT_TT2DEFS;
if (tt_setmode(_iosb, _ttbuf_new) == TT_FAILURE) {
(void) tt_fini ();
return TT_FAILURE;
}
if (atexit(tt_fini) != 0) {
(void) tt_fini ();
return TT_FAILURE;
}
_io_on = 1;
return TT_SUCCESS;
}
/*
- tt_getc :
*/
int tt_getc ()
{
int incount;
static char buffer[TT_BUFSIZ];
static char *bufptr = buffer;
static char *bufend = buffer;
/*
* If io not initialized, do so.
*/
if (_io_on == 0)
if (tt_init() == TT_FAILURE)
return TT_ERROR;
/*
* First call to vms_read reads any leftover
* characters from operating system's read
* buffer -- it should return TIMEOUT. Then
* call again and again until a character
* is successfully read.
*/
if (bufptr >= bufend) {
bufptr = bufend = buffer;
incount = vms_read (buffer, TT_BUFSIZ, 0);
while (incount < TT_SUCCESS)
incount = vms_read (buffer, 1, 2);
bufend = &buffer[incount];
}
/*
* If escape was read, call vms_read with
* timeout 0 to read all characters in the
* escape sequence.
*/
if (*bufptr == '\033') {
char junk[80];
(void) vms_read(junk, 80, 0);
bufptr = bufend = buffer;
return '\033';
}
*bufend = '\0';
return (*bufptr++ & 0177);
}
/*
- tt_flush :
*/
void tt_flush ()
{
/*
* Alternatively we could call vms_read with 0 timeout
* until no more characters are available, i.e.
*
* char ch;
*
* while (vms_read(&ch, 1, 0) > TT_FAILURE)
* ;
*
* Hopefully the final vms_read() will return TT_TIMEOUT
*/
_io_pu = 1;
return;
}
/*
- tt_fini :
*/
void tt_fini ()
{
if (_io_on == 0)
return;
(void) tt_setmode (_iosb, _ttbuf_old);
/*
* De-assign io channel.
*/
(void) tt_freechannel ();
_io_on = 0;
return;
}
/*
- tt_speed :
*/
int tt_speed ()
{
if (_io_on == 0)
if (tt_init() == TT_FAILURE)
return TT_ERROR;
if (_iosb.ospeed < BAUD_MIN || _iosb.ospeed > BAUD_MAX)
return TT_FAILURE;
else
return _iosb.ospeed;
}
/*
- tt_cols :
*/
int tt_cols ()
{
if (_io_on == 0)
if (tt_init() == TT_FAILURE)
return TT_ERROR;
if (_ttbuf_new.cols > 0)
return _ttbuf_new.cols;
return TT_ERROR;
}
/*
- tt_rows :
*/
int tt_rows ()
{
if (_io_on == 0)
if (tt_init() == TT_FAILURE)
return TT_ERROR;
if (_ttbuf_new.rows > 0)
return _ttbuf_new.rows;
return TT_ERROR;
}
/*
- tt_shell :
*/
void tt_shell ()
{
long status;
struct dsc$descriptor_s dsc;
dsc.dsc$w_length = sizeof("")-1;
dsc.dsc$b_dtype = DSC$K_DTYPE_T;
dsc.dsc$b_class = DSC$K_CLASS_S;
dsc.dsc$a_pointer = "";
(void) LIB$SPAWN (&dsc, 0, 0, 0, 0, 0, &status, 0, 0, 0, 0, 0);
return;
}
#endif /* VMS */