📄 emul.c
字号:
emulHaltTransmit();
continue;
case 24: /* CAN */
case 26: /* SUB */
term.state = consNormal;
emulAddCheckerboard();
continue;
case 27: /* ESC */
term.state = consEscape;
continue;
case 127: /* DEL */
continue;
}
if (*text < ' ')
continue;
if (term.state == consNormal) {
}
switch (term.state) {
case consNormal:
if (*text == 0x90) { /* DCS */
term.state = consDCS;
emulParamInit ();
continue;
} else {
emulAddChar(*text, bKeyboard);
}
continue;
case consDCS:
if (*text == '1') term.stateSParam = 1; /* hexadecimal value */
else if (! isdigit (*text)) goto case_consDCS1;
term.state = consDCS1;
continue;
case consDCS1:
case_consDCS1:
term.dcschar = *text;
term.state = consDCS2;
continue;
case consDCS2:
if (*text==0x9C) { /* ST */
if (term.dcschar == 'v') { /* answerback message */
emulSetAnswerBack (term.numSParam, term.sparam);
}
term.state = consNormal;
} else {
emulSParamAdd (*text);
}
continue;
case consEscape: /* \E */
term.state = consNormal;
switch (*text) {
case 'N':
emulCharSet(1);
continue;
case 'O':
emulCharSet(0);
continue;
case 'D':
emulLineFeed();
continue;
case 'E':
emulCarriageReturn();
emulLineFeed();
continue;
case 'M':
emulReverseLineFeed();
continue;
case '7':
emulCursorSave();
continue;
case '8':
emulCursorRestore();
continue;
case 'H':
emulTabSet();
continue;
case 'c':
emulResetTerminal();
continue;
case '[':
emulParamInit();
term.state = consOpenSquare;
continue;
case ']':
emulParamInit();
term.state = consCloseSquare;
continue;
case '=':
emulKeypadApplication();
continue;
case '>':
emulKeypadNumeric();
continue;
case '#':
term.state = consHash;
continue;
case '(':
term.state = consOpenParen;
continue;
case ')':
term.state = consCloseParen;
continue;
}
continue;
case consCloseSquare:
if (*text >= '0' && *text <= '9') {
emulParamAdd(*text - '0');
continue;
}
term.state = consGetTitle;
continue;
case consGetTitle:
emulAddTitle(*text);
continue;
case consOpenSquare: /* \E[ */
if (*text == '?') {
term.seenQuestion = TRUE;
term.state = consGetParams;
continue;
}
term.state = consGetParams;
/*| fall-through |*/
case consGetParams: /* \E[ */
if (*text == ';') {
emulParamNext();
continue;
}
if (*text >= '0' && *text <= '9') {
emulParamAdd(*text - '0');
continue;
}
term.state = consHaveParams;
/*| fall-through |*/
case consHaveParams: /* \E[ */
term.state = consNormal;
/* Handle all of the commands that can have '?' first
*/
switch (*text) {
case 'h':
emulSetMode(TRUE);
continue;
case 'l':
emulSetMode(FALSE);
continue;
}
if (term.seenQuestion) {
term.seenQuestion = FALSE;
continue;
}
/* None of these can have '?'
*/
switch (*text) {
case 'A':
emulCursorUp();
continue;
case 'B':
emulCursorDown();
continue;
case 'C':
emulCursorRight();
continue;
case 'D':
emulCursorLeft();
continue;
case 'E':
emulCursorDown();
term.cursor.x = 0;
case 'F':
emulCursorUp();
term.cursor.x = 0;
continue;
case 'H': case 'f':
emulCursorAddress();
continue;
case 'G':
emulColumnAddress();
continue;
case 'd':
emulRowAddress();
continue;
case 'K':
emulClearEndOfLine();
continue;
case 'I':
emulTabForward();
continue;
case 'Z':
emulTabBackward();
continue;
case 'J':
emulClearEndOfScreen();
continue;
case 'X':
emulCharBlank();
continue;
case 'L':
emulLineInsert();
continue;
case 'M':
emulLineDelete();
continue;
case 'P':
emulCharDelete(bKeyboard);
continue;
case 'r':
emulScrollRegion();
continue;
case '@':
emulCharInsert();
continue;
case 'm':
emulParamInterpret();
continue;
case 'n':
emulCursorReport();
continue;
case 'c':
emulStatusReport();
continue;
case 'g':
emulTabClear();
continue;
case 's':
emulCursorSave();
continue;
case 'u':
emulCursorRestore();
continue;
case 'i':
emulPrintControl();
continue;
case 't':
emulWinManip ();
}
continue;
case consHash:
/* Double height/width commands
*/
term.state = consNormal;
emulSetDouble(*text);
continue;
case consOpenParen:
/* Change G0 character set
*/
term.state = consNormal;
switch (currEmul.flags & ETF_ESC_PARO) {
case ETF_ESC_PARO_LINUX:
switch (*text) {
case 'A': term.G0CharSet = ukCharSet; break;
case 'B': term.G0CharSet = usCharSet; break;
case '0': term.G0CharSet = graphicsCharSet; break;
case '1': term.G0CharSet = altCharSet; break;
case '2': term.G0CharSet = altGraphicsCharSet; break;
}
break;
case ETF_ESC_PARO_VT320:
switch (*text) {
case '0': emulCharSet(1); break; /* smacs */
case 'B': emulCharSet(0); break; /* rmacs */
}
break;
}
continue;
case consCloseParen:
/* Change G1 character set
*/
term.state = consNormal;
switch (*text) {
case 'A': term.G1CharSet = ukCharSet; break;
case 'B': term.G1CharSet = usCharSet; break;
case '0': term.G1CharSet = graphicsCharSet; break;
case '1': term.G1CharSet = altCharSet; break;
case '2': term.G1CharSet = altGraphicsCharSet; break;
}
continue;
}
}
/* Force Windows to update the terminal window
*/
winUpdate();
/* Move the caret to the new location and redisplay it.
*/
winCaretPos(term.cursor.x, term.cursor.y);
if (cursorHidden)
termShowCaret();
/* Update the history scrollbar
*/
winSetScrollbar();
}
/* Handle a normal key press
*/
void emulKeyPress(char ch)
{
if (!socketConnected() || term.echoKeystrokes) {
/* When in local echo mode, or not connected, echo the character
*/
emulAddText((unsigned char*)(&ch), 1, TRUE);
return;
}
/* if (!socketConnected())
return; */
/* Do local flow control first - this needs special handling
*/
if (ch == CTRL('S')) {
/* Stop character flow.
*/
if (rawGetProtocol() != protoNone && socketLocalFlowControl())
/* We are doing either telnet or login protocol, and we
* have negotiated local flow control. Handle the flow
* control by not reading any more data from the
* socket.
*/
socketSetFlowStop(TRUE);
else
/* Flow control is handled by the remote end. Send the ^S.
*/
socketWrite(&ch, 1);
return;
} else if (ch == CTRL('Q')) {
/* Resume character flow.
*/
if (rawGetProtocol() != protoNone && socketLocalFlowControl())
/* We are doing either telnet or login protocol, and we
* have negotiated local flow control. Tell the socket
* module to resume reading data.
*/
socketSetFlowStop(FALSE);
else
/* Flow control handled by the remote end. Send the ^Q.
*/
socketWrite(&ch, 1);
return;
}
/* Now handle normal characters.
*/
if (socketFlowStopped()
&& rawGetProtocol() != protoNone
&& socketLocalFlowControl()
&& term.flowStartAny)
/* Flow is stopped and we have negotiated flow restart on any
* keystroke. Use the keystroke to restart flow.
*/
socketSetFlowStop(FALSE);
else {
/* Send the character to the remote end.
*/
if (ch == '\r') {
/* Carriage return gets special treatment.
*/
switch (rawGetProtocol()) {
case protoTelnet:
/* Telnet protocol says that Carriage Return must
* always be followed by a nul character.
** I think not --- RFC says: send \r\n _or_ \r\0
** LZS 2000.11.06
*/
/*LZS*** if (term.newLineMode) */
socketWrite("\r\n", 2);
/*LZS*** else
socketWrite("\r", 2);*/
break;
case protoRlogin:
/* For login protocol, send only the Carriage Return
*/
if (term.newLineMode)
socketWrite("\r\n", 2);
else
socketWrite("\r", 1);
break;
case protoNone:
/* For all other protocols, send Carriage Return
* followed by Line Feed. This satisfies things like
* SMTP, NNTP, HTML, FTP, ...
*/
socketWrite("\r\n", 2);
break;
}
} else {
/* Normal character - just send it
*/
ch = currEmul.ctAnsiToServer [(unsigned char)ch];
socketWrite(&ch, 1);
}
}
}
/* Handle a function key press
*/
void emulFuncKeyPress(char* str)
{
emulFuncKeyPress2(EFK_LOCAL_SAME, str);
}
/* Handle a function key press local/remote
*/
void emulFuncKeyPress2(int localaction, char *str)
{
int len;
if (str == NULL)
return;
len = strlen(str);
if (len == 0)
return;
if (term.echoKeystrokes || !socketConnected()) {
/* When in local echo mode, or not connected, echo the key sequence
*/
switch (localaction) {
case EFK_LOCAL_SKIP:
break;
case EFK_LOCAL_SAME:
emulAddText((unsigned char*)str, len, TRUE);
break;
case EFK_LOCAL_BACKSPACE:
emulBackspace(TRUE);
winCaretPos(term.cursor.x, term.cursor.y);
if (term.cursorVisible)
termShowCaret();
break;
case EFK_LOCAL_DELETE:
emulCharDeleteCore(1, TRUE);
break;
case EFK_LOCAL_INSERT:
term.insertMode = ! term.insertMode;
break;
case EFK_LOCAL_LEFT:
case EFK_LOCAL_RIGHT:
case EFK_LOCAL_HOME:
case EFK_LOCAL_END:
editMoveCursor(localaction);
winCaretPos(term.cursor.x, term.cursor.y);
if (term.cursorVisible)
termShowCaret();
break;
case EFK_LOCAL_SEND:
if (socketConnected()) {
emulSendCurrentLine();
} else {
emulCarriageReturn ();
emulLineFeed ();
}
winCaretPos(term.cursor.x, term.cursor.y);
if (term.cursorVisible)
termShowCaret();
break;
default:
break;
}
winUpdate();
}
if (socketConnected() && !term.echoKeystrokes) {
/* When connected and not local echo mode send to remote end */
if (socketFlowStopped()
&& rawGetProtocol() != protoNone
&& socketLocalFlowControl()
&& term.flowStartAny)
/* Flow is stopped and we have negotiated flow restart on any
* keystroke. Use the keystroke to restart flow.
*/
socketSetFlowStop(FALSE);
else
/* Send the function key sequence to the remote end
*/
socketWrite(str, len);
}
}
/* Set terminal local echo mode on or off
*/
void emulSetEcho(BOOL echo)
{
term.echoKeystrokes = echo;
}
/* Set terminal local flow control "resume with any character" on or off
*/
void emulLocalFlowAny(BOOL any)
{
term.flowStartAny = any;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -