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.

529 lines
13 KiB

  1. /* File: D:\WACKER\tdll\update.c (Created: 09-Dec-1993)
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 1 $
  7. * $Date: 10/05/98 12:36p $
  8. */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. #include <math.h>
  12. #include "stdtyp.h"
  13. #include "mc.h"
  14. #include "assert.h"
  15. #include "session.h"
  16. #include <emu\emu.h>
  17. #include "update.h"
  18. #include "update.hh"
  19. static HHUPDATE VerifyUpdateHdl(const HUPDATE hUpdate);
  20. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  21. * FUNCTION:
  22. * updateCreate
  23. *
  24. * DESCRIPTION:
  25. * Creates and initializes an update record. Make sure to call
  26. * UpdateDestroy when before killing the session or pay dear and dire
  27. * consequences in lost memory blocks - a Windows no-no.
  28. *
  29. * ARGUMENTS:
  30. * None, zippo, nil, nada, zilch, nothing.
  31. *
  32. * RETURNS:
  33. * If you're lucky, and it's Tuesday, and I can program (highly unlikely),
  34. * a handle (read pointer) to the update record. Otherwize, a NULL pointer
  35. * indicating that you're a memory piggy.
  36. *
  37. */
  38. HUPDATE updateCreate(const HSESSION hSession)
  39. {
  40. HHUPDATE hUpd;
  41. // Get some space for the update record.
  42. hUpd = (HHUPDATE)malloc(sizeof(struct stUpdate));
  43. if (hUpd == (HHUPDATE)0) // release version returns NULL
  44. {
  45. assert(FALSE);
  46. return 0;
  47. }
  48. memset(hUpd, 0, sizeof(struct stUpdate));
  49. hUpd->hSession = hSession;
  50. updateReset(hUpd);
  51. return (HUPDATE)hUpd;
  52. }
  53. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  54. * FUNCTION:
  55. * updateDestory
  56. *
  57. * DESCRIPTION:
  58. * Releases memory allocated for Update record.
  59. *
  60. * ARGUMENTS:
  61. * HUPDATE hUpdate -- handle of update record to nuke.
  62. *
  63. * RETURNS:
  64. * void
  65. */
  66. void updateDestroy(const HUPDATE hUpdate)
  67. {
  68. HHUPDATE hUpd = (HHUPDATE)hUpdate;
  69. if (hUpd == (HHUPDATE)0)
  70. return;
  71. free(hUpd);
  72. hUpd = NULL;
  73. return;
  74. }
  75. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  76. * FUNCTION:
  77. * VerifyUpdateHdl
  78. *
  79. * DESCRIPTION:
  80. * Verifies that we have a valid update handle.
  81. *
  82. * ARGUMENTS:
  83. * hUpdate - external update handle
  84. *
  85. * RETURNS:
  86. * Internal update handle or zero on error.
  87. *
  88. */
  89. static HHUPDATE VerifyUpdateHdl(const HUPDATE hUpdate)
  90. {
  91. const HHUPDATE hUpd = (HHUPDATE)hUpdate;
  92. if (hUpd == 0)
  93. {
  94. assert(0);
  95. ExitProcess(1);
  96. }
  97. return hUpd;
  98. }
  99. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  100. * FUNCTION:
  101. * updateReset
  102. *
  103. * DESCRIPTION:
  104. * Resets the update record to its initial state.
  105. *
  106. * ARGUMENTS:
  107. * HUPDATE hUpdate -- handle of update record to reset.
  108. *
  109. * RETURNS:
  110. * nothing
  111. *
  112. */
  113. void updateReset(const HHUPDATE hUpd)
  114. {
  115. // Something tricky going on here. I purposely don't reset the
  116. // sTopline, sRow, sCol, and usCType values so that they persist.
  117. // This avoids some problems on Client side of trying to figure
  118. // out what has changed.
  119. hUpd->bUpdateType = UPD_LINE;
  120. hUpd->fUpdateLock = FALSE;
  121. hUpd->stLine.iLine = -1;
  122. hUpd->fRealloc = FALSE;
  123. return;
  124. }
  125. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  126. * FUNCTION:
  127. * updateScroll
  128. *
  129. * DESCRIPTION:
  130. * Modifies update record to reflect the specified scrolling operation.
  131. *
  132. * ARGUMENTS:
  133. * Never argues. Just does what it's told to do.
  134. *
  135. * HUPDATE hUpdate -- the update record of course.
  136. * int yBeg -- begining line # of scroll region (inclusive)
  137. * int yEnd -- ending line # of scroll region (inclusive)
  138. * int sScrlInc -- Amount to scroll (negative or positive)
  139. * int sTopline -- line in image buf of screen row 0 (emu_imgtop)
  140. * BOOL fSave -- wheather to save line to backscroll buffer.
  141. *
  142. * RETURNS:
  143. * Nothing
  144. *
  145. */
  146. void updateScroll(const HUPDATE hUpdate,
  147. const int yBeg,
  148. const int yEnd,
  149. const int iScrlInc,
  150. const int iTopLine,
  151. const BOOL fSave)
  152. {
  153. const HHUPDATE hUpd = VerifyUpdateHdl(hUpdate);
  154. struct stScrlMode *pstScrl;
  155. int i, j;
  156. pstScrl = &hUpd->stScrl;
  157. DbgOutStr("iScrollInc=%d, yBeg=%d, yEnd=%d, iTopLine=%d\r\n",
  158. iScrlInc, yBeg, yEnd, iTopLine, 0);
  159. if (hUpd->bUpdateType != UPD_SCROLL)
  160. {
  161. DbgOutStr("Trans to Scroll Mode\r\n", 0, 0, 0, 0, 0);
  162. i = hUpd->stLine.iLine; // save this value for test below.
  163. // Setup initial scroll mode paramaters.
  164. hUpd->bUpdateType = UPD_SCROLL;
  165. pstScrl->iFirstLine = 0;
  166. pstScrl->iScrlInc = 0;
  167. pstScrl->iRgnScrlInc = 0;
  168. pstScrl->iBksScrlInc = 0;
  169. pstScrl->yBeg = 0;
  170. pstScrl->yEnd = 0;
  171. memset(pstScrl->auchLines, 0, UPD_MAXLINES * sizeof(BYTE));
  172. // If we were updating in line mode, make sure to mark that line
  173. // in scroll mode.
  174. if (i != -1)
  175. {
  176. pstScrl->auchLines[i] = (UCHAR)1;
  177. DbgOutStr("Trans -> %d\r\n", i, 0, 0, 0, 0);
  178. }
  179. }
  180. hUpd->iTopline = iTopLine;
  181. pstScrl->fSave = fSave;
  182. emuQueryRowsCols(sessQueryEmuHdl(hUpd->hSession), &j, &i);
  183. // Adjust for zero offset used by emulators...
  184. //
  185. j -= 1;
  186. /* -------------- Full screen scroll-up case ------------- */
  187. if (yBeg == 0 && yEnd == j && iScrlInc > 0)
  188. {
  189. pstScrl->yBeg = yBeg;
  190. pstScrl->yEnd = yEnd;
  191. pstScrl->iScrlInc += iScrlInc;
  192. pstScrl->iFirstLine =
  193. min(pstScrl->iFirstLine+iScrlInc, (UPD_MAXLINES-1)/2);
  194. }
  195. /* -------------- Region scroll and scroll-down ------------- */
  196. else
  197. {
  198. if (iScrlInc > 0)
  199. pstScrl->iRgnScrlInc += iScrlInc;
  200. memset(pstScrl->auchLines + pstScrl->iFirstLine + yBeg, 1,
  201. (abs(yEnd-yBeg)+1) * sizeof(UCHAR));
  202. }
  203. if ((pstScrl->iScrlInc + pstScrl->iRgnScrlInc) >= hUpd->iScrlMax)
  204. hUpd->fUpdateLock = TRUE;
  205. return;
  206. }
  207. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  208. * FUNCTION:
  209. * updateBackscroll
  210. *
  211. * DESCRIPTION:
  212. * This function updates the number of lines scrolled in the backscroll
  213. * buffer which may be different than the number of lines scrolled in
  214. * the terminal. I had to decouple the scrolling of these two regions
  215. * to handle the goofy way internet systems clear the screen. This
  216. * function is only called by backscrlAdd().
  217. *
  218. * ARGUMENTS:
  219. * HUPDATE hUpdate - the update record of course.
  220. * int iLInes - number of lines to scroll backscroll buffer.
  221. *
  222. * RETURNS:
  223. * void
  224. *
  225. */
  226. void updateBackscroll(const HUPDATE hUpdate, const int iLines)
  227. {
  228. const HHUPDATE hUpd = VerifyUpdateHdl(hUpdate);
  229. struct stScrlMode *pstScrl;
  230. int i;
  231. pstScrl = &hUpd->stScrl;
  232. if (hUpd->bUpdateType != UPD_SCROLL)
  233. {
  234. DbgOutStr("Trans to Scroll Mode (BS)\r\n", 0, 0, 0, 0, 0);
  235. i = hUpd->stLine.iLine; // save this value for test below.
  236. // Setup initial scroll mode paramaters.
  237. hUpd->bUpdateType = UPD_SCROLL;
  238. pstScrl->iFirstLine = 0;
  239. pstScrl->iScrlInc = 0;
  240. pstScrl->iRgnScrlInc = 0;
  241. pstScrl->iBksScrlInc = 0;
  242. pstScrl->yBeg = 0;
  243. pstScrl->yEnd = 0;
  244. memset(pstScrl->auchLines, 0, UPD_MAXLINES * sizeof(BYTE));
  245. // If we were updating in line mode, make sure to mark that line
  246. // in scroll mode.
  247. if (i != -1)
  248. {
  249. pstScrl->auchLines[i] = (UCHAR)1;
  250. DbgOutStr("Trans -> %d\r\n", i, 0, 0, 0, 0);
  251. }
  252. }
  253. pstScrl->iBksScrlInc += iLines;
  254. DbgOutStr("iBksScrlInc = %d\r\n", pstScrl->iBksScrlInc, 0, 0, 0, 0);
  255. return;
  256. }
  257. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  258. * FUNCTION:
  259. * updateLine
  260. *
  261. * DESCRIPTION:
  262. * Modifies the update record line array for the given line range.
  263. *
  264. * ARGUMENTS:
  265. * HUPDATE hUpdate -- the update record of course.
  266. * int yBeg -- begining line # (inclusive)
  267. * int yEnd -- ending line # (inclusive)
  268. *
  269. * RETURNS:
  270. * void
  271. *
  272. */
  273. void updateLine(const HUPDATE hUpdate, const int yBeg, const int yEnd)
  274. {
  275. const HHUPDATE hUpd = VerifyUpdateHdl(hUpdate);
  276. BYTE *pauchLines;
  277. struct stScrlMode *pstScrl;
  278. assert(hUpd != (HHUPDATE)0);
  279. pstScrl = &hUpd->stScrl; // for speed...
  280. if (hUpd->bUpdateType != UPD_SCROLL)
  281. {
  282. DbgOutStr("Trans to Line Mode\r\n", 0, 0, 0, 0, 0);
  283. memset(pstScrl->auchLines, 0, UPD_MAXLINES);
  284. // 10/20/92 - This if statement fixes a bug that caused the
  285. // update records to miss a line that was being updated in
  286. // character mode and then jumping to another line - mrw.
  287. if (hUpd->stLine.iLine != -1)
  288. {
  289. pauchLines = pstScrl->auchLines + hUpd->stLine.iLine;
  290. *pauchLines = (UCHAR)1;
  291. DbgOutStr("Trans -> %d\r\n", hUpd->stLine.iLine, 0, 0, 0, 0);
  292. }
  293. hUpd->bUpdateType = UPD_SCROLL;
  294. pstScrl->yBeg = 0;
  295. pstScrl->yEnd = 0;
  296. pstScrl->iScrlInc = 0;
  297. pstScrl->iRgnScrlInc = 0;
  298. pstScrl->iBksScrlInc = 0;
  299. pstScrl->fSave = FALSE;
  300. pstScrl->iFirstLine = 0;
  301. }
  302. memset(pstScrl->auchLines+pstScrl->iFirstLine+yBeg, 1, yEnd-yBeg+1);
  303. DbgOutStr("Line -> %d - %d\r\n", yBeg, yEnd, 0, 0, 0);
  304. return;
  305. }
  306. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  307. * FUNCTION:
  308. * updateChar
  309. *
  310. * DESCRIPTION:
  311. * Modifies the update record when it is in character mode. This is a
  312. * complex function but it handles a character a quickly as possible.
  313. * Usually, only one or two checks are made. Also, if this routine
  314. * is called in line mode, it calls the appropriate line mode routine.
  315. *
  316. * ARGUMENTS:
  317. * HUPDATE hUpdate -- handle to update buffer
  318. * int yPos -- line to modify
  319. * int xPos -- character position within line.
  320. *
  321. * RETURNS:
  322. * TRUE on success
  323. *
  324. */
  325. void updateChar(const HUPDATE hUpdate,
  326. const int yPos,
  327. const int xBegPos,
  328. const int xEndPos)
  329. {
  330. const HHUPDATE hUpd = VerifyUpdateHdl(hUpdate);
  331. struct stLineMode *pstLine;
  332. assert(hUpd != (HHUPDATE)0);
  333. assert(xBegPos <= xEndPos);
  334. // First check to see if we are in line mode. If not, check if this
  335. // line is included in the UPD_SCROLL parameters of hUpd already.
  336. // The check is made to avoid the overhead of a function call if the
  337. // line is already set in the UPD_SCROLL parameters.
  338. if (hUpd->bUpdateType == UPD_SCROLL)
  339. {
  340. struct stScrlMode *pstScrl = &hUpd->stScrl;
  341. if (pstScrl->auchLines[yPos + pstScrl->iFirstLine] == 0)
  342. updateLine((HUPDATE)hUpd, yPos, yPos);
  343. return;
  344. }
  345. // Ok, it is just a line. Update the UPD_LINE parameters.
  346. // Check to see that we have not jumped to a different line however.
  347. // If we have, we are no longer in UPD_LINE mode.
  348. pstLine = &hUpd->stLine; // for speed...
  349. if (yPos != pstLine->iLine)
  350. {
  351. // Check to see if sLine == -1. This means the update buffer was
  352. // just flushed and reset and that this is the first change to come
  353. // in since that time. Otherwise, we have more than one line in
  354. // our update region and have to jump to UPD_SCROLL mode.
  355. if (pstLine->iLine != -1)
  356. {
  357. updateLine((HUPDATE)hUpd, pstLine->iLine, pstLine->iLine);
  358. updateLine((HUPDATE)hUpd, yPos, yPos);
  359. }
  360. else
  361. {
  362. pstLine->iLine = yPos;
  363. pstLine->xBeg = xBegPos;
  364. pstLine->xEnd = xEndPos;
  365. DbgOutStr("Char -> iLine=%d, xBeg=%d, xEnd=%d\r\n",
  366. yPos, xBegPos, xEndPos, 0, 0);
  367. }
  368. return;
  369. }
  370. // Ok, we've eliminated any conflicts. Go ahead and update.
  371. if (xBegPos < pstLine->xBeg)
  372. pstLine->xBeg = xBegPos;
  373. if (xEndPos > pstLine->xEnd)
  374. pstLine->xEnd = xEndPos;
  375. DbgOutStr("Char -> iLine=%d, xBeg=%d, xEnd=%d\r\n",
  376. yPos, xBegPos, xEndPos, 0, 0);
  377. return;
  378. }
  379. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  380. * FUNCTION:
  381. * updateCursorPos
  382. *
  383. * DESCRIPTION:
  384. * Sets the row and col values of the host cursor in the given update handle
  385. *
  386. * ARGUMENTS:
  387. * HUPDATE hUpdate - need I say!
  388. * int iRow - host cursor row
  389. * int iCol - host cursor col
  390. *
  391. * RETURNS:
  392. * nothing
  393. *
  394. */
  395. void updateCursorPos(const HUPDATE hUpdate,
  396. const int iRow,
  397. const int iCol)
  398. {
  399. const HHUPDATE hUpd = VerifyUpdateHdl(hUpdate);
  400. hUpd->iRow = iRow;
  401. hUpd->iCol = iCol;
  402. return;
  403. }
  404. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  405. * FUNCTION:
  406. * updateSetReallocFlag
  407. *
  408. * DESCRIPTION:
  409. * Sets the realloc flag in the update records. This flag can only be
  410. * cleared by a client update request.
  411. *
  412. * ARGUMENTS:
  413. *
  414. * RETURNS:
  415. *
  416. */
  417. int updateSetReallocFlag(const HUPDATE hUpdate, const BOOL fState)
  418. {
  419. const HHUPDATE hUpd = VerifyUpdateHdl(hUpdate);
  420. hUpd->fRealloc = fState ? TRUE : FALSE;
  421. NotifyClient(hUpd->hSession, EVENT_TERM_UPDATE, 0);
  422. return 0;
  423. }
  424. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  425. * FUNCTION:
  426. * updateSetScrlMax
  427. *
  428. * DESCRIPTION:
  429. * Sets the upper limit on the number of lines that can be scrolled
  430. * before the update records stop accepting input.
  431. *
  432. * ARGUMENTS:
  433. * hUpdate - external update handle
  434. * iScrlmax - max limit
  435. *
  436. * RETURNS:
  437. * 0
  438. *
  439. */
  440. int updateSetScrlMax(const HUPDATE hUpdate, const int iScrlMax)
  441. {
  442. const HHUPDATE hUpd = VerifyUpdateHdl(hUpdate);
  443. hUpd->iScrlMax = iScrlMax;
  444. return 0;
  445. }