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

📄 term.c

📁 dtelent是开源的开发项目
💻 C
📖 第 1 页 / 共 5 页
字号:
	     */
	    termTryScroll(-term.winSize.cy / 2);
	else
	    emulFuncKeyPress(emulGetTerm()->keyPageUp);
	break;
    case VK_NEXT:
	if (shiftPressed)
			/* Shift-PageDown acts like xterm - scroll forwards in
	     * history half a terminal height
	     */
	    termTryScroll(term.winSize.cy / 2);
	else
	    emulFuncKeyPress(emulGetTerm()->keyPageDown);
	break;
    case VK_UP:
	emulFuncKeyPress((term.ansiCursorKeys ? "\x1bOA" : "\x1b[A"));
	break;
    case VK_DOWN:
	emulFuncKeyPress((term.ansiCursorKeys ? "\x1bOB" : "\x1b[B"));
	break;
    case VK_RIGHT:
	emulFuncKeyPress2(EFK_LOCAL_RIGHT,
	    (term.ansiCursorKeys ? "\x1bOC" : "\x1b[C"));
	break;
    case VK_LEFT:
	emulFuncKeyPress2(EFK_LOCAL_LEFT,
	    (term.ansiCursorKeys ? "\x1bOD" : "\x1b[D"));
	break;
    case VK_HOME:
	emulFuncKeyPress2(EFK_LOCAL_HOME, emulGetTerm()->keyHome);
	break;
    case VK_END:
	emulFuncKeyPress2(EFK_LOCAL_END, emulGetTerm()->keyEnd);
	break;
    case VK_INSERT:
	if (shiftPressed)
	    /* Shift-Insert pastes the selection
			 */
	    termSelectPaste();
	else if (controlPressed)
	    /* Control-Insert copies the selection
	     */
	    termSelectCopy();
	else
	    emulFuncKeyPress2(EFK_LOCAL_INSERT, emulGetTerm()->keyInsert);
	break;
    case VK_DELETE:
	emulFuncKeyPress2(EFK_LOCAL_DELETE, emulGetTerm()->keyDelete);
	break;

    case VK_F1:
	termFuncKeyDown(shiftPressed, 1) ;
	break;

    case VK_F2:
        termFuncKeyDown(shiftPressed, 2) ;
	break;

    case VK_F3:
        termFuncKeyDown(shiftPressed, 3) ;
	break;

    case VK_F4:
        termFuncKeyDown(shiftPressed, 4) ;
	break;

    case VK_F5:
        termFuncKeyDown(shiftPressed, 5) ;
	break;

    case VK_F6:
        termFuncKeyDown(shiftPressed, 6) ;
	break;

    case VK_F7:
        termFuncKeyDown(shiftPressed, 7) ;
	break;

    case VK_F8:
        termFuncKeyDown(shiftPressed, 8) ;
	break;

    case VK_F9:
        termFuncKeyDown(shiftPressed, 9) ;
	break;

    case VK_F10:
        termFuncKeyDown(shiftPressed, 10) ;
	break;

    case VK_F11:
        termFuncKeyDown(shiftPressed, 11) ;
	break;

    case VK_F12:
        termFuncKeyDown(shiftPressed, 12) ;
	break;
   }
}

/* User pressed a function key (F1-F12)
 *
 * Args:
 * shiftPressed - is pressed the shift key ?
 * nFkey        - number of the function key
 */
void termFuncKeyDown(BOOL shiftPressed, int nFkey)
{
    Emul *emul;

    emul = emulGetTerm();
    if (shiftPressed) {
        nFkey += 10;          /* Dirty hard-code by Lorinczy Zsigmond */
    }
    if (nFkey <= emul->nMaxFkey) {
        emulFuncKeyPress(emul->keyF[nFkey-1]);
    }
}

/* User pressed a normal character key
 *
 * Args:
 * key -   key that was pressed
 * flags - key data from Windows message
 */
void termKeyPress(UINT key, DWORD flags)
{
    /* Get state of Shift and Control keys when message was sent
     */
    BOOL controlPressed = (GetKeyState(VK_CONTROL) & KF_UP) != 0;
    BOOL shiftPressed = (GetKeyState(VK_SHIFT) & KF_UP) != 0;
    BOOL isRepeat = (HIWORD(flags) & KF_REPEAT) != 0;

    if (!term.autoRepeat && isRepeat)
	return;

    if (key == '\t') {
	if (shiftPressed)
	    /* Cannot rely on Windows for Shift+Tab since it passes
	     * Shift+Tab as Tab.
	     */
	    emulFuncKeyPress(emulGetTerm()->keyBacktab);
	else
	    emulKeyPress('\t');
    } else if (controlPressed && key == ' ') {
	    /* Cannot rely on Windows for Ctrl+Key since it passes
	     * Ctrl-Space as Space.  Not good for Emacs, it expects
	     * nul.
	     */
	    emulKeyPress(0);
    } else if (key == '\b') {
	    if ((GetKeyState('H') & KF_UP) != 0)
		emulFuncKeyPress2(EFK_LOCAL_BACKSPACE, "\b");
	    else if (connectGetBs2DelOption())
		emulFuncKeyPress2(EFK_LOCAL_BACKSPACE,
				  emulGetTerm()->keyAltBackSpace);
	    else
		emulFuncKeyPress2(EFK_LOCAL_BACKSPACE,
				  emulGetTerm()->keyBackSpace);
     } else if (key == '\r') {
	    emulFuncKeyPress2 (EFK_LOCAL_SEND, "\r");
     } else if (key == '\n') {
	    emulFuncKeyPress2 (EFK_LOCAL_SKIP, "\n");
     } else {
	    emulKeyPress((char)key);
     }
}

/* User pressed a system key (Alt+Key)
 *
 * Args:
 * key -   the key pressed
 * flags - key data from Windows message
 */
void termSysKeyDown(UINT key, DWORD flags)
{
    BOOL isRepeat = (HIWORD(flags) & KF_REPEAT) != 0;
    int key1, key2;
    char str [16], *stp;

    if (!term.autoRepeat && isRepeat)
	return;

    if (key == VK_MENU || key == VK_SHIFT) {
	return; /* LZs, 2000.10.20 --- should be tested */
    }

    if (key == VK_F10) {
	/* When the user presses F10, Windows sends the event as a
	 * system key - I am glad that Windows makes this stuff *so*
	 * easy.
	 */
/*	emulFuncKeyPress((unsigned char *)emulGetTerm()->keyF10); */
	termKeyDown (key, flags);    /* Lorinczy Zsigmond, 2000.10.20 */
    } else {
	/* Windows has sent us a virtual key code - we have to
	 * translate that to an ASCII character.
	 *
	 * Check these functions out in the manual.  Ahhh... I love
	 * Windows.
	 */
	unsigned char state[256];
#ifdef WIN32
	WORD xlat[2];
#else
	DWORD xlat[2];
#endif
	int xlatResult;

	GetKeyboardState(state);
	state[VK_MENU] &= 0x7f;
	xlat[0] = xlat[1] = 0;
	xlatResult = ToAscii(key, (UINT)((flags >> 16) & 0xff), state, xlat, 0);

	if (xlatResult == 0) {     /* LZS 2000.06.20 --- I'm not sure ... */
	    emulKeyPress ('\x1b');
	    termKeyDown (key, flags);
	    return;
	}

        key1 = (BYTE)xlat[0];
        key2 = (BYTE)xlat[1];

	stp = str;
	if (xlatResult>=1 &&
            ((key1 >= ' ' && key1 <= '~') || key1 == 0x0d)) {
	    *stp++ = 0x1b;
	    *stp++ = (char)key1;
	}
	if (xlatResult>=2 && key1 != key2 &&
            ((key2 >= ' ' && key2 <= '~') || key2 == 0x0d)) {
	    *stp++ = 0x1b;
	    *stp++ = (char)key2;
	}
	if (stp != str) {
	    *stp = 0;
	    emulFuncKeyPress(str);
	}
    }
}

/* Process a file drag-dropped onto the terminal
 */
void termAcceptDrag(WPARAM wparam)
{
    static char droppedFileName[_MAX_PATH + 1];
    char fbuffer[4096];
    FILE* f;

    if (socketConnected())
    {
        /* To maintain predictability, we only handle 1 file at a time */
	if (DragQueryFile((HDROP) wparam, (UINT)-1, (LPSTR) NULL, 0)==1)
	{
	    DragQueryFile((HDROP) wparam, 0, droppedFileName, sizeof(droppedFileName));
            /* got filename, paste text from file's content */
            f = fopen(droppedFileName,"r");
            fgets (fbuffer, sizeof(fbuffer), f);
            while (!feof(f)){
                socketWrite(fbuffer, strlen(fbuffer));
                fgets (fbuffer, sizeof(fbuffer), f);
	    }
	    fclose(f);
	}
	else
	{
	    /* Warn user */
	    MessageBox(termGetWnd(), "Multiple drop unsupported", "DTelnet",
		MB_APPLMODAL | MB_ICONINFORMATION);
	}
    }
    else
    {
	/* Punish user */
	MessageBox(termGetWnd(), "Not connected to host", "DTelnet",
	   MB_APPLMODAL | MB_ICONHAND);
    }
    DragFinish((HDROP) wparam);
}

/* Hide the caret in the terminal window
 */
void termHideCaret(void)
{
    HideCaret(termWnd);
}

/* Show the caret in the terminal window
 */
void termShowCaret(void)
{
    ShowCaret(termWnd);
}

/* Set the caret visibility in the terminal window
 *
 * Args:
 * visible - should the caret be visible?
 */
void termSetCursorMode(BOOL visible)
{
    if (haveCaret && visible != term.cursorVisible) {
	/* We have the caret and the visibility status has changed
	 */
	if (visible)
	    ShowCaret(termWnd);
	else
	    HideCaret(termWnd);
    }
    term.cursorVisible = visible;
}

/* Application has just gained focus
 */
void termSetFocus(void)
{
    /* Rebuild our caret and restore its position
     */
    CreateCaret(termWnd, term.caretBitmap, term.cursorRect.right, term.cursorRect.bottom);
    SetCaretPos(
	term.cursor.x * term.charSize.cx + term.cursorRect.left, 
	winTerminalToWindow(term.cursor.y) * term.charSize.cy + term.cursorRect.top
    );

    /* Display the caret is necessary
     */
    if (term.cursorVisible)
	ShowCaret(termWnd);

    haveCaret = TRUE;
}

/* Application has just lost focus
 */
void termKillFocus(void)
{
		/* Destroy the caret
     */
    DestroyCaret();
    haveCaret = FALSE;
}

/* The application window has been resized - set the terminal window size
 *
 * Args:
 * cx - pixel width of the terminal window
 * cy - pixel height of the terminal window
 */
void termSetWindowSize(int cx, int cy)
{
    SIZE newSize;		/* new terminal size in characters */
    int growLines;		/* number of lines terminal grew */
    RECT rect;			/* build invalidate rect */

    /* Get the new terminal window dimensions in characters
     */
    newSize.cx = (cx - vscrollWidth) / term.charSize.cx;
    newSize.cy = cy / term.charSize.cy;
    if (newSize.cx == term.winSize.cx && newSize.cy == term.winSize.cy)
	/* No change in dimensions - nothing to do
	 */
	return;

    /* Calculate the number of lines that the window was grown.
     * Negative values mean that the window was shrunk
     */
    growLines = newSize.cy - term.winSize.cy;

		/* Resize the terminal window
     */
    MoveWindow(termWnd, 0, 0, cx, cy, TRUE);

    if (growLines > 0) {
	/* The window height has increased - we scroll the window to
	 * try to keep the last defined line at the bottom of the
	 * window.  If the line array index of the bottom of the
	 * window is larger than term.numLinesUsed, then we must
	 * scroll down, limited by term.topVisibleLine.
	 */
	int numLines = 0;	/* number of lines to scroll down */

	if (winTerminalTopLine() + newSize.cy > term.numLinesUsed) {
	    /* The bottom of the window has grown down past the last
	     * defined line.  We must scroll lines down if possible.
	     */
	    numLines = newSize.cy - (term.numLinesUsed - winTerminalTopLine());
	    if (numLines > term.topVisibleLine)
		/* We cannot scroll down more lines than exist
		 */
		numLines = term.topVisibleLine;
	}
	if (numLines > 0) {
	    /* Scroll lines down
	     */
	    winUpdate();
	    ScrollWindow(termWnd, 0, numLines * term.charSize.cy, NULL, NULL);
	    term.topVisibleLine -= numLines;
	    term.cursor.y += numLines;
	}

	/* Invalidate the extra lines at the bottom of the window
	 */
	rect.left = 0;
	rect.right = newSize.cx * term.charSize.cx;
	rect.top = term.winSize.cy * term.charSize.cy;
	rect.bottom = newSize.cy * term.charSize.cy;
	InvalidateRect(termWnd, &rect, FALSE);
    } else if (growLines < 0) {
	int numLines = 0;	/* number of lines to scroll up */

	/* The window height has decreased - scroll the window to try
	 * to keep the last line at the bottom of the window.  If we
	 * could not previously see the last line - do not bother
	 * scrolling.
	 */
	if (term.numLinesUsed <= winTerminalTopLine() + term.winSize.cy
	    && term.numLinesUsed > newSize.cy) {
	    /* Last line was visible - and we need to scroll.  Keep
	     * the last line at the bottom of the window.
	     */
	    int newTopLine = term.numLinesUsed - newSize.cy;
	    if (newTopLine != term.topVisibleLine)
		numLines = newTopLine - term.topVisibleLine;
	}
	if (numLines > 0) {
	    /* Scroll lines up
	     */
	    winUpdate();
	    /* For some bizarre reason, we have to make sure that the cursor
	     * does not get scrolled off the window - it does not redisplay
	     * when we move it back on.
	     */
			if (numLines > term.cursor.y) {
		term.cursor.y = numLines;
		winCaretPos(term.cursor.x, term.cursor.y);
	    }
	    ScrollWindow(termWnd, 0, -numLines * term.charSize.cy, NULL, NULL);
	    term.topVisibleLine += numLines;
	    term.cursor.y -= numLines;
	}
    }

    if (newSize.cx > term.winSize.cx) {
	/* Invalidate the extra columns at the right edge of the window
	 */
	rect.left = term.winSize.cx * term.charSize.cx;
	rect.right = newSize.cx * term.charSize.cx;
	rect.top = 0;
	rect.bottom = newSize.cy * term.charSize.cy;
	InvalidateRect(termWnd, &rect, FALSE);
    }

    /* Now store the new terminal window size
     */
    term.winSize.cx = newSize.cx;
    term.winSize.cy = newSize.cy;

    termCheckSizeLimits();	// Khader

    /* Make sure the terminal scroll region makes sense
     */
    if (term.haveRegion) {
	if (term.winSize.cy < term.scrollBottom)
	    term.scrollBottom = term.winSize.cy;
	if (term.scrollBottom <= term.scrollTop)
	    term.haveRegion = FALSE;
		}
    if (!term.haveRegion) {
	term.scrollTop = 0;
	term.scrollBottom = term.winSize.cy;
    }

    /* Tell the telnet server about the new size
     */
    if (term.winSize.cx > 0 && term.winSize.cy > 0)
	rawSetWindowSize(/* term.winSize.cx, term.winSize.cy */);

    /* Adjust the history scrollbar
     */
    winSetScrollbar();
}

/* Windows is going to change application window size.  Modify the
 * proposed size to enforce a character grid
 *
 * Args:
 * winSize - the proposed size of the terminal window
 */
void termWindowPosChanging(SIZE* winSize)
{
    /* Enforce grid of 1 character cell
     */
    winSize->cx -= vsc

⌨️ 快捷键说明

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