⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emul.c

📁 dtelent是开源的开发项目
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 + -