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

  1. /* File: D:\WACKER\tdll\termcur.c (Created: 26-Jan-1994)
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 4 $
  7. * $Date: 3/26/02 8:44a $
  8. */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. #include "stdtyp.h"
  12. #include "session.h"
  13. #include "assert.h"
  14. #include "timers.h"
  15. #include <emu\emu.h>
  16. #include "term.h"
  17. #include "term.hh"
  18. #include "misc.h"
  19. static void CalcHstCursorRect(const HHTERM hhTerm, const PRECT prc);
  20. static void CalcLclCursorRect(const HHTERM hhTerm, const PRECT prc);
  21. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  22. * FUNCTION:
  23. * CalHstCursorRect (static function seen only by TERMPROC.C)
  24. *
  25. * DESCRIPTION:
  26. * Figures out the bounding rectangle of the host cursor.
  27. *
  28. * ARGUMENTS:
  29. * HTERM hTerm - pointer to the terminal instance data
  30. * PRECT prc - pointer to rectangle to fill
  31. *
  32. * RETURNS:
  33. * Nothing.
  34. *
  35. */
  36. static void CalcHstCursorRect(const HHTERM hhTerm, const PRECT prc)
  37. {
  38. int iRow;
  39. prc->bottom = ((hhTerm->ptHstCur.y + 2 - hhTerm->iVScrlPos)) * hhTerm->yChar;
  40. prc->top = prc->bottom - hhTerm->iHstCurSiz;
  41. prc->left = (((hhTerm->ptHstCur.x - hhTerm->iHScrlPos) * hhTerm->xChar)) +
  42. hhTerm->xIndent + hhTerm->xBezel;
  43. prc->right = prc->left + hhTerm->xChar;
  44. // Check for double wide left/right pair. If so, make the
  45. // cursor wider.
  46. iRow = (hhTerm->ptHstCur.y + hhTerm->iTopline) % MAX_EMUROWS;
  47. if (hhTerm->ptHstCur.x < (MAX_EMUCOLS - 1) &&
  48. hhTerm->fppstAttr[iRow][hhTerm->ptHstCur.x].dblwilf &&
  49. hhTerm->fppstAttr[iRow][hhTerm->ptHstCur.x+1].dblwirt)
  50. {
  51. prc->right += hhTerm->xChar;
  52. }
  53. // This keeps the cursor from appearing in the indent margin.
  54. if (prc->left <= hhTerm->xIndent)
  55. prc->left = prc->right = 0;
  56. }
  57. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  58. * FUNCTION:
  59. * CalLclCursorRect (static function seen only by TERMPROC.C)
  60. *
  61. * DESCRIPTION:
  62. * Figures out the bounding rectangle of the selection cursor.
  63. *
  64. * ARGUMENTS:
  65. * hhTerm hhTerm - pointer to the terminal instance data
  66. * PRECT prc - pointer to rectangle to fill
  67. *
  68. * RETURNS:
  69. * Nothing.
  70. *
  71. */
  72. static void CalcLclCursorRect(const HHTERM hhTerm, const PRECT prc)
  73. {
  74. prc->left = ((hhTerm->ptLclCur.x - hhTerm->iHScrlPos) * hhTerm->xChar)
  75. + hhTerm->xIndent + hhTerm->xBezel;
  76. prc->right = prc->left + 2;
  77. prc->top = (hhTerm->ptLclCur.y - hhTerm->iVScrlPos) * hhTerm->yChar;
  78. prc->bottom = prc->top + hhTerm->yChar;
  79. return;
  80. }
  81. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  82. * FUNCTION:
  83. * PaintHostCursor
  84. *
  85. * DESCRIPTION:
  86. * Paints the host cursor at the position and style in hLayout. Also
  87. * Hides and shows the caret or local cursor which was not part of the
  88. * orginal design here but fit in nicely.
  89. *
  90. */
  91. void PaintHostCursor(const HHTERM hhTerm, const BOOL fOn, const HDC hdc)
  92. {
  93. RECT rc;
  94. if (hhTerm->fHstCurOn == fOn)
  95. return;
  96. hhTerm->fHstCurOn = fOn;
  97. CalcHstCursorRect(hhTerm, &rc);
  98. InvertRect(hdc, &rc);
  99. return;
  100. }
  101. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  102. * FUNCTION:
  103. * PaintLocalCursor
  104. *
  105. * DESCRIPTION:
  106. * Local meaning the seletion cursor in this case.
  107. *
  108. */
  109. void PaintLocalCursor(const HHTERM hhTerm, const BOOL fOn, const HDC hdc)
  110. {
  111. RECT rc;
  112. if (hhTerm->fCursorsLinked && hhTerm->fLclCurOn == 0)
  113. return;
  114. if (hhTerm->fLclCurOn == fOn)
  115. return;
  116. hhTerm->fLclCurOn = fOn;
  117. CalcLclCursorRect(hhTerm, &rc);
  118. InvertRect(hdc, &rc);
  119. return;
  120. }
  121. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  122. * FUNCTION:
  123. * ShowCursors
  124. *
  125. * DESCRIPTION:
  126. * Use to just show the host cursor but also shows the caret or local
  127. * cursor as well.
  128. *
  129. * ARGUMENTS:
  130. * HHTERM hhTerm - internal terminal handle.
  131. *
  132. * RETURNS:
  133. * VOID
  134. *
  135. */
  136. void ShowCursors(const HHTERM hhTerm)
  137. {
  138. const HDC hdc = GetDC(hhTerm->hwnd);
  139. PaintHostCursor(hhTerm, TRUE, hdc);
  140. PaintLocalCursor(hhTerm, TRUE, hdc);
  141. ReleaseDC(hhTerm->hwnd, hdc);
  142. return;
  143. }
  144. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  145. * FUNCTION:
  146. * HideCursors
  147. *
  148. * DESCRIPTION:
  149. * Use to just hide the host cursor but also hides the caret or local
  150. * cursor as well.
  151. *
  152. * ARGUMENTS:
  153. * HHTERM hhTerm - internal terminal handle.
  154. *
  155. * RETURNS:
  156. * VOID
  157. *
  158. */
  159. void HideCursors(const HHTERM hhTerm)
  160. {
  161. const HDC hdc = GetDC(hhTerm->hwnd);
  162. PaintHostCursor(hhTerm, FALSE, hdc);
  163. PaintLocalCursor(hhTerm, FALSE, hdc);
  164. ReleaseDC(hhTerm->hwnd, hdc);
  165. return;
  166. }
  167. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  168. * FUNCTION:
  169. * SetLclCurPos
  170. *
  171. * DESCRIPTION:
  172. * The local cursor is the marking cursor. This routine just positions
  173. * it according to the coordinates handling any painting requirements.
  174. *
  175. * ARGUMENTS:
  176. * HHTERM hhTerm - internal terminal handle
  177. * LPPOINT ptCur - point structure where marking cursor goes
  178. *
  179. * RETURNS:
  180. * VOID
  181. *
  182. */
  183. void SetLclCurPos(const HHTERM hhTerm, const LPPOINT lpptCur)
  184. {
  185. const HDC hdc = GetDC(hhTerm->hwnd);
  186. PaintLocalCursor(hhTerm, FALSE, hdc);
  187. hhTerm->ptLclCur = *lpptCur;
  188. hhTerm->fCursorsLinked = FALSE;
  189. PaintLocalCursor(hhTerm, TRUE, hdc);
  190. ReleaseDC(hhTerm->hwnd, hdc);
  191. return;
  192. }
  193. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  194. * FUNCTION:
  195. * LinkCursors
  196. *
  197. * DESCRIPTION:
  198. * Magic little function that causes the selection cursor to link-up with
  199. * the host cursor. This happens the view has to be shifted to present
  200. * the host cursor or when characters are typed at the keyboard.
  201. *
  202. * ARGUMENTS:
  203. * HHTERM hhTerm - internal terminal handle.
  204. *
  205. * RETURNS:
  206. * void
  207. *
  208. */
  209. void LinkCursors(const HHTERM hhTerm)
  210. {
  211. if (!hhTerm->fCursorsLinked)
  212. {
  213. const HDC hdc = GetDC(hhTerm->hwnd);
  214. hhTerm->fCursorsLinked = TRUE;
  215. PaintLocalCursor(hhTerm, FALSE, hdc);
  216. ReleaseDC(hhTerm->hwnd, hdc);
  217. hhTerm->fExtSelect = FALSE;
  218. MarkText(hhTerm, &hhTerm->ptBeg, &hhTerm->ptEnd, FALSE, MARK_ABS);
  219. hhTerm->ptBeg = hhTerm->ptEnd = hhTerm->ptHstCur;
  220. TestForMarkingLock(hhTerm);
  221. }
  222. return;
  223. }
  224. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  225. * FUNCTION:
  226. * MoveSelectionCursor
  227. *
  228. * DESCRIPTION:
  229. * Moves the selection cursor by the specified amount and updates the
  230. * terminal window so that the cursor is in view. Used by kbd routines.
  231. *
  232. * ARGUMENTS:
  233. * HTERM hTerm - handle to terminal
  234. * HWND hwnd - terminal window
  235. * INT x - amount to move left or right
  236. * INT y - amount to move up or down
  237. * BOOL fMarking- TRUE means we are marking text.
  238. *
  239. * RETURNS:
  240. * void
  241. *
  242. */
  243. void MoveSelectionCursor(const HHTERM hhTerm,
  244. const HWND hwnd,
  245. int x,
  246. int y,
  247. BOOL fMarking)
  248. {
  249. int yTemp;
  250. POINT ptTmp;
  251. // Extended selection is where the user does not have to hold down
  252. // shift keys to select text. - mrw
  253. fMarking |= hhTerm->fExtSelect;
  254. if (fMarking == FALSE)
  255. UnmarkText(hhTerm);
  256. ptTmp = hhTerm->ptEnd;
  257. // This tests to see if the selection cursor is on-screen. If the
  258. // selection cursor is off-screen, place it at the top of the
  259. // screen and then perform the operation. This is how MicroSoft
  260. // Word behaves.
  261. if (hhTerm->ptEnd.y < hhTerm->iVScrlPos ||
  262. (hhTerm->ptEnd.y - hhTerm->iTermHite + 1) > hhTerm->iVScrlPos)
  263. {
  264. hhTerm->ptEnd.y = hhTerm->iVScrlPos;
  265. }
  266. hhTerm->ptEnd.x += x;
  267. hhTerm->ptEnd.x = max(min(hhTerm->iCols, hhTerm->ptEnd.x), 0);
  268. yTemp = hhTerm->ptEnd.y += y;
  269. hhTerm->ptEnd.y = max(min(hhTerm->iRows, hhTerm->ptEnd.y), hhTerm->iVScrlMin);
  270. //mpt:1-23-98 attempt to re-enable DBCS code
  271. #ifndef CHAR_NARROW
  272. termValidatePosition(hhTerm,
  273. x >= 0 ? VP_ADJUST_RIGHT : VP_ADJUST_LEFT,
  274. &hhTerm->ptEnd);
  275. #endif
  276. if (fMarking == FALSE)
  277. hhTerm->ptBeg = hhTerm->ptEnd;
  278. SetLclCurPos(hhTerm, &hhTerm->ptEnd);
  279. // Figure out much to scroll vertically.
  280. if (hhTerm->ptEnd.y < hhTerm->iVScrlPos)
  281. y = hhTerm->ptEnd.y;
  282. else if ((hhTerm->ptEnd.y - hhTerm->iTermHite) >= hhTerm->iVScrlPos)
  283. y = hhTerm->ptEnd.y - hhTerm->iTermHite + 1;
  284. else
  285. y = hhTerm->iVScrlPos;
  286. // This condition occurs when we are scrolling and the Bezel is
  287. // present.
  288. //
  289. if (yTemp > hhTerm->ptEnd.y && y < hhTerm->iVScrlMax)
  290. y = hhTerm->iVScrlMax;
  291. // Do the scroll
  292. //
  293. if (y != hhTerm->iVScrlPos)
  294. SendMessage(hwnd, WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, y), 0);
  295. // Figure out much to scroll horizontally
  296. //
  297. if (hhTerm->ptEnd.x < hhTerm->iHScrlPos)
  298. x = hhTerm->ptEnd.x;
  299. else if (hhTerm->ptEnd.x >= (hhTerm->iHScrlPos + hhTerm->iCols - hhTerm->iHScrlMax))
  300. x = hhTerm->ptEnd.x - (hhTerm->iCols - hhTerm->iHScrlMax) + 1;
  301. else
  302. x = hhTerm->iHScrlPos;
  303. if (x != hhTerm->iHScrlPos)
  304. SendMessage(hwnd, WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, x), 0);
  305. // Force update to keep things smooth looking. Note, UpdateWindow()
  306. // does nothing if the update rectangle is NULL.
  307. if (fMarking)
  308. MarkText(hhTerm, &ptTmp, &hhTerm->ptEnd, TRUE, MARK_XOR);
  309. UpdateWindow(hwnd);
  310. return;
  311. }
  312. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  313. * FUNCTION:
  314. * CursorTimerProc
  315. *
  316. * DESCRIPTION:
  317. * Multiplex timer callback routine used for cursor blinking. Also
  318. * controls blinking text.
  319. *
  320. * ARGUMENTS:
  321. * pvhwnd - terminal window handle.
  322. * ltime - contains time elapsed.
  323. *
  324. * RETURNS:
  325. * void
  326. *
  327. */
  328. void CALLBACK CursorTimerProc(void *pvhwnd, long ltime)
  329. {
  330. const HWND hwnd = (HWND)pvhwnd;
  331. if (GetFocus() == hwnd)
  332. {
  333. const HHTERM hhTerm = (HHTERM)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  334. if (hhTerm->fBlink && !IsTerminalServicesEnabled())
  335. {
  336. const HDC hdc = GetDC(hhTerm->hwnd);
  337. PaintHostCursor(hhTerm, hhTerm->fHstCurOn ? FALSE : TRUE, hdc);
  338. ReleaseDC(hhTerm->hwnd, hdc);
  339. }
  340. BlinkText(hhTerm);
  341. }
  342. return;
  343. }