|
|
/* File: D:\WACKER\tdll\termcur.c (Created: 26-Jan-1994)
* * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI * All rights reserved * * $Revision: 4 $ * $Date: 3/26/02 8:44a $ */ #include <windows.h>
#pragma hdrstop
#include "stdtyp.h"
#include "session.h"
#include "assert.h"
#include "timers.h"
#include <emu\emu.h>
#include "term.h"
#include "term.hh"
#include "misc.h"
static void CalcHstCursorRect(const HHTERM hhTerm, const PRECT prc); static void CalcLclCursorRect(const HHTERM hhTerm, const PRECT prc);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * CalHstCursorRect (static function seen only by TERMPROC.C) * * DESCRIPTION: * Figures out the bounding rectangle of the host cursor. * * ARGUMENTS: * HTERM hTerm - pointer to the terminal instance data * PRECT prc - pointer to rectangle to fill * * RETURNS: * Nothing. * */ static void CalcHstCursorRect(const HHTERM hhTerm, const PRECT prc) { int iRow; prc->bottom = ((hhTerm->ptHstCur.y + 2 - hhTerm->iVScrlPos)) * hhTerm->yChar; prc->top = prc->bottom - hhTerm->iHstCurSiz;
prc->left = (((hhTerm->ptHstCur.x - hhTerm->iHScrlPos) * hhTerm->xChar)) + hhTerm->xIndent + hhTerm->xBezel;
prc->right = prc->left + hhTerm->xChar;
// Check for double wide left/right pair. If so, make the
// cursor wider.
iRow = (hhTerm->ptHstCur.y + hhTerm->iTopline) % MAX_EMUROWS;
if (hhTerm->ptHstCur.x < (MAX_EMUCOLS - 1) && hhTerm->fppstAttr[iRow][hhTerm->ptHstCur.x].dblwilf && hhTerm->fppstAttr[iRow][hhTerm->ptHstCur.x+1].dblwirt) { prc->right += hhTerm->xChar; }
// This keeps the cursor from appearing in the indent margin.
if (prc->left <= hhTerm->xIndent) prc->left = prc->right = 0; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * CalLclCursorRect (static function seen only by TERMPROC.C) * * DESCRIPTION: * Figures out the bounding rectangle of the selection cursor. * * ARGUMENTS: * hhTerm hhTerm - pointer to the terminal instance data * PRECT prc - pointer to rectangle to fill * * RETURNS: * Nothing. * */ static void CalcLclCursorRect(const HHTERM hhTerm, const PRECT prc) { prc->left = ((hhTerm->ptLclCur.x - hhTerm->iHScrlPos) * hhTerm->xChar) + hhTerm->xIndent + hhTerm->xBezel;
prc->right = prc->left + 2; prc->top = (hhTerm->ptLclCur.y - hhTerm->iVScrlPos) * hhTerm->yChar; prc->bottom = prc->top + hhTerm->yChar; return; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * PaintHostCursor * * DESCRIPTION: * Paints the host cursor at the position and style in hLayout. Also * Hides and shows the caret or local cursor which was not part of the * orginal design here but fit in nicely. * */ void PaintHostCursor(const HHTERM hhTerm, const BOOL fOn, const HDC hdc) { RECT rc;
if (hhTerm->fHstCurOn == fOn) return;
hhTerm->fHstCurOn = fOn; CalcHstCursorRect(hhTerm, &rc); InvertRect(hdc, &rc);
return; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * PaintLocalCursor * * DESCRIPTION: * Local meaning the seletion cursor in this case. * */ void PaintLocalCursor(const HHTERM hhTerm, const BOOL fOn, const HDC hdc) { RECT rc;
if (hhTerm->fCursorsLinked && hhTerm->fLclCurOn == 0) return;
if (hhTerm->fLclCurOn == fOn) return;
hhTerm->fLclCurOn = fOn; CalcLclCursorRect(hhTerm, &rc); InvertRect(hdc, &rc);
return; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * ShowCursors * * DESCRIPTION: * Use to just show the host cursor but also shows the caret or local * cursor as well. * * ARGUMENTS: * HHTERM hhTerm - internal terminal handle. * * RETURNS: * VOID * */ void ShowCursors(const HHTERM hhTerm) { const HDC hdc = GetDC(hhTerm->hwnd);
PaintHostCursor(hhTerm, TRUE, hdc); PaintLocalCursor(hhTerm, TRUE, hdc);
ReleaseDC(hhTerm->hwnd, hdc); return; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * HideCursors * * DESCRIPTION: * Use to just hide the host cursor but also hides the caret or local * cursor as well. * * ARGUMENTS: * HHTERM hhTerm - internal terminal handle. * * RETURNS: * VOID * */ void HideCursors(const HHTERM hhTerm) { const HDC hdc = GetDC(hhTerm->hwnd);
PaintHostCursor(hhTerm, FALSE, hdc); PaintLocalCursor(hhTerm, FALSE, hdc);
ReleaseDC(hhTerm->hwnd, hdc); return; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * SetLclCurPos * * DESCRIPTION: * The local cursor is the marking cursor. This routine just positions * it according to the coordinates handling any painting requirements. * * ARGUMENTS: * HHTERM hhTerm - internal terminal handle * LPPOINT ptCur - point structure where marking cursor goes * * RETURNS: * VOID * */ void SetLclCurPos(const HHTERM hhTerm, const LPPOINT lpptCur) { const HDC hdc = GetDC(hhTerm->hwnd);
PaintLocalCursor(hhTerm, FALSE, hdc); hhTerm->ptLclCur = *lpptCur; hhTerm->fCursorsLinked = FALSE; PaintLocalCursor(hhTerm, TRUE, hdc);
ReleaseDC(hhTerm->hwnd, hdc); return; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * LinkCursors * * DESCRIPTION: * Magic little function that causes the selection cursor to link-up with * the host cursor. This happens the view has to be shifted to present * the host cursor or when characters are typed at the keyboard. * * ARGUMENTS: * HHTERM hhTerm - internal terminal handle. * * RETURNS: * void * */ void LinkCursors(const HHTERM hhTerm) { if (!hhTerm->fCursorsLinked) { const HDC hdc = GetDC(hhTerm->hwnd);
hhTerm->fCursorsLinked = TRUE; PaintLocalCursor(hhTerm, FALSE, hdc); ReleaseDC(hhTerm->hwnd, hdc);
hhTerm->fExtSelect = FALSE;
MarkText(hhTerm, &hhTerm->ptBeg, &hhTerm->ptEnd, FALSE, MARK_ABS); hhTerm->ptBeg = hhTerm->ptEnd = hhTerm->ptHstCur; TestForMarkingLock(hhTerm); }
return; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * MoveSelectionCursor * * DESCRIPTION: * Moves the selection cursor by the specified amount and updates the * terminal window so that the cursor is in view. Used by kbd routines. * * ARGUMENTS: * HTERM hTerm - handle to terminal * HWND hwnd - terminal window * INT x - amount to move left or right * INT y - amount to move up or down * BOOL fMarking- TRUE means we are marking text. * * RETURNS: * void * */ void MoveSelectionCursor(const HHTERM hhTerm, const HWND hwnd, int x, int y, BOOL fMarking) { int yTemp; POINT ptTmp;
// Extended selection is where the user does not have to hold down
// shift keys to select text. - mrw
fMarking |= hhTerm->fExtSelect;
if (fMarking == FALSE) UnmarkText(hhTerm);
ptTmp = hhTerm->ptEnd;
// This tests to see if the selection cursor is on-screen. If the
// selection cursor is off-screen, place it at the top of the
// screen and then perform the operation. This is how MicroSoft
// Word behaves.
if (hhTerm->ptEnd.y < hhTerm->iVScrlPos || (hhTerm->ptEnd.y - hhTerm->iTermHite + 1) > hhTerm->iVScrlPos) { hhTerm->ptEnd.y = hhTerm->iVScrlPos; }
hhTerm->ptEnd.x += x; hhTerm->ptEnd.x = max(min(hhTerm->iCols, hhTerm->ptEnd.x), 0);
yTemp = hhTerm->ptEnd.y += y; hhTerm->ptEnd.y = max(min(hhTerm->iRows, hhTerm->ptEnd.y), hhTerm->iVScrlMin);
//mpt:1-23-98 attempt to re-enable DBCS code
#ifndef CHAR_NARROW
termValidatePosition(hhTerm, x >= 0 ? VP_ADJUST_RIGHT : VP_ADJUST_LEFT, &hhTerm->ptEnd); #endif
if (fMarking == FALSE) hhTerm->ptBeg = hhTerm->ptEnd;
SetLclCurPos(hhTerm, &hhTerm->ptEnd);
// Figure out much to scroll vertically.
if (hhTerm->ptEnd.y < hhTerm->iVScrlPos) y = hhTerm->ptEnd.y;
else if ((hhTerm->ptEnd.y - hhTerm->iTermHite) >= hhTerm->iVScrlPos) y = hhTerm->ptEnd.y - hhTerm->iTermHite + 1;
else y = hhTerm->iVScrlPos;
// This condition occurs when we are scrolling and the Bezel is
// present.
//
if (yTemp > hhTerm->ptEnd.y && y < hhTerm->iVScrlMax) y = hhTerm->iVScrlMax;
// Do the scroll
//
if (y != hhTerm->iVScrlPos) SendMessage(hwnd, WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, y), 0);
// Figure out much to scroll horizontally
//
if (hhTerm->ptEnd.x < hhTerm->iHScrlPos) x = hhTerm->ptEnd.x;
else if (hhTerm->ptEnd.x >= (hhTerm->iHScrlPos + hhTerm->iCols - hhTerm->iHScrlMax)) x = hhTerm->ptEnd.x - (hhTerm->iCols - hhTerm->iHScrlMax) + 1;
else x = hhTerm->iHScrlPos;
if (x != hhTerm->iHScrlPos) SendMessage(hwnd, WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, x), 0);
// Force update to keep things smooth looking. Note, UpdateWindow()
// does nothing if the update rectangle is NULL.
if (fMarking) MarkText(hhTerm, &ptTmp, &hhTerm->ptEnd, TRUE, MARK_XOR);
UpdateWindow(hwnd); return; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * CursorTimerProc * * DESCRIPTION: * Multiplex timer callback routine used for cursor blinking. Also * controls blinking text. * * ARGUMENTS: * pvhwnd - terminal window handle. * ltime - contains time elapsed. * * RETURNS: * void * */ void CALLBACK CursorTimerProc(void *pvhwnd, long ltime) { const HWND hwnd = (HWND)pvhwnd;
if (GetFocus() == hwnd) { const HHTERM hhTerm = (HHTERM)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (hhTerm->fBlink && !IsTerminalServicesEnabled()) { const HDC hdc = GetDC(hhTerm->hwnd); PaintHostCursor(hhTerm, hhTerm->fHstCurOn ? FALSE : TRUE, hdc); ReleaseDC(hhTerm->hwnd, hdc); }
BlinkText(hhTerm); }
return; }
|