📄 emul.c
字号:
case 2:
debug("mode:%s\n", set ? "ANSI" : "VT52");
break;
case 3:
debug("mode:column %d\n", set ? 132 : 80);
break;
case 4:
debug("mode:scrolling %s\n", set ? "smooth" : "jump");
break;
case 18:
debug("mode:print-ff %s\n", set ? "yes" : "no");
break;
case 19:
debug("mode:print-extent %s\n", set ? "fullscreen" : "region");
break;
default:
debug("mode:unknown? %d\n", term.params[0]);
break;
#endif
}
} else {
switch (term.params[0]) {
case 4:
term.insertMode = set;
break;
case 20:
term.newLineMode = set;
break;
#if 0
case 2:
debug("mode:keyboard %s\n", set ? "locked" : "unlocked");
break;
case 12:
debug("mode:send-receive %s\n", set ? "full" : "echo");
break;
default:
debug("mode:unknown %d\n", term.params[0]);
break;
#endif
}
}
}
/* Move the cursor up <param-0> lines. If param-0 was not supplied,
* move cursor up one line.
*/
static void emulCursorUp(void)
{
int numLines = 1; /* number of lines to move the cursor up */
if (term.numParams == 1)
numLines = term.params[0];
else if (term.numParams != 0)
return;
if (numLines == 0)
numLines = 1;
/* Do not more the cursor up past the first line
*/
term.cursor.y -= numLines;
checkCursorLimits();
}
/* Move the cursor down <param-0> lines. If param-0 was not supplied,
* move the cursor down one line.
*/
static void emulCursorDown(void)
{
int numLines = 1; /* number of line to move the cursor down */
if (term.numParams == 1)
numLines = term.params[0];
else if (term.numParams != 0)
return;
if (numLines == 0)
numLines = 1;
/* Do not move the cursor down past the last line
*/
term.cursor.y += numLines;
checkCursorLimits();
}
/* Move the cursor right <param-0> columns. If param-0 was not
* supplied, move the cursor right one column.
*/
static void emulCursorRight(void)
{
int numColumns = 1; /* number of columns to move right */
if (term.numParams == 1)
numColumns = term.params[0];
else if (term.numParams != 0)
return;
if (numColumns == 0)
numColumns = 1;
term.cursor.x += numColumns;
checkCursorLimits();
}
/* Move the cursor left <param-0> columns. If param-0 was not
* supplied, move the cursor left one column.
*/
static void emulCursorLeft(void)
{
int numColumns = 1; /* number of columns to move left */
if (term.numParams == 1)
numColumns = term.params[0];
else if (term.numParams != 0)
return;
if (numColumns == 0)
numColumns = 1;
term.cursor.x -= numColumns;
checkCursorLimits();
}
/* Clear part or all of current line depending on param-0;
* 0 - erase from cursor to end of line
* 1 - erase from start of line up to and including cursor
* 2 - erase entire line
* If param-0 is not supplied, assume value of 0
*/
static void emulClearEndOfLine(void)
{
if (term.numParams == 0)
term.params[term.numParams++] = 0;
if (term.numParams != 1)
return;
switch (term.params[0]) {
case 0:
/* Erase cursor to end of line
*/
linesClearRange(term.cursor.y, term.cursor.x,
term.cursor.y, term.winSize.cx);
winModifyRange(term.cursor.y, term.cursor.x,
term.cursor.y, term.winSize.cx);
break;
case 1:
/* Erase beginning of line through cursor
*/
linesClearRange(term.cursor.y, 0, term.cursor.y, term.cursor.x + 1);
winModifyRange(term.cursor.y, 0, term.cursor.y, term.cursor.x + 1);
break;
case 2:
/* Erase line
*/
linesClearRange(term.cursor.y, 0, term.cursor.y, term.winSize.cx);
winModifyRange(term.cursor.y, 0, term.cursor.y, term.winSize.cx);
}
}
/* Erase part or all of screen depending on param-0;
* 0 - erase from cursor to end of screen
* 1 - erase from start of screen up to and including cursor
* 2 - erase entire screen
* If param-0 not supplied, assume value of 0
*/
static void emulClearEndOfScreen(void)
{
if (term.numParams == 0)
term.params[term.numParams++] = 0;
if (term.numParams != 1)
return;
switch (term.params[0]) {
case 0:
/* Erase cursor to end of screen
*/
linesClearRange(term.cursor.y, term.cursor.x,
term.winSize.cy, term.winSize.cx);
winModifyRange(term.cursor.y, term.cursor.x,
term.winSize.cy, term.winSize.cx);
break;
case 1:
/* Beginning of screen through cursor
*/
linesClearRange(0, 0, term.cursor.y, term.cursor.x + 1);
winModifyRange(0, 0, term.cursor.y, term.cursor.x + 1);
break;
case 2:
/* Erase entire screen
*/
linesClearRange(0, 0, term.winSize.cy, term.winSize.cx);
winModifyRange(0, 0, term.winSize.cy, term.winSize.cx);
break;
}
}
/* Reset terminal to initial state
*/
void emulResetTerminal(void)
{
clearAttribs();
term.numParams = 1;
term.params[0] = 2;
emulClearEndOfScreen();
emulTabReset();
termSetCursorMode(1);
term.cursorVisible = TRUE;
term.inverseVideo = FALSE;
term.lineWrap = TRUE;
term.insertMode = FALSE;
term.ansiCursorKeys = FALSE;
term.autoRepeat = TRUE;
term.currAttr = term.blankAttr;
term.cursor.x = term.cursor.y = 0;
term.charSet = term.savedCharSet = 0;
term.G0CharSet = term.savedG0CharSet = usCharSet;
term.G1CharSet = term.savedG1CharSet = graphicsCharSet;
term.haveRegion = FALSE;
term.scrollTop = 0;
term.scrollBottom = term.winSize.cy;
emulCursorSave();
ctabIdent (graphicsCharSet);
ctabModif (graphicsCharSet, graphToOEM, NgraphToOEM, 0);
}
/* Control double width / double height
*
* Args:
* mode - desired double height/width mode
*/
static void emulSetDouble(char mode)
{
switch (mode) {
case '3': /* double-height top half */
case '4': /* double-height bottom half */
case '5': /* single-width single-height */
case '6': /* double-width single-height */
break;
case '8': /* fill screen with E */
linesAlignTest();
winModifyRange(0, 0, term.winSize.cy, term.winSize.cx);
break;
}
}
static struct {
char msg [128];
int len;
} AnswerBack = {
"dtelnet from Dave Cole",
22
};
void emulSetAnswerBack (int len, const char *from)
{
if (len > sizeof (AnswerBack.msg))
len = sizeof (AnswerBack.msg);
memcpy (AnswerBack.msg, from, len);
AnswerBack.len = len;
}
static void emulTransmitAnswerback (void)
{
if (AnswerBack.len) {
socketWrite (AnswerBack.msg, AnswerBack.len);
}
}
/* Switch to character set
*
* Args:
* charSet - the desired character set
*/
static void emulCharSet(int charSet)
{
term.charSet = charSet;
}
/* Not implemented
*/
static void emulHaltTransmit(void)
{
}
/* Not implemented
*/
static void emulResumeTransmit(void)
{
}
/* Not implemented
*/
static void emulAddCheckerboard(void)
{
}
/* Not implemented
*/
static void emulKeypadApplication(void)
{
}
/* Not implemented
*/
static void emulKeypadNumeric(void)
{
}
/* Window manipulation functions
*/
static void emulWinManip (void)
{
int cx, cy;
char buff [64];
if (term.numParams < 1) return;
switch (term.params[0]) {
case 8:
if (term.numParams != 3 ||
term.params[1]<5 || term.params[1]>200 ||
term.params[2]<20 || term.params[1]>200) return;
cx = term.params[2] * term.charSize.cx + GetSystemMetrics(SM_CXVSCROLL);
cy = term.params[1] * term.charSize.cy;
telnetTerminalSize (cx, cy);
break;
case 14:
sprintf (buff, "\x1b[4;%d;%dt",
term.winSize.cy*term.charSize.cy,
term.winSize.cx*term.charSize.cx);
emulFuncKeyPress (buff);
break;
case 18:
sprintf (buff, "\x1b[8;%d;%dt", term.winSize.cy, term.winSize.cx);
emulFuncKeyPress (buff);
break;
default:
break;
}
}
/* Starting or stopping print mode
*/
static void emulPrintControl(void)
{
if (term.numParams < 1) return;
if (!termAttachedPrinter()) return; /* only print when allowed */
switch (term.params[0]) {
case 4: /* printer off */
printingStop();
break;
case 5: /* printer on */
printingStart();
break;
}
}
/* Add character at current cursor position.
*
* Args:
* c - the character to add
*/
static void emulAddChar(unsigned char c, BOOL bKeyboard)
{
DtChar dCh;
if (printingIsActive()) {
printingAddChar(c);
return;
}
/* Check for line wrap before adding character.
*/
emulCheckWrap();
if (term.insertMode) {
/* When in insert mode, move rest of line right one column
*/
term.numParams = 0;
emulCharInsert();
}
/* Set character at current cursor position, update the terminal
* window, and then advance the cursor one column to the right.
*/
if (bKeyboard) { /* keyboard gives ANSI codes */
dCh.cType = DTCHAR_ANSI;
dCh.cCode = c;
} else {
if (term.charSet != 0 && currEmul.ctGraphConv [c] != 0) {
/* graphics mode AND graphical character */
dCh.cType = DTCHAR_OEM;
dCh.cCode = term.G1CharSet [c];
} else { /* non-graph character */
if (currEmul.fAnsi) {
dCh.cType = DTCHAR_ANSI;
dCh.cCode = currEmul.ctServerToAnsi [c];
} else {
dCh.cType = DTCHAR_OEM;
dCh.cCode = currEmul.ctServerToOem [c];
}
}
}
if ((unsigned char)dCh.cCode < 0x80) {
dCh.cType = DTCHAR_ASCII;
}
linesSetChar(&dCh);
winModifyRange(term.cursor.y, term.cursor.x,
term.cursor.y, term.cursor.x);
term.cursor.x++;
}
/* Process a stream of characters through the terminal emulator. This
* is the main terminal emulation entry point.
*
* Args:
* text - array of characters to process
* len - number of characters in the text array
*
* The emulator is implemented as a state machine which can handle
* breaks in character sequences at any point.
*/
void emulAddText(unsigned char* text, int len, BOOL bKeyboard)
{
/* Remember whether or not we hid the cursor during the terminal
* update.
*/
BOOL cursorHidden = term.cursorVisible;
ASSERT(text != NULL && len >= 0);
/* If Terminal/Bottom on Output is set, make the current terminal
* visible (instead of history) before performing output.
*/
if (termBottomOnOutput())
termScrollToBottom();
/* Log the text if necessary
*/
logSession((char *)text, len);
/* Hide the caret while performing updates to avoid windows
* leaving ghost carets all over the place (good one
* Microsoft).
*/
if (cursorHidden)
termHideCaret();
/* Process all of the text through the emulation
*/
for (; len > 0; --len, ++text) {
if (term.state == consGetTitle && !isprint(*text)) {
term.state = consNormal;
emulSetTitle();
continue;
}
/* Some characters are state independant - handle those first
*/
switch (*text) {
case 0: /* NUL */
continue;
case 5: /* ENQ */
emulTransmitAnswerback();
continue;
case 7: /* BEL */
MessageBeep(MB_ICONASTERISK);
continue;
case '\b': /* BS */
emulBackspace(FALSE);
continue;
case '\t': /* HT */
emulTab();
continue;
case '\n': /* LF */
case 11: /* VT */
if (printingIsActive()){
printingAddChar('\n');
}
else
emulLineFeed();
continue;
case 12: /* FF */
if (printingIsActive())
printingAddChar(12);
else
emulLineFeed();
continue;
case '\r': /* CR */
emulCarriageReturn();
continue;
case 14: /* SO */
emulCharSet(1);
continue;
case 15: /* SI */
emulCharSet(0);
continue;
case 17: /* DC1 */
emulResumeTransmit();
continue;
case 19: /* DC3 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -