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.
1816 lines
44 KiB
1816 lines
44 KiB
/* File: D:\WACKER\emu\vt100.c (Created: 08-Dec-1993)
|
|
*
|
|
* Copyright 1994, 1998 by Hilgraeve Inc. -- Monroe, MI
|
|
* All rights reserved
|
|
*
|
|
* $Revision: 11 $
|
|
* $Date: 3/04/02 12:00p $
|
|
*/
|
|
|
|
#include <windows.h>
|
|
#pragma hdrstop
|
|
|
|
#include <tdll\stdtyp.h>
|
|
#include <tdll\tdll.h>
|
|
#include <tdll\htchar.h>
|
|
#include <tdll\session.h>
|
|
#include <tdll\chars.h>
|
|
#include <tdll\com.h>
|
|
#include <tdll\cloop.h>
|
|
#include <tdll\assert.h>
|
|
#include <tdll\print.h>
|
|
#include <tdll\capture.h>
|
|
#include <tdll\update.h>
|
|
#include <tdll\backscrl.h>
|
|
#include <tdll\mc.h>
|
|
|
|
#include "emu.h"
|
|
#include "emu.hh"
|
|
#include "emudec.hh"
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* emuDecGraphic
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to display the normal range of characters
|
|
* for the emulators. It handles insertion modes, end of line wrapping,
|
|
* and cursor positioning.
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
void emuDecGraphic(const HHEMU hhEmu)
|
|
{
|
|
ECHAR ccode = hhEmu->emu_code;
|
|
ECHAR aechBuf[10];
|
|
int iCharsToMove;
|
|
int fDecColHold = FALSE;
|
|
|
|
int iRow = hhEmu->emu_currow;
|
|
int iCol = hhEmu->emu_curcol;
|
|
|
|
ECHAR *tp = hhEmu->emu_apText[hhEmu->emu_imgrow];
|
|
PSTATTR ap = hhEmu->emu_apAttr[hhEmu->emu_imgrow];
|
|
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
// Initialize a test flag. This is used for a special case when
|
|
// emulating a VT100 (and maybe other DEC emulators) and the
|
|
// current column position is the maximum. When a character is placed
|
|
// at emu_maxcol, instead of advancing the cursor to column 0 of the
|
|
// next line, it is instead placed under that last character. When the
|
|
// next character arrives, it is placed at column 0 on the next line, and
|
|
// then the cursor is advanced as expected.
|
|
//
|
|
|
|
// Special DEC test.
|
|
//
|
|
if (hhEmu->mode_AWM && iCol == hhEmu->emu_maxcol)
|
|
{
|
|
if (pstPRI->fDecColHold)
|
|
{
|
|
fDecColHold = FALSE;
|
|
|
|
CaptureLine(sessQueryCaptureFileHdl(hhEmu->hSession),
|
|
CF_CAP_LINES,
|
|
tp,
|
|
emuRowLen(hhEmu, hhEmu->emu_imgrow));
|
|
|
|
printEchoString(hhEmu->hPrintEcho,
|
|
tp,
|
|
emuRowLen(hhEmu, hhEmu->emu_imgrow));
|
|
|
|
|
|
CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), TEXT("\r\n"),
|
|
StrCharGetByteCount(TEXT("\r\n")));
|
|
printEchoString(hhEmu->hPrintEcho,
|
|
aechBuf,
|
|
sizeof(ECHAR) * 2);
|
|
|
|
if (iRow == hhEmu->bottom_margin)
|
|
(*hhEmu->emu_scroll)(hhEmu, 1, TRUE);
|
|
else
|
|
++iRow;
|
|
|
|
iCol = 0;
|
|
(*hhEmu->emu_setcurpos)(hhEmu, iRow, iCol);
|
|
|
|
tp = hhEmu->emu_apText[hhEmu->emu_imgrow];
|
|
ap = hhEmu->emu_apAttr[hhEmu->emu_imgrow];
|
|
}
|
|
|
|
else
|
|
{
|
|
iCol = hhEmu->emu_maxcol;
|
|
fDecColHold = TRUE;
|
|
}
|
|
}
|
|
|
|
// Is the emulator in insert mode?
|
|
//
|
|
if (hhEmu->mode_IRM == SET)
|
|
{
|
|
iCharsToMove = (hhEmu->emu_aiEnd[hhEmu->emu_imgrow] - iCol + 1);
|
|
|
|
if (iCharsToMove + iCol >= hhEmu->emu_maxcol)
|
|
iCharsToMove -= 1;
|
|
|
|
if (iCharsToMove > 0)
|
|
{
|
|
memmove(&tp[iCol+1],
|
|
&tp[iCol],
|
|
(unsigned)iCharsToMove * sizeof(ECHAR));
|
|
|
|
memmove(&ap[iCol+1],
|
|
&ap[iCol],
|
|
(unsigned)iCharsToMove * sizeof(ECHAR));
|
|
|
|
hhEmu->emu_aiEnd[hhEmu->emu_imgrow] =
|
|
min(hhEmu->emu_aiEnd[hhEmu->emu_imgrow] + 1,
|
|
hhEmu->emu_maxcol - 1);
|
|
}
|
|
}
|
|
|
|
// Our competetor's are eating the NULL's. DOS ANSI doesn't.
|
|
// For now we'll try it their way... - mrw
|
|
//
|
|
if (ccode == (ECHAR)0)
|
|
return;
|
|
|
|
// Place the character and the current attribute into the image.
|
|
//
|
|
if (((hhEmu->stUserSettings.nEmuId == EMU_VT100) ||
|
|
(hhEmu->stUserSettings.nEmuId == EMU_VT220) ||
|
|
(hhEmu->stUserSettings.nEmuId == EMU_VT320) ||
|
|
(hhEmu->stUserSettings.nEmuId == EMU_VT100PLUS) ||
|
|
(hhEmu->stUserSettings.nEmuId == EMU_VTUTF8)) &&
|
|
ccode < sizeof(hhEmu->dspchar))
|
|
ccode = hhEmu->dspchar[ccode];
|
|
|
|
tp[iCol] = ccode;
|
|
ap[iCol] = hhEmu->emu_charattr;
|
|
|
|
// Check for double high, double wide processing.
|
|
//
|
|
if (pstPRI->aiLineAttr[hhEmu->emu_imgrow] != NO_LINE_ATTR)
|
|
{
|
|
int iColPrev = iCol;
|
|
|
|
ap[iCol].dblwilf = 1;
|
|
ap[iCol].dblwirt = 0;
|
|
ap[iCol].dblhihi = (pstPRI->aiLineAttr[hhEmu->emu_imgrow] == DBL_WIDE_HI) ? 1 : 0;
|
|
ap[iCol].dblhilo = (pstPRI->aiLineAttr[hhEmu->emu_imgrow] == DBL_WIDE_LO) ? 1 : 0;
|
|
|
|
iCol = min(iCol+1, hhEmu->emu_maxcol);
|
|
|
|
tp[iCol] = ccode;
|
|
ap[iCol] = ap[iColPrev];
|
|
ap[iCol].dblwilf = 0;
|
|
ap[iCol].dblwirt = 1;
|
|
}
|
|
|
|
#ifndef CHAR_NARROW
|
|
// Process Double Byte Characters
|
|
//
|
|
if (QueryCLoopMBCSState(sessQueryCLoopHdl(hhEmu->hSession)))
|
|
{
|
|
if (isDBCSChar(ccode))
|
|
{
|
|
int iColPrev = iCol;
|
|
|
|
ap[iCol].wilf = 1;
|
|
ap[iCol].wirt = 0;
|
|
|
|
iCol = min(iCol+1, hhEmu->emu_maxcol);
|
|
|
|
tp[iCol] = ccode;
|
|
ap[iCol] = ap[iColPrev];
|
|
ap[iCol].wilf = 0;
|
|
ap[iCol].wirt = 1;
|
|
}
|
|
#if 0
|
|
//mpt:1-23-98 handles the case when an incoming character
|
|
// (single or double byte) overwrites the first half of
|
|
// a double byte character
|
|
if ( iCol < hhEmu->emu_maxcol )
|
|
{
|
|
//if we orphaned a right half of a dbcs char
|
|
if (hhEmu->emu_apAttr[iRow][iCol + 1].wirt == TRUE)
|
|
{
|
|
//slide characters and attribs to left
|
|
iCharsToMove = hhEmu->emu_aiEnd[hhEmu->emu_imgrow] - iCol - 1;
|
|
if (iCol + 2 < hhEmu->emu_maxcol && iCharsToMove > 0)
|
|
{
|
|
memmove(&tp[iCol + 1],
|
|
&tp[iCol + 2],
|
|
(unsigned)iCharsToMove * sizeof(ECHAR));
|
|
|
|
memmove(&ap[iCol + 1],
|
|
&ap[iCol + 2],
|
|
(unsigned)iCharsToMove * sizeof(ECHAR));
|
|
}
|
|
|
|
//blank out character at end of line
|
|
tp[hhEmu->emu_aiEnd[hhEmu->emu_imgrow]] = 32;
|
|
ap[hhEmu->emu_aiEnd[hhEmu->emu_imgrow]].wirt = 0;
|
|
|
|
//move end of row since we removed a character
|
|
hhEmu->emu_aiEnd[hhEmu->emu_imgrow]--;
|
|
|
|
//update the image
|
|
updateChar(sessQueryUpdateHdl(hhEmu->hSession),
|
|
hhEmu->emu_imgrow,
|
|
hhEmu->emu_aiEnd[hhEmu->emu_imgrow],
|
|
hhEmu->mode_IRM ?
|
|
hhEmu->emu_maxcol :
|
|
hhEmu->emu_aiEnd[hhEmu->emu_imgrow]);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
#endif //CHAR_NARROW
|
|
|
|
// Update the end of row index if necessary.
|
|
//
|
|
if (iCol > hhEmu->emu_aiEnd[hhEmu->emu_imgrow])
|
|
hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = iCol;
|
|
|
|
// Update the image.
|
|
//
|
|
updateChar(sessQueryUpdateHdl(hhEmu->hSession),
|
|
iRow,
|
|
hhEmu->emu_curcol,
|
|
hhEmu->mode_IRM ? hhEmu->emu_maxcol : iCol);
|
|
|
|
// Move the position of the cursor ahead of the last character
|
|
// displayed, checking for end of line wrap.
|
|
//
|
|
iCol += 1;
|
|
|
|
// Finally, set the cursor position. This wil reset emu_currow
|
|
// and emu_curcol.
|
|
//
|
|
(*hhEmu->emu_setcurpos)(hhEmu, iRow, iCol);
|
|
|
|
// Whenever we call setcurpos, it resets pstPRI->fDecColHold so
|
|
// don't set till after we postion cursor.
|
|
//
|
|
pstPRI->fDecColHold = fDecColHold;
|
|
return;
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* ANSI_DA
|
|
*
|
|
* DESCRIPTION:
|
|
* Sends the device attribute (DA) report to the host.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void ANSI_DA(const HHEMU hhEmu)
|
|
{
|
|
int fOldValue;
|
|
ECHAR ech[15];
|
|
|
|
CnvrtMBCStoECHAR(ech, sizeof(ech), TEXT("\033[?1;2c"),
|
|
StrCharGetByteCount(TEXT("\033[?1;2c")));
|
|
|
|
fOldValue = CLoopGetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession));
|
|
|
|
CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), FALSE);
|
|
|
|
emuSendString(hhEmu, ech, (int)StrCharGetEcharByteCount(ech));
|
|
|
|
CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), fOldValue);
|
|
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* vt100_savecursor
|
|
*
|
|
* DESCRIPTION:
|
|
* Saves the current cursor postion; and, it also
|
|
* saves display attributes, character set, wrap mode, and origin mode.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*
|
|
* NOTES:
|
|
* This function contains Auto Detect code.
|
|
*/
|
|
void vt100_savecursor(const HHEMU hhEmu)
|
|
{
|
|
ECHAR sel;
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
sel = hhEmu->emu_code;
|
|
|
|
if (sel == ETEXT('7')) /* save cursor & attributes */
|
|
{
|
|
(*hhEmu->emu_getcurpos)(hhEmu, &pstPRI->sv_row, &pstPRI->sv_col);
|
|
pstPRI->sv_state = hhEmu->iCurAttrState;
|
|
pstPRI->sv_attr = hhEmu->attrState[hhEmu->iCurAttrState];
|
|
vt_charset_save(hhEmu);
|
|
pstPRI->sv_AWM = hhEmu->mode_AWM;
|
|
pstPRI->sv_DECOM = hhEmu->mode_DECOM;
|
|
pstPRI->sv_protectmode = hhEmu->mode_protect;
|
|
pstPRI->fAttrsSaved = TRUE;
|
|
}
|
|
|
|
else if (sel == ETEXT('8')) /* restore cursor and attr. */
|
|
{
|
|
(*hhEmu->emu_setcurpos)(hhEmu, pstPRI->sv_row, pstPRI->sv_col);
|
|
|
|
//if (pstPRI->sv_col == hhEmu->emu_maxcol)
|
|
// hhEmu->emu_curcol = pstPRI->sv_col; /* in order to wrap on next char */
|
|
|
|
if (pstPRI->fAttrsSaved)
|
|
{
|
|
hhEmu->iCurAttrState = pstPRI->sv_state;
|
|
|
|
hhEmu->attrState[hhEmu->iCurAttrState] = pstPRI->sv_attr;
|
|
|
|
hhEmu->emu_charattr = hhEmu->attrState[hhEmu->iCurAttrState];
|
|
}
|
|
|
|
vt_charset_restore(hhEmu);
|
|
|
|
hhEmu->mode_AWM = pstPRI->sv_AWM;
|
|
hhEmu->mode_DECOM = pstPRI->sv_DECOM;
|
|
hhEmu->mode_protect = pstPRI->sv_protectmode;
|
|
}
|
|
|
|
else /* clear saved conditions */
|
|
{
|
|
pstPRI->sv_row = pstPRI->sv_col = 0;
|
|
pstPRI->sv_state = hhEmu->iCurAttrState;
|
|
pstPRI->sv_AWM = pstPRI->sv_DECOM = RESET;
|
|
pstPRI->sv_protectmode = FALSE;
|
|
pstPRI->fAttrsSaved = FALSE;
|
|
}
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* vt100_answerback
|
|
*
|
|
* DESCRIPTION:
|
|
* Sends the answerback message defined on the menus.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void vt100_answerback(const HHEMU hhEmu)
|
|
{
|
|
int fOldValue;
|
|
TCHAR *sp;
|
|
ECHAR *pech = NULL;
|
|
|
|
sp = hhEmu->acAnswerback;
|
|
|
|
// If there is nothing to send, there is nothing to send
|
|
if (StrCharGetStrLength(sp) == 0)
|
|
return;
|
|
|
|
pech = malloc((unsigned int)StrCharGetByteCount(sp));
|
|
if (pech == NULL)
|
|
{
|
|
assert(FALSE);
|
|
return;
|
|
}
|
|
|
|
CnvrtMBCStoECHAR(pech, StrCharGetByteCount(sp), sp, StrCharGetByteCount(sp));
|
|
|
|
/* to not get recursive answerback's in half duplex */
|
|
|
|
fOldValue = CLoopGetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession));
|
|
|
|
CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), FALSE);
|
|
|
|
emuSendString(hhEmu, pech, (int)StrCharGetEcharByteCount(pech));
|
|
free(pech);
|
|
pech = NULL;
|
|
|
|
CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), fOldValue);
|
|
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* vt100_hostreset
|
|
*
|
|
* DESCRIPTION:
|
|
* Calls vt100_reset() when told to reset by the host.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void vt100_hostreset(const HHEMU hhEmu)
|
|
{
|
|
vt100_reset(hhEmu, TRUE);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* vt100_reset
|
|
*
|
|
* DESCRIPTION:
|
|
* Resets the emulator.
|
|
*
|
|
* ARGUMENTS:
|
|
* host_request -- TRUE when told to reset by the host.
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
int vt100_reset(const HHEMU hhEmu, const int host_request)
|
|
{
|
|
hhEmu->mode_KAM = hhEmu->mode_IRM = hhEmu->mode_VEM =
|
|
hhEmu->mode_HEM = hhEmu->mode_LNM = hhEmu->mode_DECCKM =
|
|
hhEmu->mode_DECOM = hhEmu->mode_DECCOLM = hhEmu->mode_DECPFF =
|
|
hhEmu->mode_DECPEX = hhEmu->mode_DECSCNM = hhEmu->mode_25enab =
|
|
hhEmu->mode_protect = hhEmu->mode_block =
|
|
hhEmu->mode_local = RESET;
|
|
|
|
hhEmu->mode_SRM = hhEmu->mode_DECTCEM = SET;
|
|
|
|
hhEmu->mode_AWM = hhEmu->stUserSettings.fWrapLines;
|
|
|
|
vt_charset_init(hhEmu);
|
|
if (host_request)
|
|
{
|
|
ANSI_Pn_Clr(hhEmu);
|
|
ANSI_SGR(hhEmu);
|
|
ANSI_RIS(hhEmu);
|
|
}
|
|
hhEmu->emu_code = ETEXT('>');
|
|
|
|
vt_alt_kpmode(hhEmu);
|
|
|
|
if (hhEmu->stUserSettings.nEmuId == EMU_ANSI ||
|
|
hhEmu->stUserSettings.nEmuId == EMU_AUTO)
|
|
hhEmu->emu_kbdin = ansi_kbdin;
|
|
else
|
|
hhEmu->emu_kbdin = vt100_kbdin;
|
|
|
|
hhEmu->mode_AWM = RESET;
|
|
hhEmu->stUserSettings.fWrapLines = RESET;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* vt100_report
|
|
*
|
|
* DESCRIPTION:
|
|
* Sends the current terminal parameters specified by the DECREQTPARM.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void vt100_report(const HHEMU hhEmu)
|
|
{
|
|
int sol, i = 0, xspeed = 0;
|
|
TCHAR str[20];
|
|
TCHAR tempstr[4];
|
|
ECHAR ech[20];
|
|
int fOldValue;
|
|
TCHAR *sp;
|
|
long lBaud;
|
|
int nDataBits, nParity;
|
|
|
|
HCOM hCom;
|
|
|
|
static int baudrates[] = {50, 75, 110, 135, 150, 200, 300, 600, 1200,
|
|
1800, 2000, 2400, 2600, 4800, 9600, 19200};
|
|
|
|
sol = hhEmu->num_param[0];
|
|
if (sol != 0 && sol != 1)
|
|
return;
|
|
|
|
wsprintf(str, TEXT("\x01B[%s;"),
|
|
sol == 0 ? (LPTSTR)TEXT("2") : (LPTSTR)TEXT("3"));
|
|
|
|
hCom = sessQueryComHdl(hhEmu->hSession);
|
|
ComGetBaud(hCom, &lBaud);
|
|
ComGetDataBits(hCom, &nDataBits);
|
|
ComGetParity(hCom, &nParity);
|
|
|
|
// Parity
|
|
//
|
|
if (nParity == 0) // None
|
|
StrCharCat(str, TEXT("1;"));
|
|
else if (nParity == 1) // Odd
|
|
StrCharCat(str, TEXT("4;"));
|
|
else // Even
|
|
StrCharCat(str, TEXT("5;"));
|
|
|
|
// Data bits
|
|
//
|
|
nDataBits == 8 ? StrCharCat(str, TEXT("1;")) : StrCharCat(str, TEXT("2;"));
|
|
|
|
while (xspeed < 120)
|
|
{
|
|
if ((long)baudrates[i] >= lBaud)
|
|
break;
|
|
i++;
|
|
xspeed += 8;
|
|
}
|
|
|
|
// Recieving speed
|
|
//
|
|
wsprintf(tempstr, "%d", xspeed);
|
|
StrCharCat(str, tempstr);
|
|
|
|
// Sending speed
|
|
//
|
|
StrCharCat(str, TEXT(";"));
|
|
StrCharCat(str, tempstr);
|
|
|
|
// Bit rate multiplier ; Flags
|
|
//
|
|
StrCharCat(str, TEXT(";1;0x"));
|
|
|
|
sp = str;
|
|
|
|
CnvrtMBCStoECHAR(ech, sizeof(ech), sp, StrCharGetByteCount(sp));
|
|
|
|
/* to not get recursive vt100_report's if half duplex */
|
|
|
|
fOldValue = CLoopGetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession));
|
|
|
|
CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), FALSE);
|
|
|
|
emuSendString(hhEmu, ech, (int)StrCharGetEcharByteCount(ech));
|
|
|
|
CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), fOldValue);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* vt100_kbdin
|
|
*
|
|
* DESCRIPTION:
|
|
* Processes local keyboard keys for the VT100 emulator.
|
|
* Note: mode_DECKPAM is TRUE or SET when in DEC KeyPad Aplication Mode.
|
|
* Removed key processing 1/3/92. Will replace with something resonable
|
|
* later - mrw.
|
|
*
|
|
* ARGUMENTS:
|
|
* key -- key to process
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
int vt100_kbdin(const HHEMU hhEmu, int key, const int fTest)
|
|
{
|
|
int index = 0;
|
|
/* -------------- Check Backspace & Delete keys ------------- */
|
|
|
|
if (hhEmu->stUserSettings.fReverseDelBk && ((key == VK_BACKSPACE) ||
|
|
(key == DELETE_KEY) || (key == DELETE_KEY_EXT)))
|
|
{
|
|
key = (key == VK_BACKSPACE) ? DELETE_KEY : VK_BACKSPACE;
|
|
}
|
|
|
|
/* -------------- Mapped PF1-PF4 keys ------------- */
|
|
|
|
#if 0 // mrw:11/3/95 - removed because we can't control num-lock
|
|
// in Win95
|
|
else if (hhEmu->stUserSettings.fMapPFkeys &&
|
|
(index = emuKbdKeyLookup(hhEmu, key, &hhEmu->stEmuKeyTbl4)) != -1)
|
|
{
|
|
if (!fTest)
|
|
emuSendKeyString(hhEmu, index, &hhEmu->stEmuKeyTbl4);
|
|
}
|
|
#endif
|
|
|
|
/* -------------- Cursor Key Mode ------------- */
|
|
|
|
else if (hhEmu->mode_DECCKM == SET &&
|
|
(index = emuKbdKeyLookup(hhEmu, key, &hhEmu->stEmuKeyTbl3)) != -1)
|
|
{
|
|
if (!fTest)
|
|
emuSendKeyString(hhEmu, index, &hhEmu->stEmuKeyTbl3);
|
|
}
|
|
|
|
/* -------------- Keypad Application Mode ------------- */
|
|
|
|
else if (hhEmu->mode_DECKPAM &&
|
|
(index = emuKbdKeyLookup(hhEmu, key, &hhEmu->stEmuKeyTbl2)) != -1)
|
|
{
|
|
if (!fTest)
|
|
emuSendKeyString(hhEmu, index, &hhEmu->stEmuKeyTbl2);
|
|
}
|
|
|
|
/* -------------- Normal keys ------------- */
|
|
|
|
else if ((index = emuKbdKeyLookup(hhEmu, key, &hhEmu->stEmuKeyTbl)) != -1)
|
|
{
|
|
if (!fTest)
|
|
emuSendKeyString(hhEmu, index, &hhEmu->stEmuKeyTbl);
|
|
}
|
|
|
|
else
|
|
{
|
|
index = std_kbdin(hhEmu, key, fTest);
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
#if FALSE // Never used in HyperTerminal.
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* fakevt_kbdin
|
|
*
|
|
* DESCRIPTION:
|
|
* Processes local keyboard keys for the WANG, IBM3278 & RENX3278 emulators.
|
|
*
|
|
* ARGUMENTS:
|
|
* key -- key to process
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
int fakevt_kbdin(const HHEMU hhEmu, int key, const int fTest)
|
|
{
|
|
int index;
|
|
|
|
/* -------------- Check Backspace & Delete keys ------------- */
|
|
|
|
if (hhEmu->stUserSettings.fReverseDelBk && ((key == VK_BACKSPACE) ||
|
|
(key == DELETE_KEY) || key == DELETE_KEY_EXT))
|
|
{
|
|
key = (key == VK_BACKSPACE) ? DELETE_KEY : VK_BACKSPACE;
|
|
}
|
|
|
|
if ((index = emuKbdKeyLookup(hhEmu, key, &hhEmu->stEmuKeyTbl)) != -1)
|
|
{
|
|
if (!fTest)
|
|
emuSendKeyString(hhEmu, index, &hhEmu->stEmuKeyTbl);
|
|
}
|
|
|
|
else
|
|
{
|
|
index = std_kbdin(hhEmu, key, fTest);
|
|
}
|
|
|
|
return index;
|
|
}
|
|
#endif
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* vt100PrintCommands
|
|
*
|
|
* DESCRIPTION:
|
|
* Processes VT100 printing commands.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void vt100PrintCommands(const HHEMU hhEmu)
|
|
{
|
|
int line;
|
|
int from;
|
|
int to;
|
|
ECHAR sel;
|
|
ECHAR aechBuf[10];
|
|
|
|
sel = (ECHAR)hhEmu->selector[0];
|
|
|
|
switch (sel)
|
|
{
|
|
// Auto print on.
|
|
//
|
|
case ETEXT(0xF5):
|
|
hhEmu->print_echo = TRUE;
|
|
printSetStatus(hhEmu->hPrintEcho, TRUE);
|
|
break;
|
|
|
|
// Auto print off.
|
|
//
|
|
case ETEXT(0xF4):
|
|
hhEmu->print_echo = FALSE;
|
|
printSetStatus(hhEmu->hPrintEcho, FALSE);
|
|
printEchoClose(hhEmu->hPrintEcho);
|
|
|
|
break;
|
|
|
|
// Print screen.
|
|
//
|
|
case ETEXT(0x00):
|
|
if (hhEmu->mode_DECPEX == RESET)
|
|
from = hhEmu->top_margin, to = hhEmu->bottom_margin;
|
|
else
|
|
from = 0, to = EMU_DEFAULT_MAXROW;
|
|
|
|
for (line = from; line <= to; ++line)
|
|
printEchoLine(hhEmu->hPrintHost,
|
|
hhEmu->emu_apText[row_index(hhEmu, line)],
|
|
emuRowLen(hhEmu, row_index(hhEmu, line)));
|
|
|
|
if (hhEmu->mode_DECPFF == SET) /* print form feed */
|
|
{
|
|
CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), TEXT("0x0C"),
|
|
StrCharGetByteCount(TEXT("0x0C")));
|
|
printEchoLine(hhEmu->hPrintHost, aechBuf, sizeof(ECHAR));
|
|
}
|
|
|
|
break;
|
|
|
|
// Print Cursor line.
|
|
//
|
|
case ETEXT(0xF1):
|
|
printEchoLine(hhEmu->hPrintEcho,
|
|
hhEmu->emu_apText[row_index(hhEmu,
|
|
hhEmu->emu_currow)],
|
|
emuRowLen(hhEmu,
|
|
row_index(hhEmu, hhEmu->emu_currow)));
|
|
break;
|
|
|
|
// Enter printer controller mode. State is hard coded for now...
|
|
// Bad news.
|
|
//
|
|
case ETEXT(0x05):
|
|
hhEmu->state = 6;
|
|
printSetStatus(hhEmu->hPrintHost, TRUE);
|
|
break;
|
|
|
|
// Exit printer controller mode. This is seen when not in
|
|
// controller mode.
|
|
//
|
|
case ETEXT(0x04):
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void vt100_prnc(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
ECHAR aechBuf[10];
|
|
size_t size;
|
|
|
|
*pstPRI->pntr++ = hhEmu->emu_code;
|
|
*pstPRI->pntr = 0;
|
|
++pstPRI->len_s;
|
|
|
|
CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), TEXT("\033[4i"),
|
|
StrCharGetByteCount(TEXT("\033[4i")));
|
|
|
|
size = (size_t)StrCharGetByteCount(TEXT("\033[4i"));
|
|
if ((pstPRI->len_s >= 4) && (memcmp(pstPRI->pntr - 4, aechBuf, size) == 0))
|
|
{
|
|
/* received termination string, wrap it up */
|
|
#if defined(INCL_PRINT_PASSTHROUGH)
|
|
if( !hhEmu->stUserSettings.fPrintRaw)
|
|
{
|
|
printEchoRaw(hhEmu->hPrintHost, pstPRI->storage, pstPRI->len_s - ((*(pstPRI->pntr - 3) == (TCHAR)TEXT('\233')) ? 3 : 4));
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
emuPrintChars(hhEmu, pstPRI->storage, pstPRI->len_s - ((*(pstPRI->pntr - 3) == (TCHAR)TEXT('\233')) ? 3 : 4));
|
|
printEchoChar(hhEmu->hPrintHost, ETEXT('\n'));
|
|
}
|
|
|
|
pstPRI->pntr = pstPRI->storage;
|
|
pstPRI->len_s = 0;
|
|
hhEmu->state = 0; /* drop out of this routine */
|
|
|
|
// Finish-up print job
|
|
DbgOutStr("print-control off\r\n", 0, 0, 0, 0, 0);
|
|
printEchoClose(hhEmu->hPrintHost);
|
|
return;
|
|
}
|
|
|
|
/* haven't received termination sequence yet, is storage filled? */
|
|
if (pstPRI->len_s >= (int)(sizeof(pstPRI->storage) - 1))
|
|
{
|
|
/* copy most of string to print buffer */
|
|
#if defined(INCL_PRINT_PASSTHROUGH)
|
|
if( !hhEmu->stUserSettings.fPrintRaw )
|
|
{
|
|
printEchoRaw(hhEmu->hPrintHost, pstPRI->storage, pstPRI->len_s - 4);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
emuPrintChars(hhEmu, pstPRI->storage, pstPRI->len_s - 4);\
|
|
}
|
|
|
|
/* move end of string to beginning of storage */
|
|
memmove(pstPRI->storage, &pstPRI->storage[pstPRI->len_s - 4], 4 * sizeof(ECHAR));
|
|
pstPRI->pntr = pstPRI->storage + 4;
|
|
pstPRI->len_s = 4;
|
|
}
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
void emuSetDoubleAttr(const HHEMU hhEmu)
|
|
{
|
|
|
|
switch(hhEmu->emu_code)
|
|
{
|
|
// Double width, double height, top half.
|
|
//
|
|
case '3':
|
|
emuSetDoubleAttrRow(hhEmu, DBL_WIDE_HI);
|
|
break;
|
|
|
|
// Double width double height, bottom half.
|
|
//
|
|
case '4':
|
|
emuSetDoubleAttrRow(hhEmu, DBL_WIDE_LO);
|
|
break;
|
|
|
|
// Single width single height.
|
|
//
|
|
case '5':
|
|
emuSetSingleAttrRow(hhEmu);
|
|
break;
|
|
|
|
// Double width, single height.
|
|
//
|
|
case '6':
|
|
emuSetDoubleAttrRow(hhEmu, DBL_WIDE_SINGLE_HEIGHT);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
void emuSetSingleAttrRow(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int iOldRow,
|
|
iOldCol,
|
|
iImgRow;
|
|
|
|
// Determine the image row.
|
|
//
|
|
iImgRow = row_index(hhEmu, hhEmu->emu_currow);
|
|
|
|
// If the current line attribute is the same as the one we're
|
|
// being asked to change to, get out-a-town.
|
|
//
|
|
if (pstPRI->aiLineAttr[iImgRow] == NO_LINE_ATTR)
|
|
return;
|
|
|
|
// Get the current cursor position.
|
|
//
|
|
std_getcurpos(hhEmu, &iOldRow, &iOldCol);
|
|
|
|
// Convert the current row.
|
|
//
|
|
emuFromDblToSingle(hhEmu);
|
|
|
|
// Update the line.
|
|
//
|
|
updateLine(sessQueryUpdateHdl(hhEmu->hSession),
|
|
hhEmu->emu_currow,
|
|
hhEmu->emu_currow);
|
|
|
|
// Put the cursor back to where it was, or at the new rightmost
|
|
// margin, whichever is less.
|
|
//
|
|
iOldCol = iOldCol / 2;
|
|
iOldCol = min(iOldCol, hhEmu->emu_maxcol);
|
|
std_setcurpos(hhEmu, iOldRow, iOldCol);
|
|
|
|
// Finally, update this rows line attribute value.
|
|
//
|
|
pstPRI->aiLineAttr[iImgRow] = NO_LINE_ATTR;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
void emuSetDoubleAttrRow(const HHEMU hhEmu, const int iLineAttr)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int iChar,
|
|
iImgRow,
|
|
iOldRow,
|
|
iOldCol,
|
|
iUpperAttr,
|
|
iLowerAttr;
|
|
|
|
// Determine the image row.
|
|
//
|
|
iImgRow = row_index(hhEmu, hhEmu->emu_currow);
|
|
|
|
// If the current line attribute is the same as the one we're
|
|
// being asked to change to, get out-a-town.
|
|
//
|
|
if (pstPRI->aiLineAttr[iImgRow] == iLineAttr)
|
|
return;
|
|
|
|
// Get the current cursor position.
|
|
//
|
|
std_getcurpos(hhEmu, &iOldRow, &iOldCol);
|
|
|
|
// If the current line attribute is anything but NO_LINE_ATTR, call
|
|
// a routine that will first put the row back into that state. That
|
|
// is, this routine converts FROM a standard line INTO a double wide
|
|
// line.
|
|
//
|
|
if (pstPRI->aiLineAttr[iImgRow] != NO_LINE_ATTR)
|
|
{
|
|
emuFromDblToSingle(hhEmu);
|
|
iOldCol = iOldCol / 2;
|
|
}
|
|
|
|
// Start a shell game!
|
|
//
|
|
iChar = (hhEmu->emu_maxcol+1) / 2;
|
|
|
|
// Remember that both of the following values will be zero in the
|
|
// case of processing a DBL_WIDE_SINGLE_HEIGHT request.
|
|
//
|
|
iUpperAttr = (iLineAttr == DBL_WIDE_HI) ? 1 : 0;
|
|
iLowerAttr = (iLineAttr == DBL_WIDE_LO) ? 1 : 0;
|
|
|
|
while (iChar >= 0)
|
|
{
|
|
hhEmu->emu_apText[iImgRow][(iChar * 2) + 1] = hhEmu->emu_apText[iImgRow][iChar];
|
|
hhEmu->emu_apAttr[iImgRow][(iChar * 2) + 1].dblwirt = 1;
|
|
hhEmu->emu_apAttr[iImgRow][(iChar * 2) + 1].dblwilf = 0;
|
|
hhEmu->emu_apAttr[iImgRow][(iChar * 2) + 1].dblhihi = (unsigned)iUpperAttr;
|
|
hhEmu->emu_apAttr[iImgRow][(iChar * 2) + 1].dblhilo = (unsigned)iLowerAttr;
|
|
|
|
hhEmu->emu_apText[iImgRow][(iChar * 2)] = hhEmu->emu_apText[iImgRow][iChar];
|
|
hhEmu->emu_apAttr[iImgRow][(iChar * 2)].dblwirt = 0;
|
|
hhEmu->emu_apAttr[iImgRow][(iChar * 2)].dblwilf = 1;
|
|
hhEmu->emu_apAttr[iImgRow][(iChar * 2)].dblhihi = (unsigned)iUpperAttr;
|
|
hhEmu->emu_apAttr[iImgRow][(iChar * 2)].dblhilo = (unsigned)iLowerAttr;
|
|
|
|
iChar--;
|
|
}
|
|
|
|
// Null terminate the new text image.
|
|
//
|
|
hhEmu->emu_apText[iImgRow][hhEmu->emu_maxcol + 1] = ETEXT('\0');
|
|
|
|
// Update the line.
|
|
//
|
|
updateLine(sessQueryUpdateHdl(hhEmu->hSession),
|
|
hhEmu->emu_currow,
|
|
hhEmu->emu_currow);
|
|
|
|
// Put the cursor back to where it was, or at the new rightmost
|
|
// margin, whichever is less.
|
|
//
|
|
iOldCol = iOldCol * 2;
|
|
iOldCol = min(iOldCol, hhEmu->emu_maxcol);
|
|
std_setcurpos(hhEmu, iOldRow, iOldCol);
|
|
|
|
// Finally, update this rows line attribute value.
|
|
//
|
|
pstPRI->aiLineAttr[iImgRow] = iLineAttr;
|
|
|
|
return;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
* emuFromDblToSingle
|
|
*
|
|
* DESCRIPTION:
|
|
* Note that this is a utility function and does not update the emulator
|
|
* image. The calling function should do this.
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
void emuFromDblToSingle(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
register int i;
|
|
|
|
int iSource,
|
|
iDest,
|
|
iLastCol,
|
|
iImgRow;
|
|
|
|
// Determine the image row.
|
|
//
|
|
iImgRow = row_index(hhEmu, hhEmu->emu_currow);
|
|
|
|
// If the current line attribute is the same as the one we're
|
|
// being asked to change to, get out-a-town.
|
|
//
|
|
if (pstPRI->aiLineAttr[iImgRow] == NO_LINE_ATTR)
|
|
return;
|
|
|
|
// A new shell game.
|
|
//
|
|
iSource = 0;
|
|
iDest = 0;
|
|
|
|
iLastCol = (hhEmu->emu_maxcol+1) / 2;
|
|
|
|
// TODO: JCM - in two location below, the text buffer is set to
|
|
// spaces, instead of nulls. Figure out why this is the case. We
|
|
// should be able to set these to nulls.
|
|
|
|
while (iSource <= hhEmu->emu_maxcol)
|
|
{
|
|
if (hhEmu->emu_apText[iImgRow][iSource] == ETEXT('\0')) // TODO 1:
|
|
hhEmu->emu_apText[iImgRow][iDest] = ETEXT(' ');
|
|
else
|
|
hhEmu->emu_apText[iImgRow][iDest] =
|
|
hhEmu->emu_apText[iImgRow][iSource];
|
|
|
|
hhEmu->emu_apAttr[iImgRow][iDest].dblwirt = 0;
|
|
hhEmu->emu_apAttr[iImgRow][iDest].dblwilf = 0;
|
|
hhEmu->emu_apAttr[iImgRow][iDest].dblhihi = 0;
|
|
hhEmu->emu_apAttr[iImgRow][iDest].dblhilo = 0;
|
|
|
|
iSource += 2;
|
|
iDest += 1;
|
|
}
|
|
|
|
for (i = iLastCol; i < MAX_EMUCOLS ; ++i)
|
|
{
|
|
hhEmu->emu_apText[iImgRow][i] = ETEXT(' '); // TODO 2:
|
|
hhEmu->emu_apAttr[iImgRow][i] = hhEmu->emu_clearattr;
|
|
/*
|
|
hhEmu->emu_apAttr[iImgRow][i].dblwirt = 0;
|
|
hhEmu->emu_apAttr[iImgRow][i].dblwilf = 0;
|
|
hhEmu->emu_apAttr[iImgRow][i].dblhihi = 0;
|
|
hhEmu->emu_apAttr[iImgRow][i].dblhilo = 0;
|
|
*/
|
|
}
|
|
|
|
pstPRI->aiLineAttr[iImgRow] = NO_LINE_ATTR;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* FUNCTION:
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
void emuDecTab(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int col;
|
|
|
|
col = hhEmu->emu_curcol;
|
|
|
|
while (col <= hhEmu->emu_maxcol)
|
|
{
|
|
if (hhEmu->tab_stop[++col])
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (pstPRI->aiLineAttr[hhEmu->emu_imgrow] != NO_LINE_ATTR)
|
|
col = (col * 2) - 1;
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, col);
|
|
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecCUF
|
|
*
|
|
* DESCRIPTION:
|
|
* Moves the cursor forward the specified number of characters, but stops
|
|
* at the last character in the current line.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuDecCUF(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int nchars, col;
|
|
|
|
nchars = hhEmu->num_param[hhEmu->num_param_cnt];
|
|
|
|
if (nchars < 1)
|
|
nchars = 1;
|
|
|
|
if (pstPRI->aiLineAttr[hhEmu->emu_imgrow])
|
|
nchars = (nchars * 2);
|
|
|
|
col = hhEmu->emu_curcol;
|
|
col += nchars;
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, col);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecCUP
|
|
*
|
|
* DESCRIPTION:
|
|
* Positions the cursor at the specified row and column. The row & column
|
|
* numbering start at 1. If origin mode is on, the positioning is relative
|
|
* to the home of the scrolling region.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuDecCUP(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int row, col;
|
|
|
|
row = hhEmu->num_param[0];
|
|
col = hhEmu->num_param_cnt > 0 ? hhEmu->num_param[1] : 0;
|
|
|
|
if (pstPRI->aiLineAttr[row_index(hhEmu, row)] != NO_LINE_ATTR)
|
|
col = (col * 2) - 1;
|
|
|
|
if (row <= 1)
|
|
row = 1;
|
|
|
|
if (col <= 1)
|
|
col = 1;
|
|
|
|
if (hhEmu->mode_DECOM) /* VT100 Origin mode - position rel to margin */
|
|
{
|
|
row += hhEmu->top_margin;
|
|
if (row > hhEmu->bottom_margin + 1)
|
|
row = hhEmu->bottom_margin + 1;
|
|
}
|
|
else /* Position is one-based from upper left */
|
|
{
|
|
if (row > hhEmu->emu_maxrow + 1)
|
|
row = hhEmu->emu_maxrow + 1;
|
|
}
|
|
|
|
if (col > hhEmu->emu_maxcol + 1)
|
|
col = hhEmu->emu_maxcol + 1;
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, row - 1, col - 1); /* ANSI is one-based, HA zero-based */
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecCUB
|
|
*
|
|
* DESCRIPTION: Moves the cursor backwards (to the left) the specified number
|
|
* of characters, but stops at the 1st character in the current
|
|
* line. The vt emus need a special function to handle the
|
|
* virtual column beyond the edge of the screen.
|
|
*
|
|
* ARGUMENTS: none
|
|
*
|
|
* RETURNS: nothing
|
|
*/
|
|
void emuDecCUB(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int nchars;
|
|
|
|
nchars = hhEmu->num_param[hhEmu->num_param_cnt];
|
|
|
|
if (nchars < 1)
|
|
nchars = 1;
|
|
|
|
if (pstPRI->aiLineAttr[hhEmu->emu_imgrow])
|
|
nchars = (nchars * 2);
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu,
|
|
hhEmu->emu_currow,
|
|
hhEmu->emu_curcol - nchars);
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecED
|
|
*
|
|
* DESCRIPTION:
|
|
* Erases some or all of the virtual screen image and corresponding
|
|
* real screen.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuDecED(const HHEMU hhEmu)
|
|
{
|
|
int selector = hhEmu->selector[0];
|
|
|
|
switch (selector)
|
|
{
|
|
case 0: /* cursor to end of screen */
|
|
case 0x0F:
|
|
case 0xF0:
|
|
(*hhEmu->emu_clearscreen)(hhEmu, 0);
|
|
break;
|
|
|
|
case 1: /* start of screen to cursor */
|
|
case 0xF1:
|
|
(*hhEmu->emu_clearscreen)(hhEmu, 1);
|
|
break;
|
|
|
|
case 2: /* Entire screen */
|
|
case 0xF2:
|
|
(*hhEmu->emu_clearscreen)(hhEmu, 2);
|
|
break;
|
|
default:
|
|
commanderror(hhEmu);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecUnload
|
|
*
|
|
* DESCRIPTION:
|
|
* Unloads current emulator by freeing used memory.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuVT100Unload(const HHEMU hhEmu)
|
|
{
|
|
PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
assert(hhEmu);
|
|
|
|
if (pstPRI)
|
|
{
|
|
if (pstPRI->aiLineAttr)
|
|
{
|
|
free(pstPRI->aiLineAttr);
|
|
pstPRI->aiLineAttr = 0;
|
|
}
|
|
|
|
free(hhEmu->pvPrivate);
|
|
hhEmu->pvPrivate = 0;
|
|
}
|
|
|
|
//
|
|
// Make sure to free the key tables that were created when the emulator
|
|
// was loaded, otherwise there is a memory leak. REV: 05/09/2001
|
|
//
|
|
emuKeyTableFree(&hhEmu->stEmuKeyTbl);
|
|
emuKeyTableFree(&hhEmu->stEmuKeyTbl2);
|
|
emuKeyTableFree(&hhEmu->stEmuKeyTbl3);
|
|
emuKeyTableFree(&hhEmu->stEmuKeyTbl4);
|
|
|
|
return;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecIND
|
|
*
|
|
* DESCRIPTION:
|
|
* Moves cursor down 1 line and scrolls 1 line if necessary. IND stands
|
|
* for index.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuDecIND(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int fSourceIsDbl, fDestIsDbl;
|
|
int iCol;
|
|
|
|
// If we're at the bottom line, scroll.
|
|
//
|
|
if (hhEmu->emu_currow == hhEmu->bottom_margin)
|
|
{
|
|
(*hhEmu->emu_scroll)(hhEmu, 1, TRUE);
|
|
return;
|
|
}
|
|
|
|
fSourceIsDbl = (pstPRI->aiLineAttr[row_index(hhEmu, hhEmu->emu_currow)] == NO_LINE_ATTR)
|
|
? FALSE : TRUE;
|
|
fDestIsDbl = (pstPRI->aiLineAttr[row_index(hhEmu, hhEmu->emu_currow + 1)] == NO_LINE_ATTR)
|
|
? FALSE : TRUE;
|
|
|
|
iCol = hhEmu->emu_curcol;
|
|
|
|
// If both source and dest are the same, regardless of size, go
|
|
// ahead and make the move. It only matters if they're different.
|
|
//
|
|
if (fSourceIsDbl == fDestIsDbl) // Both the same
|
|
iCol = iCol;
|
|
else if (fSourceIsDbl) // Source is double, dest is single.
|
|
iCol = iCol / 2;
|
|
else // Source is singel, dest is double.
|
|
iCol = iCol * 2;
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow + 1, iCol);
|
|
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecRI
|
|
*
|
|
* DESCRIPTION:
|
|
* Moves cursor up 1 line and scrolls 1 line if necessary.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuDecRI(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int fSourceIsDbl, fDestIsDbl;
|
|
int iCol;
|
|
|
|
// If we're at the bottom line, scroll.
|
|
//
|
|
if (hhEmu->emu_currow == hhEmu->top_margin)
|
|
{
|
|
(*hhEmu->emu_scroll)(hhEmu, 1, FALSE);
|
|
return;
|
|
}
|
|
|
|
fSourceIsDbl = (pstPRI->aiLineAttr[row_index(hhEmu, hhEmu->emu_currow)] == NO_LINE_ATTR)
|
|
? FALSE : TRUE;
|
|
fDestIsDbl = (pstPRI->aiLineAttr[row_index(hhEmu, hhEmu->emu_currow - 1)] == NO_LINE_ATTR)
|
|
? FALSE : TRUE;
|
|
|
|
iCol = hhEmu->emu_curcol;
|
|
|
|
// If both source and dest are the same, regardless of size, go
|
|
// ahead and make the move. It only matters if they're different.
|
|
//
|
|
if (fSourceIsDbl == fDestIsDbl) // Both the same
|
|
iCol = iCol;
|
|
else if (fSourceIsDbl) // Source is double, dest is single.
|
|
iCol = iCol / 2;
|
|
else // Source is singel, dest is double.
|
|
iCol = iCol * 2;
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow - 1, iCol);
|
|
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecCUU
|
|
*
|
|
* DESCRIPTION: Moves the cursor up the specified number of lines, but stops
|
|
* at the top of the scrolling region. The column is constant.
|
|
* If above the scrolling region, it stops at the top of the
|
|
* screen.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuDecCUU(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int nlines,
|
|
row,
|
|
fSourceIsDbl,
|
|
fDestIsDbl,
|
|
iCol;
|
|
|
|
nlines = hhEmu->num_param[hhEmu->num_param_cnt];
|
|
|
|
if (nlines < 1)
|
|
nlines = 1;
|
|
|
|
row = hhEmu->emu_currow;
|
|
row -= nlines;
|
|
|
|
fSourceIsDbl = (pstPRI->aiLineAttr[row_index(hhEmu, hhEmu->emu_currow)] == NO_LINE_ATTR)
|
|
? FALSE : TRUE;
|
|
fDestIsDbl = (pstPRI->aiLineAttr[row_index(hhEmu, hhEmu->emu_currow - nlines)] == NO_LINE_ATTR)
|
|
? FALSE : TRUE;
|
|
|
|
iCol = hhEmu->emu_curcol;
|
|
|
|
// The following code adjusts the column value for double wide
|
|
// characters.
|
|
//
|
|
if (fSourceIsDbl == fDestIsDbl) // Both the same
|
|
iCol = iCol;
|
|
else if (fSourceIsDbl) // Source is double, dest is single.
|
|
iCol = iCol / 2;
|
|
else // Source is singel, dest is double.
|
|
iCol = iCol * 2;
|
|
|
|
if (row < hhEmu->top_margin && (hhEmu->emu_currow >= hhEmu->top_margin || hhEmu->emu_currow < 0))
|
|
row = hhEmu->top_margin;
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, row, iCol);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecCUD
|
|
*
|
|
* DESCRIPTION: Moves the cursor down the specified number of lines, but stops
|
|
* at the bottom of the scrolling region. The column is constant.
|
|
* If below the scrolling region, it stops at the bottom of the
|
|
* screen.
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuDecCUD(const HHEMU hhEmu)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int nlines,
|
|
row,
|
|
fSourceIsDbl,
|
|
fDestIsDbl,
|
|
iCol;
|
|
|
|
nlines = hhEmu->num_param[hhEmu->num_param_cnt];
|
|
|
|
if (nlines < 1)
|
|
nlines = 1;
|
|
|
|
row = hhEmu->emu_currow;
|
|
row += nlines;
|
|
|
|
fSourceIsDbl = (pstPRI->aiLineAttr[row_index(hhEmu, hhEmu->emu_currow)] == NO_LINE_ATTR)
|
|
? FALSE : TRUE;
|
|
fDestIsDbl = (pstPRI->aiLineAttr[row_index(hhEmu, hhEmu->emu_currow + nlines)] == NO_LINE_ATTR)
|
|
? FALSE : TRUE;
|
|
|
|
iCol = hhEmu->emu_curcol;
|
|
|
|
// The following code adjusts the column value for double wide
|
|
// characters.
|
|
//
|
|
if (fSourceIsDbl == fDestIsDbl) // Both the same
|
|
iCol = iCol;
|
|
else if (fSourceIsDbl) // Source is double, dest is single.
|
|
iCol = iCol / 2;
|
|
else // Source is singel, dest is double.
|
|
iCol = iCol * 2;
|
|
|
|
if (row > hhEmu->bottom_margin &&
|
|
(hhEmu->emu_currow <= hhEmu->bottom_margin || hhEmu->emu_currow > hhEmu->emu_maxrow))
|
|
row = hhEmu->bottom_margin;
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, row, iCol);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecSetCurPos
|
|
*
|
|
* DESCRIPTION:
|
|
* Moves the cursor to the specified position on the virtual screen.
|
|
* If the cursor is beyond the end of existing text, the virtual screen
|
|
* line is filled out with spaces. If the cursor is beyond the edges of
|
|
* the video display, the video cursor is placed as close as possible
|
|
* to the desired position as the cursor display is changed.
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuDecSetCurPos(const HHEMU hhEmu, const int iRow, const int iCol)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int iTempCol;
|
|
int i;
|
|
|
|
// If we move the cursor, we need to clear the pstPRI->fDecHoldFlag;
|
|
//
|
|
pstPRI->fDecColHold = FALSE;
|
|
|
|
hhEmu->emu_currow = max(min(iRow, hhEmu->emu_maxrow), 0);
|
|
hhEmu->emu_curcol = max(min(iCol, hhEmu->emu_maxcol), 0);
|
|
|
|
iTempCol = hhEmu->emu_curcol;
|
|
|
|
// If the row is a double wide character row, don't ever let the
|
|
// cursor land on an odd column number. If it's there now, back
|
|
// it up one.
|
|
//
|
|
i = row_index(hhEmu, hhEmu->emu_currow);
|
|
|
|
if (pstPRI->aiLineAttr[i])
|
|
{
|
|
if (iTempCol % 2 == 1)
|
|
{
|
|
iTempCol -= 1;
|
|
}
|
|
}
|
|
|
|
updateCursorPos(sessQueryUpdateHdl(hhEmu->hSession), iRow, iTempCol);
|
|
hhEmu->emu_imgrow = row_index(hhEmu, hhEmu->emu_currow);
|
|
return;
|
|
#if 0
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
|
|
int iTempCol;
|
|
|
|
hhEmu->emu_currow = max(min(iRow, hhEmu->emu_maxrow), 0);
|
|
hhEmu->emu_curcol = max(min(iCol, hhEmu->emu_maxcol), 0);
|
|
|
|
iTempCol = hhEmu->emu_curcol;
|
|
|
|
// Do range checking for DEC emulation. This prevents the cursor
|
|
// from being displayed in the 81st position, which is a valid
|
|
// internal location, but is not a valid display column.
|
|
//
|
|
if (hhEmu->emu_curcol == hhEmu->emu_maxcol &&
|
|
(hhEmu->stUserSettings.nEmuId == EMU_VT100 ||
|
|
hhEmu->stUserSettings.nEmuId == EMU_VT100J))
|
|
{
|
|
iTempCol -= 1;
|
|
}
|
|
|
|
// If the row is a double wide character row, don't ever let the
|
|
// cursor land on an odd column number. If it's there now, back
|
|
// it up one.
|
|
//
|
|
if (pstPRI->aiLineAttr[row_index(hhEmu, hhEmu->emu_currow)])
|
|
{
|
|
if (iTempCol % 2 == 1)
|
|
{
|
|
iTempCol -= 1;
|
|
}
|
|
}
|
|
|
|
updateCursorPos(sessQueryUpdateHdl(hhEmu->hSession), iRow, iTempCol);
|
|
|
|
hhEmu->emu_imgrow = row_index(hhEmu, hhEmu->emu_currow);
|
|
return;
|
|
#endif
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* emuDecClearScreen
|
|
*
|
|
* DESCRIPTION:
|
|
* Erases some or all of the virtual screen image.
|
|
*
|
|
* ARGUMENTS:
|
|
* select -- 0 to erase from cursor to end of screen
|
|
* -- 1 to erase from start of screen to cursor
|
|
* -- 2 to erase entire screen
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void emuDecClearScreen(const HHEMU hhEmu, const int nClearSelect)
|
|
{
|
|
const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
|
|
ECHAR aechBuf[10];
|
|
register int r;
|
|
int trow, tcol;
|
|
PSTATTR pstAttr;
|
|
BOOL fSave;
|
|
|
|
trow = hhEmu->emu_currow;
|
|
tcol = hhEmu->emu_curcol;
|
|
|
|
switch (nClearSelect)
|
|
{
|
|
/* cursor to end of screen */
|
|
case 0:
|
|
fSave = (hhEmu->emu_currow == 0 &&
|
|
hhEmu->emu_curcol == 0) ? TRUE : FALSE;
|
|
|
|
for (r = hhEmu->emu_currow + (fSave ? 0 : 1) ; r < MAX_EMUROWS; ++r)
|
|
{
|
|
if (fSave)
|
|
{
|
|
backscrlAdd(sessQueryBackscrlHdl(hhEmu->hSession),
|
|
hhEmu->emu_apText[row_index(hhEmu, r)],
|
|
hhEmu->emu_maxcol+1);
|
|
|
|
CaptureLine(sessQueryCaptureFileHdl(hhEmu->hSession),
|
|
CF_CAP_SCREENS,
|
|
hhEmu->emu_apText[row_index(hhEmu, r)],
|
|
emuRowLen(hhEmu, row_index(hhEmu, r)));
|
|
|
|
printEchoScreen(hhEmu->hPrintEcho,
|
|
hhEmu->emu_apText[row_index(hhEmu, r)],
|
|
emuRowLen(hhEmu, row_index(hhEmu, r)));
|
|
|
|
CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), TEXT("\r\n"),
|
|
StrCharGetByteCount(TEXT("\r\n")));
|
|
printEchoScreen(hhEmu->hPrintEcho,
|
|
aechBuf,
|
|
sizeof(ECHAR) * 2);
|
|
}
|
|
|
|
clear_imgrow(hhEmu, r);
|
|
|
|
pstPRI->aiLineAttr[row_index(hhEmu, r)] = NO_LINE_ATTR;
|
|
}
|
|
|
|
// Clear the partial row now.
|
|
//
|
|
ECHAR_Fill(hhEmu->emu_apText[row_index(hhEmu, hhEmu->emu_currow)] +
|
|
hhEmu->emu_curcol,
|
|
EMU_BLANK_CHAR,
|
|
(size_t)(MAX_EMUCOLS - hhEmu->emu_curcol + 1));
|
|
|
|
if (hhEmu->emu_curcol <= hhEmu->emu_aiEnd[hhEmu->emu_imgrow])
|
|
hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_curcol - 1;
|
|
|
|
pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, hhEmu->emu_currow)];
|
|
|
|
for (r = hhEmu->emu_curcol ; r < MAX_EMUCOLS ; ++r)
|
|
pstAttr[r] = hhEmu->emu_clearattr;
|
|
|
|
// Tell the video image what to do. Use the emuDispRgnScrollUp() call
|
|
// instead of RgnClear so edges of terminal get painted if
|
|
// clear attribute changes.
|
|
|
|
updateScroll(sessQueryUpdateHdl(hhEmu->hSession),
|
|
0,
|
|
hhEmu->emu_maxrow,
|
|
hhEmu->emu_maxrow + 1,
|
|
hhEmu->emu_imgtop,
|
|
TRUE);
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, hhEmu->emu_curcol);
|
|
|
|
// Added a global to save the clear attribute at the time of
|
|
// notification. This is necessary since the message is posted
|
|
// and a race condition can develop.
|
|
|
|
hhEmu->emu_clearattr_sav = hhEmu->emu_clearattr;
|
|
|
|
NotifyClient(hhEmu->hSession, EVENT_EMU_CLRATTR, 0);
|
|
break;
|
|
|
|
|
|
/* start of screen to cursor */
|
|
|
|
case 1:
|
|
for (r = 0; r < hhEmu->emu_currow; ++r)
|
|
{
|
|
clear_imgrow(hhEmu, r);
|
|
|
|
pstPRI->aiLineAttr[row_index(hhEmu, r)] = NO_LINE_ATTR;
|
|
}
|
|
|
|
ECHAR_Fill(hhEmu->emu_apText[row_index(hhEmu, hhEmu->emu_currow)],
|
|
EMU_BLANK_CHAR,
|
|
(size_t)(hhEmu->emu_curcol + 1));
|
|
|
|
if (hhEmu->emu_curcol >= hhEmu->emu_aiEnd[hhEmu->emu_imgrow])
|
|
hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = EMU_BLANK_LINE;
|
|
|
|
pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, hhEmu->emu_currow)];
|
|
|
|
for (r = 0 ; r <= hhEmu->emu_curcol ; ++r)
|
|
pstAttr[r] = hhEmu->emu_clearattr;
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, hhEmu->emu_curcol);
|
|
|
|
updateLine(sessQueryUpdateHdl(hhEmu->hSession), 0, hhEmu->emu_currow);
|
|
break;
|
|
|
|
/* Entire screen */
|
|
case 2:
|
|
for (r = 0; r < MAX_EMUROWS; ++r)
|
|
{
|
|
backscrlAdd(sessQueryBackscrlHdl(hhEmu->hSession),
|
|
hhEmu->emu_apText[row_index(hhEmu, r)],
|
|
hhEmu->emu_maxcol+1);
|
|
|
|
CaptureLine(sessQueryCaptureFileHdl(hhEmu->hSession),
|
|
CF_CAP_SCREENS,
|
|
hhEmu->emu_apText[row_index(hhEmu, r)],
|
|
emuRowLen(hhEmu, row_index(hhEmu, r)));
|
|
|
|
printEchoScreen(hhEmu->hPrintEcho,
|
|
hhEmu->emu_apText[row_index(hhEmu, r)],
|
|
emuRowLen(hhEmu, row_index(hhEmu, r)));
|
|
|
|
CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), TEXT("\r\n"),
|
|
StrCharGetByteCount(TEXT("\r\n")));
|
|
printEchoScreen(hhEmu->hPrintEcho,
|
|
aechBuf,
|
|
sizeof(ECHAR) * 2);
|
|
|
|
clear_imgrow(hhEmu, r);
|
|
|
|
pstPRI->aiLineAttr[r] = NO_LINE_ATTR;
|
|
}
|
|
|
|
updateScroll(sessQueryUpdateHdl(hhEmu->hSession),
|
|
0,
|
|
hhEmu->emu_maxrow,
|
|
hhEmu->emu_maxrow + 1,
|
|
hhEmu->emu_imgtop,
|
|
TRUE);
|
|
|
|
|
|
// Save the clear attribute at the time of
|
|
// notification. This is necessary since the message is posted
|
|
// and a race condition can develop.
|
|
|
|
hhEmu->emu_clearattr_sav = hhEmu->emu_clearattr;
|
|
|
|
NotifyClient(hhEmu->hSession, EVENT_EMU_CLRATTR, 0);
|
|
break;
|
|
|
|
default:
|
|
commanderror(hhEmu);
|
|
}
|
|
|
|
(*hhEmu->emu_setcurpos)(hhEmu, trow, tcol);
|
|
}
|
|
|
|
|
|
/* end of vt100.c */
|