mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1538 lines
46 KiB
1538 lines
46 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
viotty.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the VIO-TTY utilities procedures
|
|
|
|
Author:
|
|
|
|
Michael Jarus (mjarus) 12-Apr-1992
|
|
|
|
Environment:
|
|
|
|
User Mode Only
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define WIN32_ONLY
|
|
#include "os2ses.h"
|
|
#include "event.h"
|
|
#include "trans.h"
|
|
#include "vio.h"
|
|
#include "os2win.h"
|
|
#include <io.h>
|
|
#include <stdio.h>
|
|
#include <limits.h>
|
|
|
|
|
|
/*
|
|
* - character definitions for ANSI 3.64
|
|
*/
|
|
|
|
#define ANSI_ESC 0x1b /* ESC - escape */
|
|
#define ANSI_CUU 0x41 /* ESC[<n>A - cursor up */
|
|
#define ANSI_CUD 0x42 /* ESC[<n>B - cursor down */
|
|
#define ANSI_CUF 0x43 /* ESC[<n>C - cursor forward */
|
|
#define ANSI_CUB 0x44 /* ESC[<n>D - cursor back */
|
|
#define ANSI_CUP 0x48 /* ESC[<row>;<col>H - cursor position */
|
|
#define ANSI_ED 0x4a /* ESC[2J - erase display */
|
|
#define ANSI_EL 0x4b /* ESC[K - erase line */
|
|
#define ANSI_CUP1 0x66 /* ESC[<row>;<col>f - cursor position */
|
|
#define ANSI_SMOD 0x68 /* ESC[=<s>h - set mode */
|
|
#define ANSI_RMOD 0x6c /* ESC[=<s>l - reset mode */
|
|
#define ANSI_SGR 0x6d /* ESC[<g1>;...;<gn>m - select graphic rendition */
|
|
#define ANSI_SCP 0x73 /* ESC[s - save cursor position */
|
|
#define ANSI_RCP 0x75 /* ESC[u - restore cursor position */
|
|
//#define ANSI_ICH 0x40 /* ESC[@ insert character */
|
|
//#define ANSI_CNL 0x45 /* ESC[E cursor to next line */
|
|
//#define ANSI_CPL 0x46 /* ESC[F cursor to previous line */
|
|
//#define ANSI_IL 0x4c /* ESC[L insert line */
|
|
//#define ANSI_DL 0x4d /* ESC[M delete line */
|
|
//#define ANSI_DCH 0x50 /* ESC[P delete character */
|
|
//#define ANSI_SU 0x53 /* ESC[S scroll up */
|
|
//#define ANSI_SD 0x54 /* ESC[T scroll down */
|
|
//#define ANSI_ECH 0x58 /* ESC[X erase character */
|
|
//#define ANSI_CBT 0x5a /* ESC[Z backward tabulation */
|
|
|
|
/* states of the finite state machine */
|
|
|
|
#define NOCMD 1 /* type of crt state - most chars will go onto screen */
|
|
#define ESCED 2 /* we've seen an ESC, waiting for rest of CSI */
|
|
#define EQCMD 3 /* if '=' goto MODPARAMS else PARAMS */
|
|
#define PARAMS 4 /* we're building the parameter list for ansicmd */
|
|
#define MODPARAMS 5 /* we're building the parameter list for MODCMD */
|
|
#define MODCMD 6 /* we've seen "ESC[=Num" waiting for #h or #l (# in {0..7}) */
|
|
#define MODDBCS 7 /* we've seen DBCS lead-in char */
|
|
|
|
#define NPARMS 4 /* max # of params */
|
|
|
|
#define BACKGROUND_MASK (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED)
|
|
#define FOREGROUND_MASK (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
|
|
#define OS2_BACKGROUND_MASK (OS2_BACKGROUND_BLUE | OS2_BACKGROUND_GREEN | OS2_BACKGROUND_RED)
|
|
#define OS2_FOREGROUND_MASK (OS2_FOREGROUND_BLUE | OS2_FOREGROUND_GREEN | OS2_FOREGROUND_RED)
|
|
#define OS2_BACKGROUND_WHITE (OS2_BACKGROUND_BLUE | OS2_BACKGROUND_GREEN | OS2_BACKGROUND_RED)
|
|
#define OS2_FOREGROUND_WHITE (OS2_FOREGROUND_BLUE | OS2_FOREGROUND_GREEN | OS2_FOREGROUND_RED)
|
|
#define OS2_BACKGROUND_BLACK 0
|
|
#define OS2_FOREGROUND_BLACK 0
|
|
#define OS2_DEFAULT (OS2_FOREGROUND_WHITE | OS2_BACKGROUND_BLACK)
|
|
|
|
#define TTY_LAST_PARMS_MAX ((USHRT_MAX - 10) / 10)
|
|
|
|
#define TTY_DEST_BUFFER ((PCHAR)Ow2VioDataAddress)
|
|
|
|
extern CONSOLE_SCREEN_BUFFER_INFO StartUpScreenInfo;
|
|
|
|
extern HANDLE Od2VioWriteSemHandle;
|
|
|
|
DWORD
|
|
Od2AcquireMutant(
|
|
IN HANDLE handle
|
|
);
|
|
|
|
DWORD
|
|
Od2ReleaseMutant(
|
|
IN HANDLE handle
|
|
);
|
|
|
|
DWORD
|
|
Ow2VioUpdateCurPos(
|
|
IN COORD CurPos
|
|
);
|
|
|
|
COORD Ow2TtySavedCursorPosition; /* CurPos for saving */
|
|
USHORT Ow2TtyParmList[NPARMS]; /* parameter list */
|
|
ULONG Ow2TtyParmNum; /* index of parameter we're building */
|
|
USHORT Ow2TtyAnsiState; /* state of machine */
|
|
USHORT Ow2TtyIgnoreNextChar;
|
|
COORD Ow2TtyCoord;
|
|
DWORD Ow2TtyNumBytes;
|
|
|
|
|
|
DWORD
|
|
Ow2TtyScreen(
|
|
IN LPSTR SourStr,
|
|
IN DWORD cnt
|
|
);
|
|
|
|
VOID
|
|
Ow2TtyClrParam();
|
|
|
|
DWORD
|
|
Ow2TtyAnsiCmd(
|
|
IN CHAR c,
|
|
OUT BOOL *NewCoord
|
|
);
|
|
|
|
USHORT
|
|
Ow2TtyRange(
|
|
USHORT val,
|
|
USHORT def,
|
|
USHORT min,
|
|
USHORT max
|
|
);
|
|
|
|
DWORD
|
|
Ow2TtyFlushStr();
|
|
|
|
DWORD
|
|
Ow2TtySetAttr();
|
|
|
|
|
|
static BYTE ColorTable[8] = { 0, /* Black */
|
|
4, /* Red */
|
|
2, /* Green */
|
|
6, /* Yellow */
|
|
1, /* Blue */
|
|
5, /* Magenta */
|
|
3, /* Cyan */
|
|
7}; /* White */
|
|
|
|
#if DBG
|
|
BYTE Ow2TtyScreenStr[] = "Ow2TtyScreen";
|
|
BYTE Ow2TtyAnsiCmdStr[] = "Ow2TtyAnsiCmd";
|
|
BYTE Ow2TtySetAttrStr[] = "Ow2TtySetAttr";
|
|
BYTE Ow2TtyFlushStrStr[] = "Ow2TtyFlushStr";
|
|
#endif
|
|
|
|
DWORD
|
|
AnsiInitForSession()
|
|
{
|
|
SesGrp->AnsiMode = ANSI_ON;
|
|
SesGrp->WinAttr = (USHORT)StartUpScreenInfo.wAttributes;
|
|
#ifdef DBCS
|
|
// MSKK Feb.2.1993 V-AkihiS
|
|
MapWin2Os2Attr(SesGrp->WinAttr, &(SesGrp->AnsiCellAttr[0]));
|
|
#else
|
|
SesGrp->AnsiCellAttr[0] = MapWin2Os2Attr(SesGrp->WinAttr);
|
|
SesGrp->AnsiCellAttr[1] = SesGrp->AnsiCellAttr[2] = 0;
|
|
#endif
|
|
SesGrp->ansi_background = SesGrp->AnsiCellAttr[0] & OS2_BACKGROUND_MASK;
|
|
SesGrp->ansi_foreground = SesGrp->AnsiCellAttr[0] & OS2_FOREGROUND_MASK;
|
|
SesGrp->ansi_bold = (SesGrp->AnsiCellAttr[0] & OS2_FOREGROUND_INTENSITY) ? 1 : 0;
|
|
SesGrp->ansi_blink = (SesGrp->AnsiCellAttr[0] & OS2_BACKGROUND_BLINKING) ? 1 : 0;
|
|
|
|
return(AnsiInit());
|
|
}
|
|
|
|
|
|
DWORD
|
|
AnsiInit()
|
|
{
|
|
Ow2TtySavedCursorPosition = /*ansi_coord*/SesGrp->WinCoord;
|
|
Ow2TtyAnsiState = NOCMD; /* state of machine */
|
|
Ow2TtyIgnoreNextChar = 0;
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD
|
|
Ow2VioWriteTTYStr(
|
|
IN PUCHAR SourStr,
|
|
IN ULONG Length,
|
|
IN ULONG ExtRequestType
|
|
)
|
|
{
|
|
DWORD Rc;
|
|
VIOREQUESTNUMBER RequestType = (VIOREQUESTNUMBER) ExtRequestType;
|
|
USHORT Row, Col;
|
|
|
|
if (RequestType == VIOWrtStdOut)
|
|
{
|
|
if (!hStdOutConsoleType)
|
|
{
|
|
return (ERROR_INVALID_HANDLE);
|
|
}
|
|
} else if (RequestType == VIOWrtStdErr)
|
|
{
|
|
if (!hStdErrConsoleType)
|
|
{
|
|
return (ERROR_INVALID_HANDLE);
|
|
}
|
|
}
|
|
|
|
Od2AcquireMutant(Od2VioWriteSemHandle);
|
|
|
|
if (Rc = Ow2VioGetCurPos(&Row, &Col))
|
|
{
|
|
#if DBG
|
|
ASSERT1("OS2SES(VioTTY)-Ow2VioGetCurPos failed\n", FALSE);
|
|
#endif
|
|
Od2ReleaseMutant(Od2VioWriteSemHandle);
|
|
return(Rc);
|
|
}
|
|
|
|
#if DBG
|
|
IF_OD2_DEBUG( VIO )
|
|
{
|
|
UCHAR Buffer[256], *Ptr = SourStr, *Ptr1;
|
|
ULONG Count = Length, CurCount, i;
|
|
|
|
for ( ; Count ; Count -= CurCount, Ptr += CurCount )
|
|
{
|
|
CurCount = ( Count > 10 ) ? 10 : Count;
|
|
|
|
sprintf(Buffer, "%s %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x ",
|
|
(Count == Length) ? "OS2SES(VioTTY):" : " " ,
|
|
Ptr[0], Ptr[1], Ptr[2], Ptr[3], Ptr[4],
|
|
Ptr[5], Ptr[6], Ptr[7], Ptr[8], Ptr[9]
|
|
);
|
|
|
|
Ptr1 = &Buffer[48];
|
|
for ( i = 0 ; i < 10 ; i++ )
|
|
{
|
|
if ( i >= CurCount )
|
|
{
|
|
Buffer[15 + i * 3] = Buffer[16 + i * 3] = Buffer[17 + i * 3] = ' ';
|
|
} else if (Ptr[i] < 0x20)
|
|
{
|
|
if (Ptr[i] == ANSI_ESC)
|
|
{
|
|
*Ptr1++ = '<';
|
|
*Ptr1++ = 'E';
|
|
*Ptr1++ = 'S';
|
|
*Ptr1++ = 'C';
|
|
*Ptr1++ = '>';
|
|
} else if (Ptr[i] == '\n')
|
|
{
|
|
*Ptr1++ = '<';
|
|
*Ptr1++ = 'N';
|
|
*Ptr1++ = 'L';
|
|
*Ptr1++ = '>';
|
|
} else if (Ptr[i] == '\r')
|
|
{
|
|
*Ptr1++ = '<';
|
|
*Ptr1++ = 'C';
|
|
*Ptr1++ = 'R';
|
|
*Ptr1++ = '>';
|
|
} else if (Ptr[i] == '\b')
|
|
{
|
|
*Ptr1++ = '<';
|
|
*Ptr1++ = 'B';
|
|
*Ptr1++ = 'S';
|
|
*Ptr1++ = '>';
|
|
} else if (Ptr[i] == '\t')
|
|
{
|
|
*Ptr1++ = '<';
|
|
*Ptr1++ = 'T';
|
|
*Ptr1++ = 'A';
|
|
*Ptr1++ = 'B';
|
|
*Ptr1++ = '>';
|
|
} else if (Ptr[i] == '\07')
|
|
{
|
|
*Ptr1++ = '<';
|
|
*Ptr1++ = 'B';
|
|
*Ptr1++ = 'E';
|
|
*Ptr1++ = 'L';
|
|
*Ptr1++ = 'L';
|
|
*Ptr1++ = '>';
|
|
} else
|
|
{
|
|
*Ptr1++ = '<';
|
|
*Ptr1++ = '0';
|
|
*Ptr1++ = 'x';
|
|
*Ptr1++ = ((Ptr[i] & 0xF0) >> 4) + '0';
|
|
*Ptr1++ = (Ptr[i] & 0x0F) + '0';
|
|
*Ptr1++ = '>';
|
|
}
|
|
} else
|
|
{
|
|
*Ptr1++ = Ptr[i];
|
|
}
|
|
}
|
|
|
|
*Ptr1++ = '\n';
|
|
*Ptr1 = '\0';
|
|
|
|
KdPrint((Buffer));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
Rc = Ow2TtyScreen(
|
|
SourStr,
|
|
Length
|
|
);
|
|
|
|
Od2ReleaseMutant(Od2VioWriteSemHandle);
|
|
|
|
if (Rc == 1)
|
|
{
|
|
Rc = GetLastError();
|
|
}
|
|
|
|
if (Rc)
|
|
{
|
|
#if DBG
|
|
KdPrint(("OS2SES(VioTTY-VioWriteTTYStr): Rc %lu\n"));
|
|
ASSERT( FALSE );
|
|
#endif
|
|
}
|
|
return (Rc);
|
|
}
|
|
|
|
|
|
/*
|
|
** Basic concepts:
|
|
** The screen consists of rows and columns
|
|
** columns are numbered from the left, starting with one.
|
|
** rows on the screen are numbered from the top, starting with one.
|
|
** Thus, the home position in the upper left corner is row one, column one.
|
|
**
|
|
** Associated with each screen is the 'current active position'.
|
|
** It corresponds roughly to the cursor; in fact, after each call to screen
|
|
** the cursor will indicate the active position. Thus,
|
|
** the cursor movements really change the active position, and
|
|
** the cursor follows the change.
|
|
**
|
|
** This code implements a finite state machine that reads a stream of
|
|
** characters, and emits commands that alter the screen. All of these
|
|
** commands are issued via calls through the 'crtsw' array. Each element
|
|
** of this array consists of an aggregate of functions which are
|
|
** responsible for making the appropriate changes to the actual screen.
|
|
**
|
|
** The functions in the aggregate and their responsibities are:
|
|
**
|
|
** v_scroll(i)
|
|
** scroll the text on the screen i lines.
|
|
** This will move some lines off the screen, and some blank lines
|
|
** onto the screen. i may be negative, indicating that the text
|
|
** moves downward, and blank lines appear at the top.
|
|
** v_copy(sr, sc, dr, dc, cnt)
|
|
** sr and sc specify a source row and column.
|
|
** dr and dc specify a destination row and column.
|
|
** Count characters are copied from the source to the dest,
|
|
** with the copy proceeding from left to right, and top to bottom.
|
|
** If the source and destination overlap, the copy is done
|
|
** correctly.
|
|
** v_clear(r, c, cnt)
|
|
** Characters starting at row r and column are cleared to the
|
|
** space character.
|
|
** v_pchar(r, c, ch)
|
|
** The character ch is placed on the screen at row r, column c,
|
|
** using the current graphic rendition.
|
|
** return value is number of character positions to adjust active
|
|
** position by - zero means the character has no graphic
|
|
** representation.
|
|
** v_scurs(r, c)
|
|
** The cursor is moved to row r, column c.
|
|
** v_init()
|
|
** The screen and all data structures are initialized.
|
|
** v_sgr(i)
|
|
** The current graphic rendition (e. g. font, color) is set to
|
|
** that specified by i. See ANSI x3.64 for encoding.
|
|
*/
|
|
|
|
DWORD
|
|
Ow2TtyScreen(
|
|
IN LPSTR SourStr,
|
|
IN DWORD cnt
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine handles the TTY string and pass characters to the finite
|
|
state machine
|
|
|
|
Arguments:
|
|
|
|
SourStr - points to the array of characters
|
|
|
|
cnt - indicates how many characters are being passed.
|
|
|
|
Return Value:
|
|
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
{
|
|
register CHAR c;
|
|
BOOL NewCoord = FALSE; // for GET_LVB_PTR
|
|
BOOL OldWrap, NewWrap, NewParms, ignoreBSFlag;
|
|
PCHAR LVBPtr;
|
|
SHORT LFchar = FALSE;
|
|
DWORD Rc;
|
|
|
|
|
|
Ow2TtyCoord = SesGrp->WinCoord;
|
|
Ow2TtyNumBytes = 0;
|
|
LVBPtr = Ow2LvbGetPtr(Ow2TtyCoord);
|
|
|
|
while ( cnt-- )
|
|
{
|
|
c = *SourStr++;
|
|
|
|
// if (Ow2TtyIgnoreNextChar)
|
|
// {
|
|
// Ow2TtyIgnoreNextChar = 0;
|
|
// continue;
|
|
// }
|
|
|
|
switch ( Ow2TtyAnsiState )
|
|
{
|
|
case NOCMD:
|
|
if (( c == ANSI_ESC ) && SesGrp->AnsiMode)
|
|
{
|
|
/*
|
|
* Found ESC when ASNI_ON
|
|
* wait for remaining string
|
|
*/
|
|
|
|
Ow2TtyAnsiState = ESCED;
|
|
break;
|
|
} else
|
|
{
|
|
#ifdef DBCS
|
|
// MSKK Nov.17.1992 V-AkihiS
|
|
if (Ow2NlsIsDBCSLeadByte(c, SesGrp->VioCP)) {
|
|
TTY_DEST_BUFFER[Ow2TtyNumBytes++] = c;
|
|
Ow2TtyCoord.X++;
|
|
LVBUpdateTTYCharWithAttrAndCurPosDBCS(c, &LVBPtr, Ow2TtyAnsiState);
|
|
Ow2TtyAnsiState = MODDBCS;
|
|
}
|
|
else
|
|
#endif
|
|
if( c >= ' ' )
|
|
{
|
|
TTY_DEST_BUFFER[Ow2TtyNumBytes++] = c;
|
|
Ow2TtyCoord.X++;
|
|
LVBUpdateTTYCharWithAttrAndCurPos(c, &LVBPtr);
|
|
}else
|
|
{
|
|
ignoreBSFlag = FALSE;
|
|
|
|
switch(c)
|
|
{
|
|
/*
|
|
* For each char:
|
|
* - check if to handle (BS at first column, etc.)
|
|
* - update cursor position (different according to the char)
|
|
* - update LVB pointer
|
|
* - put charcater in output buffer
|
|
*/
|
|
|
|
case '\n':
|
|
Ow2TtyCoord.Y++;
|
|
NewCoord = 1;
|
|
LFchar = Ow2TtyCoord.X;
|
|
Ow2TtyCoord.X = 0;
|
|
break;
|
|
|
|
case '\r':
|
|
if (Ow2TtyCoord.X > 0)
|
|
{
|
|
Ow2TtyCoord.X = 0;
|
|
NewCoord = 1;
|
|
}
|
|
break;
|
|
|
|
case '\b':
|
|
if ( Ow2TtyCoord.X > 0 )
|
|
{
|
|
Ow2TtyCoord.X--;
|
|
NewCoord = 1;
|
|
} else
|
|
{
|
|
// wincon move to previous line so don't
|
|
// pass this char.
|
|
|
|
ignoreBSFlag = TRUE;
|
|
}
|
|
break;
|
|
|
|
case '\t':
|
|
Ow2TtyCoord.X += (8 - (Ow2TtyCoord.X % 8));
|
|
NewCoord = 1;
|
|
break;
|
|
|
|
case '\07':
|
|
break;
|
|
|
|
default:
|
|
Ow2TtyCoord.X++;
|
|
LVBUpdateTTYCharWithAttrAndCurPos(c, &LVBPtr);
|
|
break;
|
|
} /* end switch */
|
|
|
|
if (!ignoreBSFlag)
|
|
{
|
|
TTY_DEST_BUFFER[Ow2TtyNumBytes++] = c;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ESCED:
|
|
switch(c)
|
|
{
|
|
case '[':
|
|
Ow2TtyAnsiState = EQCMD;
|
|
Ow2TtyClrParam();
|
|
break;
|
|
|
|
default:
|
|
Ow2TtyAnsiState = NOCMD;
|
|
|
|
/*
|
|
* invalid string -
|
|
* put back last char and handle it in NOCMD mode
|
|
*/
|
|
|
|
cnt++ ;
|
|
SourStr--;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case EQCMD:
|
|
if (c == '=')
|
|
{
|
|
Ow2TtyAnsiState = MODPARAMS;
|
|
break;
|
|
}
|
|
|
|
Ow2TtyAnsiState = PARAMS;
|
|
NewParms = FALSE;
|
|
|
|
/* fall down into PARAMS mode */
|
|
|
|
case PARAMS:
|
|
if ( c >= '0' && c <= '9' )
|
|
{
|
|
if (Ow2TtyParmList[Ow2TtyParmNum] < TTY_LAST_PARMS_MAX)
|
|
{
|
|
Ow2TtyParmList[Ow2TtyParmNum] *= 10;
|
|
Ow2TtyParmList[Ow2TtyParmNum] += (c - '0');
|
|
NewParms = TRUE;
|
|
}
|
|
} else if (c == ';')
|
|
{
|
|
if ( Ow2TtyParmNum < (NPARMS - 1) )
|
|
{
|
|
NewParms = FALSE;
|
|
Ow2TtyParmNum++;
|
|
//NewParms = TRUE;
|
|
} else
|
|
{ Ow2TtyAnsiState = NOCMD;
|
|
|
|
/*
|
|
* invalid string -
|
|
* put back last char and handle it in NOCMD mode
|
|
*/
|
|
|
|
cnt++ ;
|
|
SourStr--;
|
|
}
|
|
} else
|
|
{
|
|
Ow2TtyAnsiState = NOCMD;
|
|
if (NewParms || (Ow2TtyParmNum == 0))
|
|
{
|
|
Ow2TtyParmNum++;
|
|
}
|
|
|
|
if ((Rc = Ow2TtyAnsiCmd(
|
|
c,
|
|
&NewCoord)) == 1)
|
|
{
|
|
#if DBG
|
|
KdPrint(("OS2SES(VIOTTY): failed on Ow2TtyAnsiCmd\n"));
|
|
#endif
|
|
return(1);
|
|
} else if ( Rc == 2 )
|
|
{
|
|
/*
|
|
* invalid string -
|
|
* put back last char and handle it in NOCMD mode
|
|
*/
|
|
|
|
cnt++ ;
|
|
SourStr--;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case MODPARAMS:
|
|
if ( c >= '0' && c <= '9' )
|
|
{
|
|
if (Ow2TtyParmList[Ow2TtyParmNum] < TTY_LAST_PARMS_MAX)
|
|
{
|
|
Ow2TtyParmList[0] *= 10;
|
|
Ow2TtyParmList[0] += (c - '0');
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* fall down into MODCMD mode */
|
|
|
|
case MODCMD:
|
|
Ow2TtyAnsiState = NOCMD;
|
|
if ( c == 'h' || c == 'l' )
|
|
{
|
|
if (Ow2TtyParmList[0] == 7)
|
|
{
|
|
OldWrap = ((SesGrp->OutputModeFlags & ENABLE_WRAP_AT_EOL_OUTPUT) != 0);
|
|
NewWrap = (c == 'h');
|
|
if (OldWrap != NewWrap)
|
|
{
|
|
if(Ow2TtyFlushStr())
|
|
{
|
|
#if DBG
|
|
KdPrint(("OS2SES(TTY): failed on FlushStr1\n"));
|
|
#endif
|
|
return(1);
|
|
}
|
|
|
|
if (!Or2WinSetConsoleMode(
|
|
#if DBG
|
|
Ow2TtyScreenStr,
|
|
#endif
|
|
hConOut,
|
|
SesGrp->OutputModeFlags^ENABLE_WRAP_AT_EOL_OUTPUT))
|
|
{
|
|
#if DBG
|
|
ASSERT1("OS2SES(TTY): failed on SetConsoleMode\n", FALSE);
|
|
#endif
|
|
return (1);
|
|
}
|
|
|
|
SesGrp->OutputModeFlags ^= ENABLE_WRAP_AT_EOL_OUTPUT;
|
|
}
|
|
break;
|
|
} else if (Ow2TtyParmList[0] < 7)
|
|
{
|
|
if(Ow2TtyFlushStr())
|
|
{
|
|
#if DBG
|
|
KdPrint(("OS2SES(TTY): failed on FlushStr2\n"));
|
|
#endif
|
|
return(1);
|
|
}
|
|
|
|
/* According to the spec
|
|
=====================
|
|
0 => 40x25 black and white
|
|
1 => 40x25 color
|
|
2 => 80x25 black and white
|
|
3 => 80x25 color
|
|
4 => 320x200 color
|
|
5 => 320x200 black and white
|
|
6 => 640x200 black and white
|
|
|
|
0,1,4,5 => 40 col (2,3,6 => 80 col)
|
|
1,3,4, => color (0,2,5,6 =>b&w)
|
|
|
|
According to OS/2 1.21 (for WIN COM)
|
|
====================================
|
|
0,1 => 80x50 (2-6 => 80x25)
|
|
*/
|
|
|
|
VioSetScreenSize(
|
|
(SHORT)((Ow2TtyParmList[0] <= 1) ? 50 : 25),
|
|
(SHORT)80,
|
|
hConOut);
|
|
|
|
Ow2TtyCoord.X = Ow2TtyCoord.Y = 0;
|
|
NewCoord = TRUE;
|
|
break;
|
|
} else
|
|
{
|
|
// illegal parameter
|
|
break;
|
|
}
|
|
} // else - illegal character
|
|
|
|
/*
|
|
* invalid string -
|
|
* put back last char and handle it in NOCMD mode
|
|
*/
|
|
|
|
cnt++ ;
|
|
SourStr--;
|
|
break;
|
|
|
|
case MODDBCS:
|
|
#ifdef DBCS
|
|
// MSKK Feb.06.1992 V-AkihiS
|
|
TTY_DEST_BUFFER[Ow2TtyNumBytes++] = c;
|
|
Ow2TtyCoord.X++;
|
|
LVBUpdateTTYCharWithAttrAndCurPosDBCS(c, &LVBPtr, Ow2TtyAnsiState);
|
|
Ow2TtyAnsiState = NOCMD;
|
|
#else
|
|
TTY_DEST_BUFFER[Ow2TtyNumBytes++] = ' ';
|
|
Ow2TtyCoord.X++;
|
|
LVBPtr += SesGrp->BytesPerCell;
|
|
Ow2TtyAnsiState = NOCMD;
|
|
#endif
|
|
break;
|
|
|
|
}
|
|
|
|
/*
|
|
* if past right hand edge
|
|
* move left and down
|
|
*/
|
|
|
|
if ( Ow2TtyCoord.X >= SesGrp->ScreenColNum )
|
|
{
|
|
if (SesGrp->OutputModeFlags & ENABLE_WRAP_AT_EOL_OUTPUT)
|
|
{
|
|
//Ow2TtyCoord.Y += (Ow2TtyCoord.X / SesGrp->ScreenColNum);
|
|
//Ow2TtyCoord.X = (Ow2TtyCoord.X % SesGrp->ScreenColNum);
|
|
|
|
//if (Ow2TtyCoord.X == 0)
|
|
//{
|
|
// Ow2TtyCoord.Y++;
|
|
//}
|
|
|
|
/*
|
|
* It happends only with '\n', so only one line at a time
|
|
*/
|
|
|
|
Ow2TtyCoord.Y++;
|
|
Ow2TtyCoord.X -= SesGrp->ScreenColNum;
|
|
} else
|
|
{
|
|
Ow2TtyCoord.X = SesGrp->ScreenColNum - 1;
|
|
NewCoord = TRUE;
|
|
}
|
|
} else if ( Ow2TtyCoord.X < 0 )
|
|
{
|
|
ASSERT(FALSE);
|
|
Ow2TtyCoord.X = 0;
|
|
}
|
|
|
|
/* if off screen, scroll */
|
|
|
|
if ( Ow2TtyCoord.Y >= SesGrp->ScreenRowNum )
|
|
{
|
|
//VioLVBScrollBuff((DWORD)(Ow2TtyCoord.Y - SesGrp->ScreenRowNum + 1));
|
|
|
|
/*
|
|
* It happends only with '\n', so only one line at a time
|
|
*/
|
|
|
|
//ASSERT(Ow2TtyCoord.Y == SesGrp->ScreenRowNum);
|
|
|
|
VioLVBScrollBuff(1);
|
|
|
|
Ow2TtyCoord.Y = SesGrp->ScreenRowNum - 1;
|
|
NewCoord = TRUE;
|
|
}
|
|
|
|
if (LFchar)
|
|
{
|
|
/*
|
|
* The console doesn't support LF but treats it as CR-LF.
|
|
* We send LF (does the scroll if necessary) and than move
|
|
* to the desire column
|
|
*/
|
|
if(Ow2TtyFlushStr())
|
|
{
|
|
#if DBG
|
|
KdPrint(("OS2SES(TTY): failed on FlushStr3\n"));
|
|
#endif
|
|
return(1);
|
|
}
|
|
|
|
if(Ow2VioSetCurPos((ULONG)Ow2TtyCoord.Y, (ULONG)LFchar))
|
|
{
|
|
ASSERT1( "OS2SES(VIOTTY): LF error on Ow2VioSetCurPos", FALSE );
|
|
}
|
|
|
|
Ow2TtyCoord = SesGrp->WinCoord;
|
|
LFchar = 0;
|
|
}
|
|
|
|
if ( NewCoord )
|
|
{
|
|
LVBPtr = Ow2LvbGetPtr(Ow2TtyCoord);
|
|
NewCoord = FALSE;
|
|
}
|
|
}
|
|
|
|
/* Flush */
|
|
|
|
if(Ow2TtyFlushStr())
|
|
{
|
|
#if DBG
|
|
KdPrint(("OS2SES(TTY): failed on FlushStr4\n"));
|
|
#endif
|
|
return(1);
|
|
}
|
|
|
|
#if DBG
|
|
IF_OD2_DEBUG( VIO )
|
|
{
|
|
ASSERT( Ow2TtyCoord.X == SesGrp->WinCoord.X );
|
|
ASSERT( Ow2TtyCoord.Y == SesGrp->WinCoord.Y );
|
|
}
|
|
#endif
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
/*
|
|
** Ow2TtyClrParam(lp) - clear the parameters for a screen
|
|
*/
|
|
|
|
VOID
|
|
Ow2TtyClrParam()
|
|
{
|
|
register USHORT i;
|
|
|
|
for ( i = 0; i < NPARMS; i += 1)
|
|
Ow2TtyParmList[i] = 0;
|
|
Ow2TtyParmNum = 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
Ow2TtyAnsiCmd(
|
|
IN CHAR c,
|
|
OUT BOOL *NewCoord
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine performs some ANSI 3.64 function, using the parameters
|
|
we've just gathered.
|
|
|
|
Arguments:
|
|
|
|
c - the character that indicates the function to be performed
|
|
|
|
NewCoord = where to flag if new coordinates were set
|
|
|
|
Return Value:
|
|
|
|
Should return 0.
|
|
|
|
1 - for any error (after ASSERT), RetCode from GetLastError().
|
|
|
|
Note:
|
|
|
|
Ow2TtyParmNum - length of parameter list
|
|
|
|
Ow2TtyParmList - list of Set Graphics Rendition values
|
|
|
|
Ow2TtyCoord - pointer to current screen coordinates
|
|
|
|
Ow2TtyCoord is updated if new coordinates were set and it also calls
|
|
Ow2TtyFlushStr to flush the TTY output buffer to the console.
|
|
|
|
hConOut is used for console handle.
|
|
|
|
If data/attr is written to the screen (erase line/display), the
|
|
LVB is updated.
|
|
|
|
|
|
--*/
|
|
{
|
|
DWORD NumFilled;
|
|
COORD Coord = Ow2TtyCoord;
|
|
BYTE Cell[4];
|
|
BOOL ValidCmd = TRUE;
|
|
|
|
//if (((Ow2TtyParmNum >= 3) && (c != ANSI_SGR)) ||
|
|
// ((Ow2TtyParmNum == 2) && (c != ANSI_CUP) && (c != ANSI_CUP1)) ||
|
|
// ((Ow2TtyParmNum == 1) && ((c == ANSI_SCP) || (c == ANSI_RCP))))
|
|
//{
|
|
// ValidCmd = FALSE;
|
|
//} else
|
|
switch ( c )
|
|
{
|
|
case ANSI_CUB: /* cursor backward */
|
|
Coord.X -= Ow2TtyRange(Ow2TtyParmList[0], 1, 0, Coord.X);
|
|
break;
|
|
|
|
case ANSI_CUF: /* cursor forward */
|
|
Coord.X += (SHORT)Ow2TtyRange(Ow2TtyParmList[0], 1, 0, (USHORT)(SesGrp->ScreenColNum - Coord.X - 1));
|
|
break;
|
|
|
|
case ANSI_CUU: /* cursor up */
|
|
Coord.Y -= Ow2TtyRange(Ow2TtyParmList[0], 1, 0, Coord.Y);
|
|
break;
|
|
|
|
case ANSI_CUD: /* cursor down */
|
|
Coord.Y += (SHORT)Ow2TtyRange(Ow2TtyParmList[0], 1, 0, (USHORT)(SesGrp->ScreenRowNum - Coord.Y - 1));
|
|
break;
|
|
|
|
case ANSI_CUP: /* cursor position */
|
|
case ANSI_CUP1: /* cursor position */
|
|
Coord.Y = (USHORT)Ow2TtyRange(Ow2TtyParmList[0], 1, 1, SesGrp->ScreenRowNum) - 1;
|
|
Coord.X = (USHORT)Ow2TtyRange(Ow2TtyParmList[1], 1, 1, SesGrp->ScreenColNum) - 1;
|
|
break;
|
|
|
|
case ANSI_ED: /* erase display */
|
|
#if 0
|
|
switch(Ow2TtyParmList[0])
|
|
{
|
|
case 2:
|
|
#endif
|
|
Coord.X = Coord.Y = 0;
|
|
if(Ow2TtyFlushStr())
|
|
{
|
|
return(1);
|
|
}
|
|
|
|
if (!Or2WinFillConsoleOutputCharacterA(
|
|
#if DBG
|
|
Ow2TtyAnsiCmdStr,
|
|
#endif
|
|
hConOut,
|
|
' ',
|
|
SesGrp->ScreenSize,
|
|
Coord,
|
|
&NumFilled))
|
|
{
|
|
#if DBG
|
|
ASSERT1("OS2SES(Ow2TtyAnsiCmd(ED)): failed on FillConsoleOutputCharacterA\n", FALSE);
|
|
#endif
|
|
return (1);
|
|
}
|
|
|
|
if (!Or2WinFillConsoleOutputAttribute(
|
|
#if DBG
|
|
Ow2TtyAnsiCmdStr,
|
|
#endif
|
|
hConOut,
|
|
(WORD)SesGrp->WinAttr,
|
|
NumFilled,
|
|
Coord,
|
|
&NumFilled))
|
|
{
|
|
#if DBG
|
|
ASSERT1("OS2SES(Ow2TtyAnsiCmd(ED)): failed on FillConsoleOutputAttribute\n", FALSE);
|
|
#endif
|
|
return (1);
|
|
}
|
|
#if DBG
|
|
ASSERT1("OS2SES(Ow2TtyAnsiCmd(ED)): partial data\n", NumFilled == SesGrp->ScreenSize );
|
|
#endif
|
|
Cell[0] = ' ';
|
|
Cell[1] = SesGrp->AnsiCellAttr[0];
|
|
Cell[2] = SesGrp->AnsiCellAttr[1];
|
|
Cell[3] = SesGrp->AnsiCellAttr[2];
|
|
VioLVBFillCell(&Cell[0],
|
|
Coord,
|
|
NumFilled);
|
|
//return(0);
|
|
#if 0
|
|
break;
|
|
|
|
case 0:
|
|
lclear(hConOut, Coord.X, Coord.Y,
|
|
((SesGrp->ScreenRowNum - Coord.X) * SesGrp->ScreenColNum) +
|
|
((SesGrp->ScreenColNum - Coord.X) + 1 ), SA_BONW);
|
|
break;
|
|
case 1:
|
|
lclear(hConOut, 0, 0, (Coord.Y)*SesGrp->ScreenColNum+Coord.X, SA_BONW);
|
|
break;
|
|
|
|
default:
|
|
#if DBG
|
|
IF_OD2_DEBUG( VIO )
|
|
{
|
|
KdPrint(("OS2SES(Ow2TtyAnsiCmd): unknown value(%u) for ED\n",
|
|
Ow2TtyParmList[0]));
|
|
}
|
|
#endif
|
|
ValidCmd = FALSE;
|
|
break;
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case ANSI_EL:
|
|
#if 0
|
|
switch(Ow2TtyParmList[0])
|
|
{
|
|
case 0:
|
|
#endif
|
|
if(Ow2TtyFlushStr())
|
|
{
|
|
return(1);
|
|
}
|
|
|
|
if (!Or2WinFillConsoleOutputCharacterA(
|
|
#if DBG
|
|
Ow2TtyAnsiCmdStr,
|
|
#endif
|
|
hConOut,
|
|
' ',
|
|
(DWORD)(SesGrp->ScreenColNum - Coord.X),
|
|
Coord,
|
|
&NumFilled))
|
|
{
|
|
#if DBG
|
|
ASSERT1("OS2SES(Ow2TtyAnsiCmd(EL)): failed on FillConsoleOutputCharacterA\n", FALSE);
|
|
#endif
|
|
return (1);
|
|
}
|
|
|
|
if (!Or2WinFillConsoleOutputAttribute(
|
|
#if DBG
|
|
Ow2TtyAnsiCmdStr,
|
|
#endif
|
|
hConOut,
|
|
(WORD)SesGrp->WinAttr,
|
|
NumFilled,
|
|
Coord,
|
|
&NumFilled))
|
|
{
|
|
#if DBG
|
|
ASSERT1("OS2SES(Ow2TtyAnsiCmd(EL)): failed on FillConsoleOutputAttribute\n", FALSE);
|
|
#endif
|
|
return (1);
|
|
}
|
|
|
|
#if DBG
|
|
ASSERT1("OS2SES(Ow2TtyAnsiCmd(EL)): partial data\n",
|
|
NumFilled == (DWORD)(SesGrp->ScreenColNum - Coord.X));
|
|
#endif
|
|
Cell[0] = ' ';
|
|
Cell[1] = SesGrp->AnsiCellAttr[0];
|
|
Cell[2] = SesGrp->AnsiCellAttr[1];
|
|
Cell[3] = SesGrp->AnsiCellAttr[2];
|
|
VioLVBFillCell(&Cell[0],
|
|
Coord,
|
|
NumFilled);
|
|
//return(0);
|
|
#if 0
|
|
break;
|
|
|
|
break;
|
|
case 1: /* start to ap */
|
|
lclear(hConOut, 0, Coord.Y, Coord.X, SA_BONW);
|
|
break;
|
|
case 2: /* whole line */
|
|
lclear(hConOut, 0, Coord.Y, SesGrp->ScreenColNum, SA_BONW);
|
|
break;
|
|
default:
|
|
|
|
#if DBG
|
|
IF_OD2_DEBUG( VIO )
|
|
{
|
|
KdPrint(("OS2SES(Ow2TtyAnsiCmd): unknown value(%u) for ED\n",
|
|
Ow2TtyParmList[0]));
|
|
}
|
|
#endif
|
|
ValidCmd = FALSE;
|
|
break;
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case ANSI_SGR:
|
|
if(Ow2TtySetAttr())
|
|
{
|
|
return(1);
|
|
}
|
|
return(0);
|
|
|
|
case ANSI_SCP:
|
|
Ow2TtySavedCursorPosition = Coord;
|
|
break;
|
|
|
|
case ANSI_RCP:
|
|
Coord = Ow2TtySavedCursorPosition;
|
|
break;
|
|
|
|
#if 0
|
|
|
|
case ANSI_CPL: /* cursor to previous line */
|
|
Coord.Y -= Ow2TtyRange(Ow2TtyParmList[0], 1, 1, SesGrp->ScreenRowNum);
|
|
Coord.X = 1;
|
|
break;
|
|
|
|
case ANSI_CNL: /* cursor to next line */
|
|
Coord.Y += Ow2TtyRange(Ow2TtyParmList[0], 1, 1, SesGrp->ScreenRowNum);
|
|
Coord.X = 1;
|
|
break;
|
|
|
|
case ANSI_CBT: /* tab backwards */
|
|
col = Coord.X;
|
|
i = Ow2TtyRange(Ow2TtyParmList[0], 1, 1, (col + 7) >> 3);
|
|
if (col & 7)
|
|
{
|
|
Coord.X = (col & ~7) + 1;
|
|
--i;
|
|
}
|
|
Coord.X -= (i << 3);
|
|
break;
|
|
|
|
case ANSI_DCH: /* delete character */
|
|
Ow2TtyParmList[0] = Ow2TtyRange(Ow2TtyParmList[0], 1, 1, (SesGrp->ScreenColNum - Coord.X) + 1);
|
|
if ( Coord.X + Ow2TtyParmList[0] <= SesGrp->ScreenColNum ) {
|
|
lcopy(hConOut, Coord.X+Ow2TtyParmList[0]-1, Coord.Y-1,
|
|
Coord.X-1, Coord.Y-1, SesGrp->ScreenColNum-(Coord.X+Ow2TtyParmList[0]-1));
|
|
}
|
|
lclear(hConOut, SesGrp->ScreenColNum-Ow2TtyParmList[0], Coord.Y-1,
|
|
Ow2TtyParmList[0], SA_BONW);
|
|
break;
|
|
|
|
case ANSI_DL: /* delete line */
|
|
Ow2TtyParmList[0] = Ow2TtyRange(Ow2TtyParmList[0], 1, 1, (SesGrp->ScreenRowNum - Coord.Y) + 1);
|
|
/* copy lines up */
|
|
if ( Coord.Y + Ow2TtyParmList[0] <= SesGrp->ScreenRowNum ) {
|
|
lcopy(hConOut, 0, Coord.Y+Ow2TtyParmList[0]-1, 0, Coord.Y-1,
|
|
SesGrp->ScreenColNum*(SesGrp->ScreenRowNum-(Coord.Y+Ow2TtyParmList[0]-1)));
|
|
}
|
|
/* clear new stuff */
|
|
lclear(hConOut, 0, SesGrp->ScreenRowNum-Ow2TtyParmList[0],
|
|
SesGrp->ScreenColNum*Ow2TtyParmList[0], SA_BONW);
|
|
break;
|
|
|
|
case ANSI_ECH: /* erase character */
|
|
Ow2TtyParmList[0] = Ow2TtyRange( Ow2TtyParmList[0], 1, 1, (SesGrp->ScreenColNum - Coord.X) + 1);
|
|
lclear(hConOut, Coord.X-1, Coord.Y-1, Ow2TtyParmList[0], SA_BONW);
|
|
break;
|
|
|
|
case ANSI_ICH: /* insert character */
|
|
Ow2TtyParmList[0] = Ow2TtyRange( Ow2TtyParmList[0], 1, 1, (SesGrp->ScreenColNum - Coord.X) + 1);
|
|
if ( Coord.X + Ow2TtyParmList[0] <= SesGrp->ScreenColNum ) {
|
|
lcopy(hConOut, Coord.X-1, Coord.Y-1, Coord.X+Ow2TtyParmList[0]-1,
|
|
Coord.Y-1, SesGrp->ScreenColNum-(Coord.X+Ow2TtyParmList[0]-1));
|
|
}
|
|
lclear(hConOut, Coord.X-1, Coord.Y-1, Ow2TtyParmList[0], SA_BONW);
|
|
break;
|
|
|
|
case ANSI_IL: /* insert line */
|
|
Ow2TtyParmList[0] = Ow2TtyRange(Ow2TtyParmList[0], 1, 1, (SesGrp->ScreenRowNum - Coord.Y) + 1);
|
|
/* copy lines down */
|
|
if ( Coord.Y + Ow2TtyParmList[0] <= SesGrp->ScreenRowNum ) {
|
|
lcopy(hConOut, 0, Coord.Y-1, 0, Coord.Y+Ow2TtyParmList[0]-1,
|
|
SesGrp->ScreenColNum * ( SesGrp->ScreenRowNum-(Coord.Y+Ow2TtyParmList[0]-1)));
|
|
}
|
|
/* clear new stuff */
|
|
lclear(hConOut, 0, Coord.Y-1, SesGrp->ScreenColNum * Ow2TtyParmList[0], SA_BONW);
|
|
break;
|
|
|
|
case ANSI_SU: /* scroll up */
|
|
Ow2TtyParmList[0] = Ow2TtyRange(Ow2TtyParmList[0], 1, 1, SesGrp->ScreenRowNum);
|
|
lscroll(hConOut, Ow2TtyParmList[0], SA_BONW);
|
|
break;
|
|
|
|
case ANSI_SD: /* scroll down */
|
|
Ow2TtyParmList[0] = -Ow2TtyRange(Ow2TtyParmList[0], 1, 1, SesGrp->ScreenRowNum);
|
|
lscroll(hConOut, Ow2TtyParmList[0], SA_BONW);
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
#if DBG
|
|
IF_OD2_DEBUG( VIO )
|
|
{
|
|
KdPrint(("OS2SES(Ow2TtyAnsiCmd): unknown cmd 0x%x\n", c));
|
|
}
|
|
#endif
|
|
ValidCmd = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (!ValidCmd)
|
|
{
|
|
return(2);
|
|
} else if ((Coord.X != Ow2TtyCoord.X) ||
|
|
(Coord.Y != Ow2TtyCoord.Y))
|
|
{
|
|
if(Ow2TtyFlushStr())
|
|
{
|
|
return(1);
|
|
}
|
|
|
|
if(Ow2VioSetCurPos((ULONG)Coord.Y, (ULONG)Coord.X))
|
|
{
|
|
ASSERT1( "OS2SES(VIOTTY): AnsiCmd error on Ow2VioSetCurPos", FALSE );
|
|
}
|
|
|
|
Ow2TtyCoord= SesGrp->WinCoord;
|
|
*NewCoord = TRUE;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
USHORT
|
|
Ow2TtyRange(
|
|
IN USHORT val,
|
|
IN USHORT def,
|
|
IN USHORT min,
|
|
IN USHORT max
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine restrict a value to range or supply a default.
|
|
|
|
Arguments:
|
|
|
|
val - the value to be restricted.
|
|
|
|
default - the value to use if val is zero
|
|
|
|
min - the minimum value
|
|
|
|
max - the maximum value
|
|
|
|
Return Value:
|
|
|
|
|
|
Note:
|
|
|
|
|
|
--*/
|
|
{
|
|
if ( val == 0 )
|
|
val = def;
|
|
if ( val >= max )
|
|
return max;
|
|
if ( val < min )
|
|
return min;
|
|
return val;
|
|
}
|
|
|
|
|
|
DWORD
|
|
Ow2TtySetAttr(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine set new attribute ("ESC[g;...;gm").
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
Should return 0.
|
|
|
|
1 - for any error (after ASSERT), RetCode from GetLastError().
|
|
|
|
Note:
|
|
|
|
Ow2TtyParmNum - length of parameter list
|
|
|
|
Ow2TtyParmList - list of Set Graphics Rendition values
|
|
|
|
Ow2TtyCoord - pointer to current screen coordinates
|
|
|
|
If new attributes is set, it also calls Ow2TtyFlushStr to flush the TTY
|
|
output buffer to the console.
|
|
|
|
hConOut is used for console handle.
|
|
|
|
Uses and updates: SesGrp->AnsiCellAttr, SesGrp->ansi_bold, SesGrp->ansi_blink,
|
|
SesGrp->ansi_background, SesGrp->ansi_foreground, SesGrp->WinAttr
|
|
|
|
--*/
|
|
{
|
|
BYTE NewAttr, LastAttr = SesGrp->AnsiCellAttr[0]; /* attribute of TTY */
|
|
ULONG i;
|
|
USHORT AnsiParm;
|
|
WORD WinAttr;
|
|
#ifdef DBCS
|
|
// MSKK Jun.28.1992 KazuM
|
|
BYTE CommonAttr[3];
|
|
#endif
|
|
|
|
for ( i = 0 ; i < Ow2TtyParmNum ; i++ )
|
|
{
|
|
AnsiParm = Ow2TtyParmList[i];
|
|
|
|
if (AnsiParm == 0)
|
|
{
|
|
/* ATTRIBUTE OFF */
|
|
/*****************/
|
|
|
|
// The default is according to Win. This sequence reset
|
|
// all the attribute only but doesn't change the color.
|
|
// According to VI.exe (set term-ibmans, fail on find-string
|
|
// and Jump to next line till end of screen, #2221, 5/2/93)
|
|
// and the updated os2tst\viowrt.
|
|
|
|
SesGrp->ansi_blink = SesGrp->ansi_bold = 0;
|
|
SesGrp->ansi_background = OS2_BACKGROUND_BLACK;
|
|
SesGrp->ansi_foreground = OS2_FOREGROUND_WHITE;
|
|
|
|
} else if (AnsiParm <= 8)
|
|
{
|
|
if (AnsiParm == 1)
|
|
{
|
|
/* BOLD */
|
|
/********/
|
|
|
|
SesGrp->ansi_bold = 1;
|
|
|
|
} else if (AnsiParm == 2)
|
|
{
|
|
/* FAINT */
|
|
/**********/
|
|
|
|
} else if (AnsiParm == 3)
|
|
{
|
|
/* ITALIC */
|
|
/**********/
|
|
|
|
} else if (AnsiParm == 4)
|
|
{
|
|
/* ?BLUE? */
|
|
/**********/
|
|
|
|
SesGrp->ansi_foreground = OS2_FOREGROUND_BLUE;
|
|
|
|
} else if (AnsiParm == 5)
|
|
{
|
|
/* BLINK */
|
|
/*********/
|
|
|
|
SesGrp->ansi_blink |= 1;
|
|
|
|
} else if (AnsiParm == 6)
|
|
{
|
|
/* RAPID-BLINK */
|
|
/***************/
|
|
|
|
} else if (AnsiParm == 7)
|
|
{
|
|
/* REVERSE VIDEO */
|
|
/*****************/
|
|
|
|
// BLACK over WHITE
|
|
|
|
SesGrp->ansi_foreground = OS2_FOREGROUND_BLACK;
|
|
SesGrp->ansi_background = OS2_BACKGROUND_WHITE;
|
|
|
|
} else if (AnsiParm == 8)
|
|
{
|
|
/* CONCEALED */
|
|
/*************/
|
|
|
|
SesGrp->ansi_background = OS2_BACKGROUND_BLACK;
|
|
SesGrp->ansi_foreground = OS2_FOREGROUND_BLACK;
|
|
}
|
|
|
|
} else if (((AnsiParm >= 30) &&
|
|
(AnsiParm <= 37)) ||
|
|
((AnsiParm >= 40) &&
|
|
(AnsiParm <= 47)))
|
|
{
|
|
/* FORE/BACKGROUND COLOR */
|
|
/*************************/
|
|
|
|
if (AnsiParm >= 40 )
|
|
{
|
|
SesGrp->ansi_background = (BYTE)( ColorTable[AnsiParm%10] << 4);
|
|
} else
|
|
{
|
|
SesGrp->ansi_foreground = (BYTE)ColorTable[AnsiParm%10];
|
|
}
|
|
}
|
|
}
|
|
|
|
NewAttr = SesGrp->ansi_background | SesGrp->ansi_foreground;
|
|
if ( SesGrp->ansi_bold )
|
|
{
|
|
NewAttr |= OS2_FOREGROUND_INTENSITY;
|
|
}
|
|
if ( SesGrp->ansi_blink )
|
|
{
|
|
NewAttr |= OS2_BACKGROUND_BLINKING;
|
|
}
|
|
|
|
if (LastAttr != NewAttr)
|
|
{
|
|
/* new attribute */
|
|
|
|
if(Ow2TtyFlushStr())
|
|
{
|
|
return(1);
|
|
}
|
|
|
|
#ifdef DBCS
|
|
// MSKK Jun.28.1992 KazuM
|
|
CommonAttr[0] = NewAttr;
|
|
CommonAttr[1] = CommonAttr[2] = 0;
|
|
if (!Or2WinSetConsoleTextAttribute(
|
|
#if DBG
|
|
Ow2TtySetAttrStr,
|
|
#endif
|
|
hConOut,
|
|
(WinAttr = MapOs2ToWinAttr(&CommonAttr[0]))))
|
|
#else
|
|
if (!Or2WinSetConsoleTextAttribute(
|
|
#if DBG
|
|
Ow2TtySetAttrStr,
|
|
#endif
|
|
hConOut,
|
|
(WinAttr = MapOs2ToWinAttr(NewAttr))))
|
|
#endif
|
|
{
|
|
#if DBG
|
|
ASSERT1("OS2SES(trans-TTY): failed on SetTextAttribute\n", FALSE);
|
|
#endif
|
|
return (1);
|
|
} else
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( VIO )
|
|
{
|
|
KdPrint(("Ow2TtySetAttr: New attr %x(win %x), Last %x(win %x)\n",
|
|
NewAttr, WinAttr, LastAttr, SesGrp->WinAttr));
|
|
}
|
|
#endif
|
|
SesGrp->AnsiCellAttr[0] = NewAttr;
|
|
SesGrp->WinAttr = (USHORT)WinAttr;
|
|
}
|
|
}
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
|
|
DWORD
|
|
Ow2TtyFlushStr(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine flush the TTY output string (from TTY_DEST_BUFFER)
|
|
to the console.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
Should return 0.
|
|
|
|
1 - for any error (after ASSERT), RetCode from GetLastError().
|
|
|
|
Note:
|
|
|
|
Ow2TtyCoord - pointer to current screen coordinates after the
|
|
flush.
|
|
|
|
According to Ow2TtyNumBytes, which is reset.
|
|
|
|
hConOut is used for console handle.
|
|
|
|
--*/
|
|
{
|
|
DWORD NumWritten;
|
|
|
|
if ( Ow2TtyNumBytes )
|
|
{
|
|
if(!Or2WinWriteConsoleA(
|
|
#if DBG
|
|
Ow2TtyFlushStrStr,
|
|
#endif
|
|
hConOut,
|
|
(LPSTR)TTY_DEST_BUFFER,
|
|
Ow2TtyNumBytes,
|
|
&NumWritten,
|
|
NULL))
|
|
{
|
|
#if DBG
|
|
ASSERT1("OS2SES(VIOTTY): flush string failed on WriteConsoleA", FALSE);
|
|
#endif
|
|
return (1);
|
|
}
|
|
|
|
#if DBG
|
|
if ( Ow2TtyNumBytes != NumWritten )
|
|
{
|
|
ASSERT1("OS2SES(VIOTTY): flush string partial data WriteConsoleA", FALSE);
|
|
//IF_OD2_DEBUG2( VIO, OS2_EXE )
|
|
//{
|
|
// KdPrint(("OS2SES(VIOTTY): flush string partial data WriteConsoleA from %u to %u\n",
|
|
// Ow2TtyNumBytes, NumWritten));
|
|
//}
|
|
}
|
|
#endif
|
|
|
|
Ow2TtyNumBytes = 0;
|
|
Ow2VioUpdateCurPos(Ow2TtyCoord);
|
|
}
|
|
|
|
return (0L);
|
|
}
|
|
|