Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1245 lines
28 KiB

/* File: D:\WACKER7\emu\emu.c (Created: 08-Dec-1993)
*
* Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
* All rights reserved
*
* $Revision: 11 $
* $Date: 7/08/02 6:32p $
*/
#include <windows.h>
#pragma hdrstop
#include <tdll\stdtyp.h>
#include <tdll\tdll.h>
#include <tdll\assert.h>
#include <tdll\mc.h>
#include <tdll\com.h>
#include <tdll\cloop.h>
#include <tdll\capture.h>
#include <tdll\session.h>
#include <tdll\load_res.h>
#include <tdll\globals.h>
#include <tdll\print.h>
#include <tdll\statusbr.h>
#include <tdll\htchar.h>
#include <search.h>
#include <tdll\update.h>
#include <term\res.h>
#include "emu.h"
#include "emu.hh"
#include "emuid.h"
#if defined(INCL_VTUTF8)
extern BOOL DoUTF8;
#endif
static int FFstrlen(const BYTE *);
int _cdecl KeyCmp(const void *, const void *);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* char_pn
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
void char_pn(const HHEMU hhEmu) /* interpret a character as a numeric param */
{
if (hhEmu->emu_code < ETEXT(' '))
hhEmu->emu_code = ETEXT(' ');
hhEmu->selector[hhEmu->selector_cnt] =
hhEmu->num_param[hhEmu->num_param_cnt] = hhEmu->emu_code - ETEXT(' ') + 1;
hhEmu->num_param[++hhEmu->num_param_cnt] = 0;
hhEmu->selector[++hhEmu->selector_cnt] = 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* commanderror
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
void commanderror(const HHEMU hhEmu)
{
hhEmu->state = 0;
ANSI_Pn_Clr(hhEmu);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* emuAutoDetectLoad
*
* DESCRIPTION:
* if auto dection is on, loads the given emulator ID and sets auto
* detection off.
*
* ARGUMENTS:
* hhEmu - private emulator handle
* EmuID - id of emulator to load
*
* RETURNS:
* void
*
*/
void emuAutoDetectLoad(const HHEMU hhEmu, const int nEmuID)
{
if (hhEmu->stUserSettings.nEmuId != EMU_AUTO)
return;
if (hhEmu->stUserSettings.nEmuId != nEmuID)
{
emuLock((HEMU)hhEmu);
hhEmu->stUserSettings.nAutoAttempts = 0;
#ifdef INCL_USER_DEFINED_BACKSPACE_AND_TELNET_TERMINAL_ID
// Load the default telnet terminal id for this emulator. - cab:11/18/96
//
emuQueryDefaultTelnetId(nEmuID, hhEmu->stUserSettings.acTelnetId,
EMU_MAX_TELNETID);
#endif
emuUnlock((HEMU)hhEmu);
emuLoad((HEMU)hhEmu, nEmuID);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* emuStdGraphic
*
* 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 emuStdGraphic(const HHEMU hhEmu)
{
ECHAR ccode;
ECHAR echBuf[10];
int iCharsToMove;
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];
ccode = hhEmu->emu_code;
// Is the emulator in insert mode?
//
if (hhEmu->mode_IRM == SET)
{
iCharsToMove = hhEmu->emu_aiEnd[hhEmu->emu_imgrow] - iCol;
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) &&
ccode < sizeof(hhEmu->dspchar))
ccode = hhEmu->dspchar[ccode];
tp[iCol] = ccode;
ap[iCol] = hhEmu->emu_charattr;
#if !defined(CHAR_NARROW)
if ((hhEmu->stUserSettings.nEmuId == EMU_AUTO) ||
(hhEmu->stUserSettings.nEmuId == EMU_ANSIW))
{
// Process Double Byte Characters
//
if (QueryCLoopMBCSState(sessQueryCLoopHdl(hhEmu->hSession)))
{
if (isDBCSChar(ccode))
{
int iColPrev = iCol;
ap[iCol].wilf = 1;
ap[iCol].wirt = 0;
// 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,
iCol,
hhEmu->mode_IRM ?
hhEmu->emu_maxcol :
hhEmu->emu_aiEnd[hhEmu->emu_imgrow]);
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));
}
//move end of row since we removed a character
hhEmu->emu_aiEnd[hhEmu->emu_imgrow] -= 1;
//update the image
updateChar(sessQueryUpdateHdl(hhEmu->hSession),
hhEmu->emu_imgrow,
hhEmu->emu_aiEnd[hhEmu->emu_imgrow] + 1,
hhEmu->mode_IRM ?
hhEmu->emu_maxcol :
hhEmu->emu_aiEnd[hhEmu->emu_imgrow] + 1);
}
}
#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,
iCol,
hhEmu->mode_IRM ?
hhEmu->emu_maxcol :
hhEmu->emu_aiEnd[hhEmu->emu_imgrow]);
// Move the position of the cursor ahead of the last character
// displayed, checking for end of line wrap.
//
iCol++;
if (iCol > hhEmu->emu_maxcol)
{
if (hhEmu->mode_AWM)
{
// This code was added, but not enabled because we did not
// want to introduce this without proper testing. If line
// wrap on capture to printer not working is reported as a
// bug, enable this code.
#if 0
printEchoChar(hhEmu->hPrintEcho, ETEXT('\r'));
printEchoChar(hhEmu->hPrintEcho, ETEXT('\n'));
#endif
printEchoString(hhEmu->hPrintEcho, tp, emuRowLen(hhEmu, iRow));
CnvrtMBCStoECHAR(echBuf, sizeof(echBuf), TEXT("\r\n"),
StrCharGetByteCount(TEXT("\r\n")));
printEchoString(hhEmu->hPrintEcho,
echBuf,
sizeof(ECHAR) * 2);
CaptureLine(sessQueryCaptureFileHdl(hhEmu->hSession),
CF_CAP_LINES,
tp,
emuRowLen(hhEmu, iRow));
if (iRow == hhEmu->bottom_margin)
(*hhEmu->emu_scroll)(hhEmu, 1, TRUE);
else
iRow += 1;
iCol = 0;
}
else
{
iCol = hhEmu->emu_maxcol;
}
}
// Finally, set the cursor position. This wil reset emu_currow
// and emu_curcol.
//
(*hhEmu->emu_setcurpos)(hhEmu, iRow, iCol);
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
* emu_cleartabs
*
* DESCRIPTION:
* Clears one or all tab stops.
*
* ARGUMENTS:
* selector -- 0 clears tab at current cursor position
* -- 3 clears all tabs in current line
*
* RETURNS:
* nothing
*/
void emu_cleartabs(const HHEMU hhEmu, int selecter)
{
int col;
switch (selecter)
{
case 0:
hhEmu->tab_stop[hhEmu->emu_curcol] = FALSE;
break;
case 3:
for (col = 0; col <= hhEmu->emu_maxcol; ++col)
hhEmu->tab_stop[col] = FALSE;
break;
default:
commanderror(hhEmu);
break;
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
* emuSendKeyString
*
* DESCRIPTION:
* Sends the specified string.
*
* ARGUMENTS:
* hhEmu - The internal emulator handle.
* nIndex - Position of key in keytable array.
* pstKeyTbl - Address of key strings table.
*
* RETURNS:
* nothing
*/
void emuSendKeyString(const HHEMU hhEmu,
const nIndex,
const PSTKEYTABLE pstKeyTbl)
{
ECHAR str[80];
PSTKEY pstKey;
TCHAR *pszTemp;
memset(str, ETEXT('\0'), sizeof(str));
assert(nIndex >= 0 && nIndex < pstKeyTbl->iMaxKeys);
pstKey = pstKeyTbl->pstKeys + nIndex;
pszTemp = pstKey->fPointer ? pstKey->u.pachKeyStr : pstKey->u.achKeyStr;
CnvrtMBCStoECHAR(str, sizeof(str), pszTemp,
StrCharGetByteCount(pszTemp));
emuSendString(hhEmu, str, pstKey->uLen);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
* emuSendString
*
* DESCRIPTION:
* Sends the specified string.
*
* ARGUMENTS:
* str -- address of string
* strlen -- length of string
*
* RETURNS:
* nothing
*/
void emuSendString(const HHEMU hhEmu, ECHAR *str, int nLen)
{
TCHAR *pchMBCS = NULL;
TCHAR *pchTemp = NULL;
unsigned long ulSize = 0;
unsigned int i = 0;
unsigned long ulDestSize = nLen + 1;
// This probably allocates way to many bytes, but if the incomming
// string is all MBC's we are safe.
pchMBCS = malloc((unsigned long)ulDestSize * sizeof(TCHAR));
if (pchMBCS == NULL)
{
assert(FALSE);
return;
}
TCHAR_Fill(pchMBCS, TEXT('\0'), nLen + 1);
#if defined(INCL_VTUTF8)
if (!DoUTF8)
{
ulSize = (unsigned long)CnvrtECHARtoMBCS(pchMBCS, (unsigned long)ulDestSize * sizeof(TCHAR),
str, (unsigned long)nLen * sizeof(ECHAR));
}
else
{
while (nLen > (int)ulSize)
{
pchMBCS[ulSize++] = (str[ulSize] & 0x00FF);
}
}
#else
ulSize = (unsigned long)CnvrtECHARtoMBCS(pchMBCS, (unsigned long)ulDestSize * sizeof(TCHAR),
str, (unsigned long)nLen * sizeof(ECHAR));
#endif
//
// Make sure the string is NULL terminated. REV: 07/23/2001
//
pchMBCS[ulDestSize - 1] = TEXT('\0');
pchTemp = pchMBCS;
ulSize = StrCharGetStrLength(pchTemp);
#if 0 //DEADWOOD:jkh, 12/12/1996
// Some systems mistake something like ESC 0 D if the codes
// are sent in separate packets. This now sends such sequences
// in a single socket write which should usually put them in
// the same packet (though it doesn't guarantee to do so.
// Loop through the # of bytes in the string
for (i = 0 ; i < ulSize ; ++i)
CLoopCharOut(sessQueryCLoopHdl(hhEmu->hSession), *pchTemp++);
#endif
CLoopBufrOut(sessQueryCLoopHdl(hhEmu->hSession), pchTemp, ulSize);
free(pchMBCS);
pchMBCS = NULL;
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
* emu_reverse_image
*
* DESCRIPTION:
* Reverses the foreground and background colors for the entire virtual
* image.
*
* ARGUMENTS:
* none
*
* RETURNS:
* nothing
*/
void emu_reverse_image(const HHEMU hhEmu)
{
int nRow, nCol;
STATTR stOldAttr;
PSTATTR pstAttr;
// Set reverse screen mode for both clear and character attributes.
//
hhEmu->attrState[CSCLEAR_STATE].revvid =
!hhEmu->attrState[CSCLEAR_STATE].revvid;
hhEmu->emu_clearattr_sav =
hhEmu->emu_clearattr = hhEmu->attrState[CSCLEAR_STATE];
hhEmu->attrState[CS_STATE].revvid =
!hhEmu->attrState[CS_STATE].revvid;
hhEmu->emu_charattr = hhEmu->attrState[CS_STATE];
for (nRow = 0; nRow < (hhEmu->emu_maxrow+1); nRow++)
{
pstAttr = hhEmu->emu_apAttr[nRow];
for (nCol = 0 ; nCol <= hhEmu->emu_maxcol ; ++nCol, ++pstAttr)
{
stOldAttr = *pstAttr;
pstAttr->txtclr = stOldAttr.bkclr;
pstAttr->bkclr = stOldAttr.txtclr;
}
}
updateLine(sessQueryUpdateHdl(hhEmu->hSession), 0, hhEmu->emu_maxrow);
NotifyClient(hhEmu->hSession, EVENT_EMU_CLRATTR, 0);
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
* emu_is25lines
*
* DESCRIPTION:
* Tells the calling function if the emulator is using the 25th line.
*
* ARGUMENTS:
* none
*
* RETURNS:
* TRUE if the emulator is using the 25th line
*/
int emu_is25lines(const HHEMU hhEmu)
{
return (hhEmu->mode_25enab ? TRUE : FALSE);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
* emu_kbdlocked
*
* DESCRIPTION:
* Replacement kbdin that ignores all keys passed to it.
*
* ARGUMENTS:
* key -- key to process
*
* RETURNS:
* nothing
*/
/* ARGSUSED */
int emu_kbdlocked(const HHEMU hhEmu, int key, const int fTest)
{
return -1;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* nothing
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
/* ARGSUSED */
void nothing(const HHEMU hhEmu)
{
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* emuKbdKeyLookup
*
* DESCRIPTION:
* Main keyboard translation routine for all emulators. Note, this
* routine will not lookup keys unless the iUseTermKeys flag is set.
*
* ARGUMENTS:
* UINT key - lower byte is char or virtual key, upper byte has flags
*
* RETURNS:
* Index if translated, else minus one.
*
*/
int emuKbdKeyLookup(const HHEMU hhEmu,
const int uKey,
const PSTKEYTABLE pstKeyTbl)
{
PSTKEY pstKey;
if (hhEmu->stUserSettings.nTermKeys == EMU_KEYS_ACCEL)
return -1;
pstKey = bsearch(&uKey,
pstKeyTbl->pstKeys,
(unsigned)pstKeyTbl->iMaxKeys,
sizeof(KEY), KeyCmp);
if (pstKey)
return (int)(pstKey - pstKeyTbl->pstKeys);
return -1;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* emuKeyTableLoad
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
/* ARGSUSED */
int emuKeyTableLoad(const HHEMU hhEmu,
const KEYTBLSTORAGE pstKeySource[],
const int nNumKeys,
PSTKEYTABLE const pstKeyTbl)
{
int l;
int nLoop = 0;
PSTKEY pstKeys;
if (nNumKeys == 0)
return FALSE;
emuKeyTableFree(pstKeyTbl); // free previous instance
if ((pstKeyTbl->pstKeys = malloc((unsigned)(nNumKeys * (int)sizeof(KEY))))
== 0)
{
assert(0);
return FALSE;
}
memset(pstKeyTbl->pstKeys, 0, (unsigned)(nNumKeys * (int)sizeof(KEY)));
if (pstKeyTbl->pstKeys)
{
for (pstKeys = pstKeyTbl->pstKeys; nLoop < nNumKeys ; pstKeys++, nLoop++)
{
pstKeys->key = pstKeySource[nLoop].KeyCode;
l = FFstrlen(pstKeySource[nLoop].achKeyStr);
if ( l <= (int)sizeof(LPTSTR) )
{
pstKeys->fPointer = FALSE;
// Because of the goofy resource compiler, it was
// necessary to define a "\xff" in the resource data,
// when what we really wanted was a "\x00\xff". So,
// now we determine when this case occurs, and load the
// \x00 value manually. Note that there is an additional
// test for this below when determining the length of the
// the data.
//
if (l != 0)
{
MemCopy(pstKeys->u.achKeyStr, pstKeySource[nLoop].achKeyStr, (unsigned)l);
}
else
{
pstKeys->u.achKeyStr[0] = '\x00';
}
}
else
{
pstKeys->fPointer = TRUE;
pstKeys->u.pachKeyStr = malloc((unsigned)(l+1));
if (!pstKeys->u.pachKeyStr)
{
emuKeyTableFree(pstKeyTbl);
break;
}
MemCopy(pstKeys->u.pachKeyStr, pstKeySource[nLoop].achKeyStr, (unsigned)l);
}
// Here's the special case test, again.
//
if (l !=0 )
pstKeys->uLen = (int)l;
else
pstKeys->uLen = 1;
pstKeyTbl->iMaxKeys += 1;
}
}
if (pstKeyTbl->iMaxKeys)
{
qsort(pstKeyTbl->pstKeys,
(unsigned)pstKeyTbl->iMaxKeys,
sizeof(KEY),
KeyCmp);
}
return (int)pstKeyTbl->iMaxKeys;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* emuKeyTableFree
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
void emuKeyTableFree(PSTKEYTABLE const pstKeyTbl)
{
int i;
for (i = 0 ; i < pstKeyTbl->iMaxKeys ; i++)
{
if (pstKeyTbl->pstKeys[i].fPointer)
{
free(pstKeyTbl->pstKeys[i].u.pachKeyStr);
pstKeyTbl->pstKeys[i].u.pachKeyStr = NULL;
}
}
pstKeyTbl->iMaxKeys = 0;
if (pstKeyTbl->pstKeys)
{
free(pstKeyTbl->pstKeys);
pstKeyTbl->pstKeys = (KEY *)0;
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* FFstrlen
*
* DESCRIPTION:
* Local version of strlen that uses '\ff' as a string terminator
*
* ARGUMENTS:
* CHAR FAR *s - '\ff' terminated string.
*
* RETURNS:
* length
*
*/
static int FFstrlen(const BYTE *s)
{
int i = 0;
while (*s++ != 0xFF)
i += 1;
return i;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* KeyCmp
*
* DESCRIPTION: Compare function for qsort.
*
* ARGUMENTS:
*
* RETURNS:
*
*/
int _cdecl KeyCmp(PSTKEY pstKey1, PSTKEY pstKey2)
{
if (pstKey1->key > pstKey2->key)
return 1;
if (pstKey1->key < pstKey2->key)
return -1;
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* emuInstallStateTable
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
void emuInstallStateTable(const HHEMU hhEmu, struct trans_entry const *e, int size)
{
struct state_entry *state_pntr = 0;
int nStateCnt = 0;
int nTransCnt = 0;
while (size--)
{
if (e->next_state == NEW_STATE) /* start a new state */
{
assert(nStateCnt < MAX_STATE);
hhEmu->state_tbl[nStateCnt].first_trans = &hhEmu->trans_tbl[nTransCnt];
state_pntr = &hhEmu->state_tbl[nStateCnt++];
state_pntr->number_trans = 0;
}
else /* add a transition */
{
assert(nTransCnt < MAX_TRANSITION);
assert(state_pntr);
if (state_pntr)
{
++state_pntr->number_trans;
}
hhEmu->trans_tbl[nTransCnt++] = *e;
}
++e;
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* emuCreateTextAttrBufs
*
* DESCRIPTION:
* This one took a while to decipher but here is the bottom line.
* emu_maxrow and emu_maxcol refer to the last row and column from
* offset 0 (ZERO)! The emulator image has 2 (two) more columns for the
* the stuff unknown to me at the present time. This function wants
* the total number of rows and columns, so emu_maxrow = 23 means the
* the argument nRows is 24.
*
* ARGUMENTS:
*
* RETURNS:
*
*/
int emuCreateTextAttrBufs(const HEMU hEmu, const size_t nRows, size_t nCols)
{
const HHEMU hhEmu = (HHEMU)hEmu;
register size_t i, ndx;
PSTATTR pstAttr;
if (hhEmu == NULL)
{
return FALSE;
}
if (hhEmu->emu_apText && hhEmu->emu_apAttr && hhEmu->emu_aiEnd)
return (TRUE);
else
emuDestroyTextAttrBufs(hEmu);
nCols += 2; // Emulators need two extra columns.
// Allocate the text buffer.
//
if ((hhEmu->emu_apText = (ECHAR **)calloc(nRows, sizeof(ECHAR *))) == 0)
{
assert(FALSE);
return FALSE;
}
for (i = 0 ; i < nRows ; ++i)
{
if ((hhEmu->emu_apText[i] = (ECHAR *)calloc(nCols, sizeof(ECHAR))) == 0)
{
assert(FALSE);
emuDestroyTextAttrBufs(hEmu);
return FALSE;
}
ECHAR_Fill(hhEmu->emu_apText[i], EMU_BLANK_CHAR, nCols);
}
// Allocate the array to hold the rightmost character column number
// for each row.
//
if ((hhEmu->emu_aiEnd = (int *)calloc(nRows, sizeof(int))) == 0)
{
assert(FALSE);
emuDestroyTextAttrBufs(hEmu);
return FALSE;
}
for (ndx = 0; ndx < nRows; ++ndx)
hhEmu->emu_aiEnd[ndx] = EMU_BLANK_LINE;
// Allocate the attribute buffer.
//
if ((hhEmu->emu_apAttr = (PSTATTR *)calloc(nRows, sizeof(LPTSTR))) == 0)
{
assert(FALSE);
emuDestroyTextAttrBufs(hEmu);
return FALSE;
}
for (i = 0 ; i < nRows ; ++i)
{
if ((hhEmu->emu_apAttr[i] = calloc(nCols, sizeof(STATTR))) == 0)
{
assert(FALSE);
emuDestroyTextAttrBufs(hEmu);
return FALSE;
}
for (ndx = 0, pstAttr = hhEmu->emu_apAttr[i] ; ndx < nCols ; ++ndx)
pstAttr[ndx] = hhEmu->emu_clearattr;
}
return TRUE;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* emuDestroyTextAttrBufs
*
* DESCRIPTION:
* Destroys any allocated buffers for text and attributes.
*
* ARGUMENTS:
* void
*
* RETURNS:
* void
*
*/
void emuDestroyTextAttrBufs(const HEMU hEmu)
{
const HHEMU hhEmu = (HHEMU)hEmu;
register int i;
if (hEmu == NULL || hhEmu == NULL)
{
return;
}
if (hhEmu->emu_apText)
{
//
// Fixed memory leak hhEmu->emu_maxrow != MAX_EMUROWS
// MAX_EMUROWS was what was allocated. REV: 12/20/2000
//
for (i = 0 ; i < MAX_EMUROWS ; ++i)
{
if (hhEmu->emu_apText[i])
{
free(hhEmu->emu_apText[i]);
hhEmu->emu_apText[i] = NULL;
}
if (hhEmu->emu_apAttr[i])
{
free(hhEmu->emu_apAttr[i]);
hhEmu->emu_apAttr[i] = NULL;
}
}
free(hhEmu->emu_apText);
hhEmu->emu_apText = 0;
free(hhEmu->emu_apAttr);
hhEmu->emu_apAttr = 0;
}
if (hhEmu->emu_aiEnd)
{
free(hhEmu->emu_aiEnd);
hhEmu->emu_aiEnd = 0;
}
if (hhEmu->emu_apAttr)
{
for (i = 0 ; i <= hhEmu->emu_maxrow ; ++i)
{
if (hhEmu->emu_apAttr[i])
{
free(hhEmu->emu_apAttr[i]);
hhEmu->emu_apAttr[i] = NULL;
}
}
free(hhEmu->emu_apAttr);
hhEmu->emu_apAttr = 0;
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* emuCreateNameTable
*
* DESCRIPTION:
* Loads the Emulator Names into a table
*
* ARGUMENTS:
* HHEMU hhEmu - Emulator Handle
*
* RETURNS:
* Success/Failure
*
*/
int emuCreateNameTable(const HHEMU hhEmu)
{
int iLen, idx, iRet;
TCHAR achText[256];
iRet = TRUE;
emuLock((HEMU)hhEmu);
if (hhEmu->pstNameTable)
{
free(hhEmu->pstNameTable);
hhEmu->pstNameTable = NULL;
}
if ((hhEmu->pstNameTable = malloc(sizeof(STEMUNAMETABLE) * NBR_EMULATORS)) == 0)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
// Load the emulator name table. It simply contains the name and id of
// all of the supported emulators.
//
// EMU_AUTO
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_AUTO, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx = 0;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_AUTO;
// EMU_ANSI
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_ANSI, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_ANSI;
// EMU_ANSIW
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_ANSIW, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_ANSIW;
// EMU_MIMI
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_MINI, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_MINI;
// EMU_VIEW
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_VIEW, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_VIEW;
// EMU_TTY
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_TTY, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_TTY;
// EMU_VT100
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_VT100, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_VT100;
// EMU_VT52
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_VT52, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_VT52;
// EMU_VT100J
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_VT100J, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_VT100J;
#if defined(INCL_VT220)
// EMU_VT220
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_VT220, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_VT220;
#endif
#if defined(INCL_VT320)
// EMU_VT320
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_VT320, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_VT320;
#endif
#if defined(INCL_VT100PLUS)
// EMU_VT100+
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_VT100PLUS, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN(hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_VTUTF8;
#endif
#if defined(INCL_VTUTF8)
// EMU_VTUTF8
//
iLen = LoadString(glblQueryDllHinst(), IDS_EMUNAME_VTUTF8, achText, sizeof(achText) / sizeof(TCHAR));
if (iLen >= EMU_MAX_NAMELEN)
{
assert(FALSE);
iRet = FALSE;
goto LoadExit;
}
idx++;
StrCharCopyN (hhEmu->pstNameTable[idx].acName, achText, EMU_MAX_NAMELEN);
hhEmu->pstNameTable[idx].nEmuId = EMU_VTUTF8;
#endif
LoadExit:
emuUnlock((HEMU)hhEmu);
return(iRet);
}
/* end of emu.c */