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

📄 emul.c

📁 dtelent是开源的开发项目
💻 C
📖 第 1 页 / 共 4 页
字号:
	ASSERT (line->len > 0);
	term.cursor.x = line->len - 1;

	--term.cursor.y;
        if (bKeyboard)
	    emulCharDeleteCore (1, bKeyboard);
    }
}

/* Send the current logical line to the remote end */
static void emulSendCurrentLine(void)
{
    int lineIdx;
    Line *line, *pline;
    int loop;
    char LineBuff [sizeof (line->text)];
static const char sCRLF [2] = "\r\n";
    int nChar, cs;
    const unsigned char *ctmap;

    lineIdx = linesTerminalToLine(term.cursor.y);
    linesCreateTo(lineIdx);
    line = linesGetLine(lineIdx);

    if (currEmul.fAnsi) {
	cs = DTCHAR_ANSI;
	ctmap = currEmul.ctAnsiToServer;
    } else {
	cs = DTCHAR_OEM;
	ctmap = currEmul.ctOemToServer;
    }

    while (lineIdx > 0 &&
	   (pline = linesGetLine(lineIdx-1))->wrapped) {
	--lineIdx;
	--term.cursor.y;
	line = pline;
    }
    for (loop = 1; loop;) {
	if (line->len) {/* do not send empty line */
	    memcpy (LineBuff, line->text, line->len);
	    nChar = 0;
	    termGetChars (LineBuff, line->text, line->len, &nChar, &cs);
	    ctabTranslay (ctmap, LineBuff, line->len);
	    socketWrite (LineBuff, line->len);
	}
	if (! line->wrapped) loop = 0;
	else {
	    ++lineIdx;
	    line = linesGetLine(lineIdx);
	    ++term.cursor.y;
	}
    }
    socketWrite (sCRLF, sizeof (sCRLF));
    logSession (sCRLF, sizeof (sCRLF));
    ++term.cursor.y;
    term.cursor.x = 0;
    emulCursorCheck ();
}

/* Save the current cursor position and character attributes
 */
static void emulCursorSave(void)
{
    term.savedCursor = term.cursor;
    term.savedAttr = term.currAttr;
    term.savedCharSet = term.charSet;
    term.savedG0CharSet = term.G0CharSet;
    term.savedG1CharSet = term.G1CharSet;
    term.savedInverseVideo = term.inverseVideo;
}

/* Restore the previously save cursor position and character attributes
 */
static void emulCursorRestore(void)
{
    term.cursor = term.savedCursor;
    term.currAttr = term.savedAttr;
    term.charSet = term.savedCharSet;
    term.G0CharSet = term.savedG0CharSet;
    term.G1CharSet = term.savedG1CharSet;
    term.inverseVideo = term.savedInverseVideo;
}

/* Perform a reverse line feed.  Scroll the terminal down if necessary.
 */
static void emulReverseLineFeed(void)
{
    term.cursor.y--;
    emulCursorCheck();
}

/* Make sure that the cursor location is within the specifed bounds
 */
static void checkCursorLimits(void)
{
    if (term.cursorRelative && term.haveRegion) {
	if (term.cursor.y < term.scrollTop)
	    term.cursor.y = term.scrollTop;
	if (term.cursor.y >= term.scrollBottom)
	    term.cursor.y = term.scrollBottom - 1;
    } else {
	if (term.cursor.y < 0)
	    term.cursor.y = 0;
	if (term.cursor.y >= term.winSize.cy)
	    term.cursor.y = term.winSize.cy - 1;
    }
    if (term.cursor.x < 0)
	term.cursor.x = 0;
    if (term.cursor.x >= term.winSize.cx)
	term.cursor.x = term.winSize.cx - 1;
}

/* Move the cursor to the position y = <param-0>, x = <param-1>.  The
 * top-left position is 1,1 on the terminal, but 0,0 in all variables.
 * If a parameter was missing, a value of 0 is assumed.
 */
static void emulCursorAddress(void)
{
    if (term.numParams == 2) {
	if (term.params[0] > 0)
	    term.params[0]--;
	if (term.params[1] > 0)
	    term.params[1]--;
    } else if (term.numParams == 0)
	term.params[0] = term.params[1] = 0;
    else
	return;

    if (term.cursorRelative && term.haveRegion)
	term.params[0] += term.scrollTop;

    term.cursor.y = term.params[0];
    term.cursor.x = term.params[1];
    checkCursorLimits();
}

/* Define a scroll region; top = <param-0> to bottom = <param-1>.  If
 * top and bottom are 0, cancel any previously defined scroll
 * region.
 */
static void emulScrollRegion(void)
{
    if (term.numParams != 0 && term.numParams != 2)
	return;
    if (term.numParams == 0)
	term.params[0] = term.params[1] = 0;

    if (term.params[0] == 0 && term.params[1] == 0
	|| term.params[0] == 1 && term.params[1] == term.winSize.cy) {
	/* Cancel scroll region
	 */
	term.scrollTop = 0;
	term.scrollBottom = term.winSize.cy;
	term.haveRegion = FALSE;
	return;
    }

    /* Make sure top line is at least 1, and bottom is greater than
     * top and on the screen.
     */
    if (term.params[0] == 0)
	term.params[0] = 1;
    if (term.params[0] >= term.params[1] || term.params[1] > term.winSize.cy)
	return;

    /* Define the new scroll region
     */
    term.scrollTop = term.params[0] - 1;
    term.scrollBottom = term.params[1];
    term.haveRegion = TRUE;

    checkCursorLimits();
}

/* Move the cursor to the column defined in <param-0>
 */
static void emulColumnAddress(void)
{
    if (term.numParams == 1)
	term.cursor.x = term.params[0] == 0 ? 0 : term.params[0] - 1;
    checkCursorLimits();
}

/* Move the cursor to the row defined in <param-0>
 */
static void emulRowAddress(void)
{
    if (term.numParams == 0)
	term.params[0] = 0;
    else if (term.numParams != 1)
	return;
    if (term.params[0] > 0)
	term.params[0]--;

    if (term.cursorRelative && term.haveRegion)
	term.params[0] += term.scrollTop;
    term.cursor.y = term.params[0];

    checkCursorLimits();
}

/* Insert <param-0> lines at the cursor location.  If param-0 was not
 * supplied, insert one line.
 */
static void emulLineInsert(void)
{
    int numLines;		/* number of lines to insert */

    if (term.numParams == 0)
	numLines = 1;
    else if (term.numParams == 1)
	numLines = term.params[0];
    else
	return;

    /* There is no point inserting more lines than are on the terminal
     */
    if (term.cursor.y + numLines >= term.scrollBottom)
	numLines = term.scrollBottom - term.cursor.y;

    /* Insert blank lines into line array and terminal window
     */
    linesInsert(term.cursor.y, term.scrollBottom, numLines);
    winLinesInsert(term.cursor.y, term.scrollBottom, numLines);
}

/* Delete <param-0> lines at the cursor position.  If param-0 was not
 * specified, delete one line.
 */
static void emulLineDelete(void)
{
    int numLines;		/* number of lines to delete */

    if (term.numParams == 0)
	numLines = 1;
    else if (term.numParams == 1)
	numLines = term.params[0];
    else
	return;

    /* No point deleting more lines than are on the terminal
     */
    if (term.cursor.y + numLines >= term.scrollBottom)
	numLines = term.scrollBottom - term.cursor.y;

    /* Delete lines from the line array and terminal window
     */
    linesDelete(term.cursor.y, term.scrollBottom, numLines);
    winLinesDelete(term.cursor.y, term.scrollBottom, numLines);
}

/* Insert <param-0> blank characters at the cursor position.  If
 * param-0 was not supplied, insert one character.
 */
static void emulCharInsert(void)
{
    int numChars;		/* number of characters to insert */

    if (term.numParams == 0)
	numChars = 1;
    else if (term.numParams == 1)
	numChars = term.params[0];
    else
	return;

    /* Insert characters into line array and terminal window
     */
    linesCharsInsert(term.cursor.y, term.cursor.x, numChars);
    winCharsInsert(term.cursor.y, term.cursor.x);
}

/* Delete n characters at the cursor position.
 * If 'bKeyboard' then handle wrapped lines
 */
static void emulCharDeleteCore (int numChars, BOOL bKeyboard)
{
    int lineIdx, nlIdx;
    Line *line, *nl;
    int y, x, yorig, xorig;
    int nDelChar, nLineRest, nCpyChar;

    y = term.cursor.y;
    x = term.cursor.x;
    yorig = y;
    xorig = x;

    lineIdx = linesTerminalToLine(term.cursor.y);

    linesCreateTo(lineIdx);
    line = linesGetLine(lineIdx);

    if (line->len <= x) return;
    nDelChar = numChars;

	nLineRest = line->len - x;
	nDelChar = (nDelChar<=nLineRest) ? numChars : nLineRest;
	nCpyChar = nLineRest - nDelChar;

	if (nCpyChar > 0) {
	    memmove(line->text + x, line->text + x + numChars, nCpyChar * sizeof (line->text[0]));
	    memmove(line->attr + x, line->attr + x + numChars, nCpyChar);
	}
	line->len -= nDelChar;

    if (bKeyboard) { /* 20060426: only if local */
    	while (line->wrapped) {
	    nlIdx = lineIdx + 1;
	    linesCreateTo (nlIdx);
	    nl = linesGetLine (nlIdx);

	    nDelChar = (nDelChar <= nl->len) ? nDelChar : nl->len;
	    nCpyChar = nl->len - nDelChar;

	    if (nDelChar>0) {
	        memmove (line->text + line->len, nl->text, nDelChar * sizeof (line->text[0]));
	        memmove (line->attr + line->len, nl->attr, nDelChar);
	        line->len += nDelChar;
	        nl->len -= nDelChar;
	        if (nl->len==0 && !nl->wrapped) {
		    line->wrapped = 0;
	        }
		memmove (nl->text, nl->text + nDelChar, nCpyChar * sizeof (line->text[0]));
		memmove (nl->attr, nl->attr + nDelChar, nCpyChar);
	    }

	    y = y+1;
	    x = 0;
	    lineIdx = nlIdx;
	    line = nl;
	}
    }

    if (y != yorig) {
	winModifyRange (yorig, 0, y, term.winSize.cx);
    } else {
	winModifyRange (yorig, xorig, y, term.winSize.cx);
    }
}

/* Delete <param-0> characters at the cursor position.  If param-0 was
 * not supplied, delete one character.
 */
static void emulCharDelete(BOOL bKeyboard)
{
    int numChars;		/* number of characters to delete */

    if (term.numParams == 0)
	numChars = 1;
    else if (term.numParams != 1)
	return;
    else
	numChars = term.params[0];

    emulCharDeleteCore (numChars, bKeyboard);
}

/* Blank <param-0> characters from the current cursor position.  If
 * param-0 was not supplied, blank one character.
 */
static void emulCharBlank(void)
{
    int numChars;		/* number of characters to blank */

    if (term.numParams == 0)
	numChars = 1;
    else if (term.numParams == 1)
	numChars = term.params[0];
    else
	return;

    /* Blank characters from the line array and terminal window
     */
    linesClearRange(term.cursor.y, term.cursor.x,
		    term.cursor.y, term.cursor.x + numChars);
    winModifyRange(term.cursor.y, term.cursor.x,
		   term.cursor.y, term.cursor.x + numChars);
}

/* Set various terminal attributes
 */
static void emulParamInterpret(void)
{
    int idx;

    if (term.numParams == 0) term.params[term.numParams++] = 0;

    for (idx = 0; idx < term.numParams; ++idx) {
	switch (term.params[idx]) {
	    case 0: clearAttribs(); break;
	    case 1: setBold(); break;
	    case 4: DEBUG("underline ON\n"); break;
	    case 5: DEBUG("blink ON\n"); break;
	    case 7: setInverse(TRUE); break;
	    case 8: DEBUG("concealed\n"); break;
	    case 10: emulCharSet(0); break;
	    case 11: emulCharSet(1); break;
	    case 22: DEBUG("alt intensity OFF\n"); break;
	    case 24: DEBUG("underline OFF\n"); break;
	    case 25: DEBUG("blink OFF\n"); break;
	    case 27: setInverse(FALSE); break;
	    case 30: setForeground(Black); break;
	    case 31: setForeground(Red); break;
	    case 32: setForeground(Green); break;
	    case 33: setForeground(Yellow); break;
	    case 34: setForeground(Blue); break;
	    case 35: setForeground(Magenta); break;
	    case 36: setForeground(Cyan); break;
	    case 37: setForeground(White); break;
	    case 39:
		DEBUG("underline OFF\n");
                setForeground(FG(term.blankAttr));
		break;
	    case 40: setBackground(Black); break;
	    case 41: setBackground(Red); break;
	    case 42: setBackground(Green); break;
	    case 43: setBackground(Yellow); break;
	    case 44: setBackground(Blue); break;
	    case 45: setBackground(Magenta); break;
	    case 46: setBackground(Cyan); break;
	    case 47: setBackground(White); break;
	    case 49: setBackground(BG(term.blankAttr)); break;
	}
    }
}

/* Report cursor address
 */
static void emulCursorReport(void)
{
    char buff[32];

    if (term.numParams == 0)
	term.params[term.numParams++] = 0;

    switch (term.params[0]) {
    case 5:
	emulFuncKeyPress("\x1b[0n");
	break;
    case 6:
	if (term.cursorRelative && term.haveRegion)
	    sprintf(buff, "\x1b[%d;%dR",
		    term.cursor.y - term.scrollTop + 1, term.cursor.x + 1);
	else
	    sprintf(buff, "\x1b[%d;%dR", term.cursor.y + 1, term.cursor.x + 1);
	emulFuncKeyPress(buff);
	break;
    }
}

/* Report terminal status
 */
static void emulStatusReport(void)
{
    if (term.numParams == 0)
	term.params[term.numParams++] = 0;

    if (term.params[0] == 0)
	emulFuncKeyPress("\x1b[?1;0c");
}

/* Set various terminal modes
 */
static void emulSetMode(BOOL set)
{
    if (term.numParams != 1)
	return;

    if (term.seenQuestion) {
	switch (term.params[0]) {
	case 1:
	    term.ansiCursorKeys = set;
	    break;
	case 5:
	    /* Switch to/from inverse video
	     */
	    if (term.inverseVideo == set)
		break;
	    linesInvertAll();
	    winModifyRange(0, 0, term.winSize.cy, term.winSize.cx);
	    setInverse(set);
	    break;
	case 6:
	    term.cursorRelative = set;
	    break;
	case 7:
			term.lineWrap = set;
			break;
	case 8:
			term.autoRepeat = set;
			break;
	case 25:
			termSetCursorMode(set);
			break;
	case 9:
			/* X10 compatible mouse reporting, maybe later */
			break;
	case 1000:
			/* X11 compatible mouse reporting */
			if (emulGetTerm()->flags & ETF_MOUSE_EVENT)
			{
				term.mouseReporting = set;
			}
			break;
	case 1001:
			/* X11 compatible mouse tracking, not yet implemented */
			break;

#if 0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -