Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

409 lines
9.9 KiB

/* 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;
}