home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 3 Comm
/
03-Comm.zip
/
STERM.ZIP
/
STERMV.C
< prev
Wrap
Text File
|
1990-11-23
|
18KB
|
598 lines
/* STERMV.C - Video output functions */
#include <string.h>
#include <stdio.h>
#include <process.h>
#define INCL_SUB
#define INCL_DOS
#include <os2kernl.h>
#define STERMV
#include "sterm.h"
static UCHAR im0s; /* insert off - cursor start line */
static UCHAR im0e; /* insert off - cursor end line */
static UCHAR im1s; /* insert on - cursor start line */
static UCHAR im1e; /* insert on - cursor end line */
static UCHAR vdata[128]; /* video data */
static UCHAR vbfc = 0x07; /* current video attribute */
static USHORT vcol; /* current col */
static USHORT vrow; /* current row */
static VIOMODEINFO viodata; /* used by vioget.../vioset... functions */
static VIOCURSORINFO vcurs; /* used by viogetcurs, etc. */
static USHORT ScreenSize = 25; /* current screen size in rows */
static UCHAR fldattr = 0x07; /* current video attribute */
/********************************************************************/
void clrscrn( void )
{
/* mono or color adapter/display and how many rows ? */
viodata.cb = 12;
VioGetMode( (PVIOMODEINFO) &viodata, 0 );
if ( ( viodata.fbType & 0x0001 ) == 0 || ( viodata.fbType & 0x0004 ) != 0 )
fldattr = fldmono;
else
fldattr = fldcolor;
ScreenSize = viodata.row;
/* cursor start/end ? */
VioGetCurType( (PVIOCURSORINFO) &vcurs, 0 );
im0s = vcurs.yStart - 1;
im0e = vcurs.cEnd;
im1s = 1;
im1e = vcurs.yStart;
/* clear the screen - put the real cursor in top left */
vbfc = fldattr;
vdata[0] = ' ';
vdata[1] = vbfc;
vrow = 1;
vcol = 1;
VioWrtNCell( (PUCHAR) vdata,
ScreenSize * 80,
vrow - 1,
vcol - 1,
0 );
setcursor( vrow, vcol, -1 );
}
/********************************************************************/
void clreor( )
{
/* clear to end of current row */
vdata[0] = ' ';
vdata[1] = vbfc;
VioWrtNCell( (UCHAR far *) vdata,
( 81 - vcol ),
vrow - 1,
vcol - 1,
0 );
}
/********************************************************************/
void gotorc( r, c )
int r;
int c;
{
/* save the new virtual cursor position */
vrow = r;
vcol = c;
}
/********************************************************************/
static void outstr( PUCHAR s, USHORT len )
{
BOOL newline = FALSE;
BOOL advance = TRUE;
UCHAR attrch[2];
/* trim CR and LF from end of string */
while ( (len) && ( ( s[len-1] == '\r' ) ||
( s[len-1] == '\n' ) ) )
{ /* line ends with CR */
if ( s[len-1] == '\r' )
newline = TRUE;
len--;
}
/* if backspace, reset cursor, blank */
if ( len == 1)
switch ( s[0] )
{
case '\b' : {
s[0] = ' ';
if ( vcol > 1 )
vcol--;
advance = FALSE;
break;
}
case '\n' : return; /* ignore linefeed */
default: {}
}
/* write string at the current virtual cursor position */
if ( len )
VioWrtCharStrAtt( (PUCHAR) s,
len,
vrow - 1,
vcol - 1,
(PBYTE) &vbfc,
0 );
/* if line ends with CR */
if ( newline ) /* carriage return */
{
vrow++;
if ( vrow > ScreenSize )
{
vrow = ScreenSize;
attrch[1] = vbfc;
attrch[0] = ' ';
VioScrollUp( 0, 0, ScreenSize-1, 79, 1, (PBYTE) attrch, 0 );
}
vcol = 1;
}
else
if ( advance )
vcol = vcol + len;
setcursor( vrow, vcol, -1 );
}
/********************************************************************/
void setcursor( int r, int c, int im )
{
/* move the real cursor and optionally set its size */
VioSetCurPos( r -1,
c - 1,
0 );
if ( im >= 0 )
{
if ( im )
{
vcurs.yStart = im1s;
vcurs.cEnd = im1e;
}
else
{
vcurs.yStart = im0s;
vcurs.cEnd = im0e;
}
VioSetCurType( (PVIOCURSORINFO) &vcurs, 0 );
}
}
#define NUL '\x00' /* null byte */
#define ENQ '\x05' /* transmit answerback msg */
#define BEL '\x07' /* alarm */
#define BS '\b' /* backspace */
#define HT '\x09' /* horizontal tab */
#define LF '\x0A' /* linefeed */
#define VT '\x0B' /* same as linefeed */
#define FF '\x0C' /* ditto */
#define CR '\x0D' /* cursor to left margin current line */
#define SO '\x0E' /* select G1 charset (ignored) */
#define SI '\x0F' /* select G0 charset ESC[ process */
#define XON '\x11' /* resume transmission */
#define XOFF '\x13' /* transmit only XON XOFF */
#define CAN '\x18' /* cancel control seq. */
#define SUB '\x1A' /* same as CAN */
#define ESC '\x1B' /* leadin to control seq. */
#define DEL '\x7F' /* deleted on input */
/* SIMVT output emulation
called from vidout with each char, may
return \0 if char is deleted or part of ctl seq */
static enum { nada, havesc, havlead, getpc1, havpc1,
havescO, eatCR, eatone } cstat;
static short pc1, /* 1st parm numeric */
pc2; /* 2nd parm numeric */
/* process completed ESC [ sequence */
static UCHAR procseq( UCHAR ic )
{
cstat = nada;
switch ( ic )
{
/* cursor backward, max to left margin */
case 'D': {
if ( vcol > 1 )
vcol--;
setcursor( vrow, vcol, -1 );
return( NUL );
}
/* cursor down, max to bottom */
case 'B': {
if ( vrow < ScreenSize )
vrow++;
setcursor( vrow, vcol, -1 );
return( NUL );
}
/* cursor right, max to right margin */
case 'C': {
if ( vcol < 80 )
vcol++;
setcursor( vrow, vcol, -1 );
return( NUL );
}
/* cursor up, max to top */
case 'A': {
if ( vrow > 1 )
vrow--;
setcursor( vrow, vcol, -1 );
return( NUL );
}
/* gotorc pc1, pc2 */
case 'f':
case 'H': {
if ( pc1 == 0 )
pc1 = 1;
if ( pc2 == 0 )
pc2 = 1;
gotorc( pc1, pc2 );
setcursor( vrow, vcol, -1 );
return( NUL );
}
/* set display attributes */
case 'm': {
cstat = nada;
switch ( pc1 )
{
case 0: { /* off */
vbfc = fldattr;
break;
}
case 1: { /* hilite - if it won't blink */
if ( fldattr & 0x08 )
vbfc = fldattr | 0x0F;
else vbfc = fldattr | 0x08;
break;
}
case 4: /* underscore */
case 5: /* blink */
case 7: ; /* reverse */
}
return( NUL );
}
/* device attributes */
case 'c': {
return( NUL );
}
/* erase display according to pc1 */
case 'J': {
switch ( pc1 )
{ /* map into a clear */
case 0:
case 1:
case 2: clrscrn();
default: {}
}
return( NUL );
}
/* erase line according to pc1 */
case 'K': { /* map into EEOL */
case 0:
case 1:
case 2: clreor();
return( NUL );
}
default: return( '?' );
}
} /* end procseq */
UCHAR vid100( UCHAR ic, BOOL fromkey )
{
CHAR linbuf[WSLEN]; /* delete-insert buffer */
USHORT bufl; /* num of chars to change */
switch ( cstat )
{
/* begin escape seq. or pass back char */
case nada: {
if ( ic == ESC )
{
pc1 = pc2 = 0;
cstat = havesc;
return( NUL );
}
/* allow no ctl chars, but BSP, LF, DEL */
if ( ic < ' ' )
{
if ( !fromkey )
return( NUL );
switch ( ic )
{
case '\b': return( ic );
case '\n': /* behave as newline */
{
if ( vrow < ScreenSize )
{
vrow++; vcol = 1;
setcursor( vrow, vcol, -1 );
}
return( NUL );
}
/* delete char */
case '\x02': { /* read/shift curr. row */
bufl = 80 - vcol;
VioReadCharStr( (PCH) linbuf,
(PUSHORT) &bufl, vrow-1, vcol, 0 );
linbuf[bufl] = ' ';
linbuf[bufl+1] = ' ';
VioWrtCharStrAtt( (PCH) linbuf,
bufl,
vrow - 1,
vcol - 1,
(PBYTE) &vbfc,
0 );
setcursor( vrow, vcol, -1 );
return( NUL );
}
default: return( NUL );
}
} /* if less than blank */
/* if insert mode, push line over */
if ( ( insmode ) && ( fromkey ) )
{
bufl = 80 - vcol;
VioReadCharStr( (PCH) linbuf,
(PUSHORT) &bufl, vrow-1, vcol-1, 0 );
VioWrtCharStrAtt( (PCH) linbuf,
bufl,
vrow - 1,
vcol,
(PBYTE) &vbfc,
0 );
}
return( ic );
}
/* if square bracket, we have leadin */
case havesc: {
switch ( ic )
{
/* sqbracket for full leadin */
case '[': {
cstat = havlead;
return( NUL );
}
/* esc seq. being cancelled */
case SUB:
case CAN: {
cstat = nada;
return( NUL );
}
/* VT52 set of sequences */
case 'O': {
cstat = havescO;
return( NUL );
}
case '=': { /* enable alt. keypad (ignore) */
cstat = nada; cstat = nada;
return( NUL);
}
case 'i': /* for now = EEOF */
case 'e': { /* erase eof */
cstat = nada;
clreor();
return( NUL );
}
/* cursor to 1st pos next line,
scrollup if bottom */
case 'E': {
if ( vrow < ScreenSize )
{
vrow++; vcol = 1;
setcursor( vrow, vcol, -1 );
}
cstat = nada;
return( NUL );
}
default: return( '?' );
}
}
/* have ESC O sequence for 3270 input,
just process clear (M), PA2 ('m') and eat the CR
that is coming. The rest are PF, PA keys */
case havescO: {
if ( ( ic == 'M' ) ||
( ic == 'm' ) )
clrscrn();
cstat = eatCR;
return( NUL );
}
/* consume a CR, else an error */
case eatCR: {
cstat = nada;
if ( ic == CR )
return( NUL );
else
return( '?' );
}
/* consume parms to 'h' */
case eatone: {
if ( ic == 'h' )
{
cstat = nada;
}
return( NUL );
}
/* set to collect numeric, or process direct */
case havlead: {
if ( ( ic >= '0' ) && ( ic <= '9' ) )
{
cstat = getpc1;
pc1 = (short) (ic - '0');
return( NUL );
}
switch ( ic )
{
/* leading ';' means pc1 = 0 */
case ';': {
cstat = havpc1;
return( NUL );
}
/* up cursor, scrolldown if top */
case 'M': {
cstat = nada;
return( NUL );
}
case '?':
{ /* set mode parms */
cstat = eatone;
return( NUL);
}
case 'h': { /* end of set mode */
cstat = nada; return ( NUL );
}
default: return( procseq( ic ) );
}
}
/* accumulate numeric in pc1, or handle ';', or short escseq */
case getpc1: {
if ( ( ic >= '0' ) && ( ic <= '9' ) )
{
pc1 = (pc1 * 10) + (USHORT) (ic - '0');
return( NUL );
}
if ( ic == ';' )
{
cstat = havpc1;
return( NUL );
}
return( procseq( ic ) );
}
/* we had a ';', may be another numeric */
case havpc1: {
/* collect pc2 */
if ( ( ic >= '0' ) && ( ic <= '9' ) )
{
pc2 = (pc2 * 10) + (short) (ic - '0');
return( NUL );
}
/* allow redundant ';' */
if ( ic == ';' )
{
return( NUL );
}
return( procseq( ic ) );
}
default: return( '?' );
}
} /* end vid100 */
/* Write to Screen with VIO functions
Will block reading 'vwork' pipe.
'MsgH' will contain function, data length
functions: display, terminate */
void vidout(void)
{
MsgH vidmsg;
USHORT abytes,
ix;
UCHAR vline[WSLEN];
UCHAR sbyt;
cstat = nada;
while ( TRUE )
{
DosRead( vworkR, (PVOID) &vidmsg, sizeof(MsgH), (PUSHORT) &abytes );
if ( vidmsg.mtype == termin )
_dosendthread();
if ( vidmsg.mtype == immed )
{
if ( keymode == SIMVT )
vidmsg.imdat = vid100( vidmsg.imdat, vidmsg.doecho );
if ( vidmsg.imdat != '\0' )
outstr( (PUCHAR) &vidmsg.imdat, 1 );
} /* immediate byte */
else
if ( vidmsg.mtype == dhead )
{
DosRead( vworkR, (PVOID) vline, vidmsg.mlen, (PUSHORT) &abytes );
for ( ix = 0; ix < abytes; ix++ )
{
if ( keymode == SIMVT )
sbyt = vid100( vline[ix], vidmsg.doecho );
if ( sbyt != '\0' )
outstr( (PVOID) &sbyt, 1 );
}
} /* end if data header */
} /* end while true */
} /* end vidout */
/* end of stermv */