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

📄 term.c

📁 dtelent是开源的开发项目
💻 C
📖 第 1 页 / 共 5 页
字号:
     */
    termSelectWordExtend(&xpos, &ypos, inNextChar);
    if (xpos == term.selectTo.x && ypos == term.selectTo.y)
	/* No change in selection, nothing else to do
	 */
	return;

    if (term.haveSelection)
	/* Redraw the part of the selection that changed
	 */
	selectInvalidate(term.selectTo.y, term.selectTo.x, ypos, xpos);

    /* Record the new selection
     */
    term.haveSelection = TRUE;
    term.selectTo.x = xpos;
    term.selectTo.y = ypos;
}

/* Return whether or not there is a selection defined
 */
static BOOL termSelectCheck(void)
{
    term.haveSelection = term.selectFrom.x != term.selectTo.x
	|| term.selectFrom.y != term.selectTo.y;
    return term.haveSelection;
}

/* Convert terminal window pixel positions to terminal character
 * positions.  Return if the mouse was actually over the next
 * character cell.
 *
 * Args:
 * xpos - point to x-position (pixels) in terminal window
 * ypos - point to y-position (pixels) in terminal window
 */
static BOOL termSelectAdjustPos(int* xpos, int* ypos)
{
    BOOL inNextChar = (*xpos % term.charSize.cx) != 0;

    /* Convert x-pos from pixels to characters
     */
    *xpos /= term.charSize.cx;
		if (*xpos < 0)
	*xpos = 0;
    else if (*xpos > term.winSize.cx)
	*xpos = term.winSize.cx;

    /* Convert y-pos from pixels to characters
     */
    *ypos /= term.charSize.cy;
    if (*ypos < 0)
	*ypos = 0;
    else if (*ypos > term.winSize.cy)
	*ypos = term.winSize.cy;

    return inNextChar;
}

/* Start a timer to automatically extend the selection when the mouse
 * is above or below the terminal window
 */
static void termSelectStartTimer(void)
{
    if (termTimerId == 0)
	termTimerId = SetTimer(termWnd, ID_TERM_TIMER, 50, NULL);
}

/* Stop the timer that is used to extend the selection
 */
static void termSelectStopTimer(void)
{
    if (termTimerId == 0)
	return;
    KillTimer(termWnd, ID_TERM_TIMER);
		termTimerId = 0;
}

/* Return whether or not the user is currently performing a selection
 */
BOOL termSelectInProgress(void)
{
    return GetCapture() == termWnd;
}

/* Return whether or not there currently is a selection
 */
BOOL termHaveSelection(void)
{
    return term.haveSelection;
}

/***********************
 * TERMINAL MANAGEMENT *
 ***********************/

/* Return handle of the terminal window
 */
HWND termGetWnd(void)
{
    return termWnd;
}

/* Build a caret.  This should really be quite easy (according to the
 * Microsoft documentation), but for some reason Windows 3.1 gives the
 * caret a random color when we use our own palette.
 *
 * After days of pulling what little hair I have left out of my head,
 * I arrived at this wonderfully elegant, and intuitively obvious
 * code.  Read it and weep.
 *
 * I would comment the code, but I do not have the stomach for it.
 */
static void termMakeCaretBitmap(void)
{
    HDC dc;
    HDC memDc;
    HBRUSH brush;
    HBRUSH oldBrush;
    HBITMAP oldBitmap;
    HPALETTE oldPalette;

    if (term.caretBitmap != NULL)
	DeleteObject(term.caretBitmap);

    switch (cursorStyle)
    {
    case cursorBlock:
        SetRect(&term.cursorRect, 0, 0, term.charSize.cx, term.charSize.cy);
        break;
    case cursorVertLine:
        SetRect(&term.cursorRect, 0, 0, 2, term.charSize.cy);
        break;
    case cursorUnderLine:
        SetRect(&term.cursorRect, 0, term.charSize.cy-2, term.charSize.cx, 2);
	break;
    }
    dc = GetDC(termWnd);
    term.caretBitmap
	= CreateCompatibleBitmap(dc, term.cursorRect.right, term.cursorRect.bottom);

    memDc = CreateCompatibleDC(dc);
    oldBitmap = (HBITMAP)SelectObject(memDc, term.caretBitmap);
    if (termHasPalette) {
	oldPalette = SelectPalette(memDc, termPalette, 0);
	RealizePalette(memDc);
	brush = CreateSolidBrush(PALETTEINDEX(BOLD+White));
    } else
	brush = CreateSolidBrush(colors[BOLD+White]);
    oldBrush = (HBRUSH)SelectObject(memDc, brush);

    PatBlt(memDc, 0, 0, term.cursorRect.right, term.cursorRect.bottom, PATCOPY);

    SelectObject(memDc, oldBrush);
    DeleteObject(brush);
    if (termHasPalette)
	SelectObject(memDc, oldPalette);
    SelectObject(memDc, oldBitmap);
    DeleteDC(memDc);

    ReleaseDC(termWnd, dc);
}

/* Set the font used to draw the terminal.  Propagate the window
 * resize up to the application window.
 */
void termSetFont(void)
{
    TEXTMETRIC tm;		/* get metrics of new terminal font */

    /* Create the font that is used in the terminal window
     */
    if (term.font != 0)
	DeleteObject(term.font);
    fontCreate (termWnd, &tm, &term.font, &term.oemfont);
    term.fontCharSet = tm.tmCharSet;
    term.charSize.cy = tm.tmHeight;
    term.charSize.cx = tm.tmAveCharWidth;

    /* Build a new caret with the new character size
     */
    termMakeCaretBitmap();

		/* Tell our parent window how big we want to be
     */
    telnetTerminalSize(term.winSize.cx * term.charSize.cx + vscrollWidth,
		       term.winSize.cy * term.charSize.cy);

    /* Now make ourselves the requested size.  It seems that if we do
     * not say fRepaint = TRUE the scrollbar is not redrawn???!?!
     *
     * I LOVE WINDOWS
     */
    MoveWindow(termWnd, 0, 0,
	       term.winSize.cx * term.charSize.cx + vscrollWidth,
	       term.winSize.cy * term.charSize.cy, TRUE);

    /* Make sure the entire client area is redrawn with the new font
     */
    InvalidateRect(termWnd, NULL, FALSE);
}

static BOOL extractGeometry(char* str, SIZE* size, SIZE* pos)
{
    int num;
    char xrel, yrel;

    num = sscanf(str, "%dx%d%c%d%c%d",
		 &size->cx, &size->cy, &xrel, &pos->cx, &yrel, &pos->cy);
    if (num == 6
	&& (xrel == '-' || xrel == '+')
	&& (yrel == '-' || yrel == '+')) {
	if (xrel == '-')
	    pos->cx = -pos->cx;
	if (yrel == '-')
			pos->cy = -pos->cy;
	return TRUE;
    }
    if (num < 2) {
	size->cx = 80;
	size->cy = 25;
    }
    pos->cx = 0;
    pos->cy = 0;
    return FALSE;
}

// Khader
/* Checks if windows size is according to defined limits
 */
void termCheckSizeLimits()
{
    /* Limit the terminal width to TERM_MIN_X .. TERM_MAX_X
     */
    if (term.winSize.cx < TERM_MIN_X) /* Khader - replaced consts with defines */
	term.winSize.cx = TERM_MIN_X;
    if (term.winSize.cx > TERM_MAX_X)
	term.winSize.cx = TERM_MAX_X;

    /* Limit the terminal height to TERM_MIN_Y .. TERM_MAX_Y
     */
    if (term.winSize.cy < TERM_MIN_Y)
	term.winSize.cy = TERM_MIN_Y;
    if (term.winSize.cy > TERM_MAX_Y)
	term.winSize.cy = TERM_MAX_Y;
}

/* Set the geometry of the terminal window (in characters)
 *
 * Args:
 * str - new window geometry in form WxH or WxH+X+Y
 */
void termSetGeometry(char* str)
{
    /* Extract the size and position from str
     */
    term.useInitPos = extractGeometry(str, &term.winSize, &term.winInitPos);
    termCheckSizeLimits();	// Khader

    /* Do not save the window geometry in the .INI file if set via the
     * command line
     */
    useIniGeometry = FALSE;
}

/* We are about to receive window focus - realise our palette and
 * force a repaint of the window if necessary
 *
 * Return the number of changes
 */
static int termPaletteChanged(void)
{
    HDC dc;			/* terminal window device context */
    HPALETTE oldPalette;	/* remember original palette in dc */
    UINT numChanges;		/* number of changes in mapping system
				 * palette since our palette last
				 * realised */

    if (!termHasPalette)
	/* We are not using a palette, nothing to do
	 */
	return 0;

    /* Realise our logical palette in the system palette and determine
     * if there are any changes in the mapping
     */
		dc = GetDC(termWnd);
    oldPalette = SelectPalette(dc, termPalette, FALSE);
    numChanges = RealizePalette(dc);
    SelectPalette(dc, oldPalette, FALSE);
    ReleaseDC(termWnd, dc);

    /* There were changes in the palette mapping - repaint the window
     */
    if (numChanges > 0)
        InvalidateRect(termWnd, NULL, FALSE);

    /* Return the number of changes in the mapping
     */
    return (int)numChanges;
}

/* Build a palette for our terminal window
 */
static void termBuildPalette(void)
{
    NPLOGPALETTE palette;
    int idx;
    HANDLE hnd = LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE)
			    + PaletteSize * sizeof(PALETTEENTRY));

    if (!hnd)
	return;

    palette = (NPLOGPALETTE)LocalLock(hnd);
    palette->palVersion = 0x300;
    palette->palNumEntries = PaletteSize;
    for (idx = 0; idx < PaletteSize; idx++) {
	COLORREF color = colors[idx];
	palette->palPalEntry[idx].peRed = GetRValue(color);
	palette->palPalEntry[idx].peGreen = GetGValue(color);
	palette->palPalEntry[idx].peBlue = GetBValue(color);
	palette->palPalEntry[idx].peFlags = 0;
    }
    termPalette = CreatePalette((LPLOGPALETTE)palette);
    LocalUnlock((HLOCAL)palette);
    LocalFree(hnd);
}

/* Set the attribute to be used for blank characters
 */
void termSetBlankAttr(int attr)
{
    term.blankAttr = (unsigned char)attr;
}

/* Set the application window title
 */
void termSetTitle(char* title)
{
    strcpy(term.title, title);
    telnetSetTitle();
}

/* Return the application window title
 */
char* termGetTitle()
{
    return term.title;
}

/* Return whether or not there is a application window title set
 */
BOOL termHasTitle()
{
    return term.title[0] != '\0';
}

/* Scroll the window a number of lines.  Positive values scroll lines
 * up.
 *
 * Args:
 * numLines - the number of lines to scroll
 */
static void termDoScroll(int numLines)
{
    if (!numLines)
	/* Nothing to do
	 */
	return;

    if (abs(numLines) >= term.winSize.cy)
	/* Scrolling replaces the entire window - repaint it all
	 */
	InvalidateRect(termWnd, NULL, TRUE);
    else
	/* Scrolling retains some of the window
	 */
	winScrollWindow(numLines);

    /* Update the top visible line and the history scrollbar
     */
		term.topVisibleLine += numLines;
    SetScrollPos(termWnd, SB_VERT, term.topVisibleLine, TRUE);
}

/* Try scrolling the terminal a number of lines.  Positive values
 * scroll lines up.
 *
 * Args:
 * numLines - the number of lines to scroll
 */
static void termTryScroll(int numLines)
{
    if (numLines > 0) {
	/* Scrolling lines up
	 */
	if (term.topVisibleLine < winTerminalTopLine()) {
	    /* We can scroll lines up.  Make sure we do not scroll
	     * more lines than exist.
	     */
	    if (term.topVisibleLine + numLines < winTerminalTopLine())
		termDoScroll(numLines);
	    else
		termDoScroll(winTerminalTopLine() - term.topVisibleLine);
	}
    } else {
	/* Scrolling lines down
	 */
	if (term.topVisibleLine > 0) {
	    /* We can scroll lines down.  Make sure wr do not scroll
	     * more lines than exist.
	     */
	    if (term.topVisibleLine + numLines >= 0)
		termDoScroll(numLines);
	    else
		termDoScroll(-term.topVisibleLine);
	}
    }
}

/* User moved the history scrollbar.  Scroll the terminal window.
 *
 * Args:
 * code - the type of scroll performed
 * pos -  the scrollbar position
 */
static void termUseScrollbar(UINT code, UINT pos)
{
    if (term.numLinesUsed <= term.winSize.cy)
	/* Cannot scroll if we have used less lines than the height of
	 * the window.
	 */
	return;

    switch (code) {
    case SB_BOTTOM:
	termDoScroll(winTerminalTopLine() - term.topVisibleLine);
	break;
    case SB_ENDSCROLL:
	break;
    case SB_LINEDOWN:
	termTryScroll(1);
	break;
    case SB_LINEUP:
	termTryScroll(-1);
	break;
    case SB_PAGEDOWN:
	termTryScroll(term.winSize.cy);
	break;
    case SB_PAGEUP:
	termTryScroll(-term.winSize.cy);
	break;
    case SB_THUMBTRACK:
    case SB_THUMBPOSITION:
	if ((int)pos > winTerminalTopLine())
	    pos = winTerminalTopLine();
	termDoScroll((int)pos - term.topVisibleLine);
	break;
    case SB_TOP:
	termDoScroll(-term.topVisibleLine);
	break;
    }

    /* Redraw the caret at the correct position
     */
    winCaretPos(term.cursor.x, term.cursor.y);
}

/* Scroll the terminal to the bottom of the history
 */
void termScrollToBottom()
{
    if (term.numLinesUsed > term.winSize.cy)
	termDoScroll(winTerminalTopLine() - term.topVisibleLine);
}

/* Toggle whether or not terminal output forces a scroll to bottom
 */
void termToggleBottomOnOutput()
{
    bottomOnOutput = !bottomOnOutput;
}

/* Return whether or not terminal output forces a scroll to bottom
 */
BOOL termBottomOnOutput()
{
		return bottomOnOutput;
}

/* Toggle the state of auto-copy on selection
 */
void termToggleAutoCopy()
{
		autoCopy = !autoCopy;
}

⌨️ 快捷键说明

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