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.

1094 lines
27 KiB

  1. /* File: D:\WACKER\emu\emu_std.c (Created: 08-Dec-1993)
  2. *
  3. * Copyright 1994, 1998 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 5 $
  7. * $Date: 5/21/02 10:28a $
  8. */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. // #define DEBUGSTR
  12. #include <tdll\stdtyp.h>
  13. #include <tdll\tdll.h>
  14. #include <tdll\assert.h>
  15. #include <tdll\chars.h>
  16. #include <tdll\cloop.h>
  17. #include <tdll\mc.h>
  18. #include <tdll\session.h>
  19. #include <tdll\backscrl.h>
  20. #include <tdll\com.h>
  21. #include <tdll\capture.h>
  22. #include <tdll\print.h>
  23. #include <tdll\update.h>
  24. #include <tdll\htchar.h>
  25. #include <xfer\xfer.h>
  26. #include "emu.h"
  27. #include "emu.hh"
  28. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  29. * FUNCTION:
  30. * stdResetTerminal
  31. *
  32. * DESCRIPTION:
  33. * Had to add a vector for reset terminal. Reset functions appear to be
  34. * in most emulators but not all and were never assigned a function
  35. * pointer. I've done this and have made a standard "stub" function
  36. * for those emulators that don't have such a function.
  37. *
  38. * ARGUMENTS:
  39. * BOOL
  40. *
  41. * RETURNS:
  42. * 0
  43. *
  44. */
  45. /* ARGSUSED */
  46. int stdResetTerminal(const HHEMU hhEmu, const int fHost)
  47. {
  48. return 0;
  49. }
  50. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  51. * FUNCTION:
  52. *
  53. * DESCRIPTION:
  54. *
  55. * ARGUMENTS:
  56. * hhEmu - Private emulator handle.
  57. * kcode - The key to examine.
  58. * fTest - TRUE if we only want to test the key.
  59. *
  60. * RETURNS:
  61. * 0 if we can process the key, -1 otherwise.
  62. *
  63. */
  64. int std_kbdin(const HHEMU hhEmu, int kcode, const int fTest)
  65. {
  66. static const int KeyBreak = VK_CANCEL|VIRTUAL_KEY|CTRL_KEY;
  67. static const int KeyExtBreak = VK_CANCEL|VIRTUAL_KEY|CTRL_KEY|EXTENDED_KEY;
  68. static const int KeyBreakNT = VK_CANCEL|EXTENDED_KEY;
  69. static const int KeyAltBreak = VK_PAUSE |VIRTUAL_KEY|ALT_KEY;
  70. ECHAR eChar;
  71. HCLOOP hCloop = sessQueryCLoopHdl(hhEmu->hSession);
  72. if (fTest)
  73. {
  74. // The backspace key is a special case. We must convert it to
  75. // whatever the user has specified in the "Settings" properties
  76. // page. So, if we are testing for backspace, return 0. This
  77. // ensures that we get called again with fTest set to FALSE. When
  78. // this happens we will process the key. - cab:11/18/96
  79. //
  80. if (kcode == VK_BACKSPACE)
  81. {
  82. #ifdef INCL_USER_DEFINED_BACKSPACE_AND_TELNET_TERMINAL_ID
  83. return 0;
  84. #else
  85. return -1;
  86. #endif
  87. }
  88. // We also process the break key.
  89. //
  90. else if (kcode == KeyBreak || kcode == KeyExtBreak ||
  91. kcode == KeyAltBreak || kcode == KeyBreakNT)
  92. {
  93. return 0;
  94. }
  95. else
  96. {
  97. return -1;
  98. }
  99. }
  100. // Process the backspace key according to the user setting
  101. // in the "Settings" properties page. - cab:11/18/96
  102. //
  103. if (kcode == VK_BACKSPACE)
  104. {
  105. #ifdef INCL_USER_DEFINED_BACKSPACE_AND_TELNET_TERMINAL_ID
  106. switch(hhEmu->stUserSettings.nBackspaceKeys)
  107. {
  108. case EMU_BKSPKEYS_CTRLH:
  109. CLoopCharOut(hCloop, TEXT('\x08'));
  110. break;
  111. case EMU_BKSPKEYS_DEL:
  112. CLoopCharOut(hCloop, TEXT('\x7F'));
  113. break;
  114. case EMU_BKSPKEYS_CTRLHSPACE:
  115. CLoopCharOut(hCloop, TEXT('\x08'));
  116. CLoopCharOut(hCloop, TEXT('\x20'));
  117. CLoopCharOut(hCloop, TEXT('\x08'));
  118. break;
  119. default:
  120. assert(0);
  121. break;
  122. }
  123. #endif
  124. return -1;
  125. }
  126. // Process the break key.
  127. //
  128. else if (kcode == KeyBreak || kcode == KeyExtBreak || kcode == KeyBreakNT)
  129. {
  130. ComDriverSpecial(sessQueryComHdl(hhEmu->hSession), "Send Break", NULL, 0);
  131. return -1;
  132. }
  133. else if (kcode == KeyAltBreak)
  134. {
  135. ComDriverSpecial(sessQueryComHdl(hhEmu->hSession), "Send IP", NULL, 0);
  136. return -1;
  137. }
  138. //
  139. // Processing for the enter key
  140. //
  141. else if (kcode == TEXT('\x0D') ||
  142. kcode == (VK_RETURN | VIRTUAL_KEY))
  143. {
  144. CLoopCharOut(hCloop, TEXT('\x0D'));
  145. //
  146. // Make sure to add the line feed ('\n' or '\x0A')
  147. // with line ends ('\r' or '\x0D') if the ASCII
  148. // settings are set for this option. REV: 5/16/2002
  149. //
  150. if (CLoopGetAddLF(hCloop))
  151. {
  152. CLoopCharOut(hCloop, TEXT('\x0A'));
  153. }
  154. return (-1);
  155. }
  156. //
  157. // processing for the for the escape key
  158. //
  159. else if (kcode == (VK_ESCAPE | VIRTUAL_KEY))
  160. {
  161. CLoopCharOut(hCloop, TEXT('\x1B'));
  162. return (-1);
  163. }
  164. //
  165. // processing for the for the tab key
  166. //
  167. else if (kcode == (VK_TAB | VIRTUAL_KEY))
  168. {
  169. CLoopCharOut(hCloop, TEXT('\x09'));
  170. return (-1);
  171. }
  172. // Throw away any other virtual keys.
  173. //
  174. else if (kcode & VIRTUAL_KEY)
  175. {
  176. return -1;
  177. }
  178. // Send any other characters out the port.
  179. //
  180. eChar = (ECHAR)kcode;
  181. CLoopCharOut(hCloop, (UCHAR)(eChar & 0x00FF));
  182. return -1;
  183. }
  184. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  185. * std_getscrollcnt
  186. *
  187. * DESCRIPTION: Tells caller how many lines the screen has scrolled since
  188. * the last request.
  189. *
  190. * ARGUMENTS: none
  191. *
  192. * RETURNS: nothing
  193. */
  194. int std_getscrollcnt(const HHEMU hhEmu)
  195. {
  196. const int retval = hhEmu->scr_scrollcnt;
  197. hhEmu->scr_scrollcnt = 0;
  198. return(retval);
  199. }
  200. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  201. * FUNCTION:
  202. *
  203. * DESCRIPTION:
  204. *
  205. * ARGUMENTS:
  206. *
  207. * RETURNS:
  208. *
  209. */
  210. void std_getscrsize(const HHEMU hhEmu, int *rows, int *cols)
  211. {
  212. *rows = hhEmu->emu_maxrow + 1;
  213. *cols = hhEmu->emu_maxcol + 1;
  214. }
  215. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  216. * FUNCTION:
  217. *
  218. * DESCRIPTION:
  219. *
  220. * ARGUMENTS:
  221. *
  222. * RETURNS:
  223. *
  224. */
  225. void std_getcurpos(const HHEMU hhEmu, int *row, int *col)
  226. {
  227. *row = hhEmu->emu_currow;
  228. *col = hhEmu->emu_curcol;
  229. }
  230. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  231. * std_setcurpos
  232. *
  233. * DESCRIPTION:
  234. * Moves the cursor to the specified position on the virtual screen.
  235. * If the cursor is beyond the end of existing text, the virtual screen
  236. * line is filled out with spaces. If the cursor is beyond the edges of
  237. * the video display, the video cursor is placed as close as possible
  238. * to the desired position as the cursor display is changed.
  239. *
  240. * ARGUMENTS:
  241. * iRow -- virtual screen row to move cursor to
  242. * iCol -- virtual screen col to move cursor to
  243. *
  244. * RETURNS:
  245. * nothing
  246. */
  247. void std_setcurpos(const HHEMU hhEmu, const int iRow, const int iCol)
  248. {
  249. hhEmu->emu_currow = max(min(iRow, hhEmu->emu_maxrow), 0);
  250. hhEmu->emu_curcol = max(min(iCol, hhEmu->emu_maxcol), 0);
  251. updateCursorPos(sessQueryUpdateHdl(hhEmu->hSession),
  252. hhEmu->emu_currow,
  253. hhEmu->emu_curcol);
  254. hhEmu->emu_imgrow = row_index(hhEmu, hhEmu->emu_currow);
  255. return;
  256. }
  257. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  258. * FUNCTION:
  259. *
  260. * DESCRIPTION:
  261. *
  262. * ARGUMENTS:
  263. *
  264. * RETURNS:
  265. *
  266. */
  267. STATTR std_getattr(const HHEMU hhEmu)
  268. {
  269. return hhEmu->attrState[CS_STATE];
  270. }
  271. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  272. * FUNCTION:
  273. *
  274. * DESCRIPTION:
  275. *
  276. * ARGUMENTS:
  277. *
  278. * RETURNS:
  279. *
  280. */
  281. void std_setattr(const HHEMU hhEmu, PSTATTR pstAttr)
  282. {
  283. assert(pstAttr);
  284. hhEmu->attrState[CS_STATE] = *pstAttr;
  285. hhEmu->attrState[CSCLEAR_STATE] = *pstAttr;
  286. hhEmu->emu_charattr = *pstAttr;
  287. hhEmu->emu_clearattr = *pstAttr;
  288. return;
  289. }
  290. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  291. * FUNCTION:
  292. *
  293. * DESCRIPTION:
  294. *
  295. * ARGUMENTS:
  296. *
  297. * RETURNS:
  298. *
  299. */
  300. void std_setcolors(const HHEMU hhEmu, const int fore, const int back)
  301. {
  302. hhEmu->attrState[CSCLEAR_STATE].txtclr = (unsigned)fore;
  303. hhEmu->attrState[CSCLEAR_STATE].bkclr = (unsigned)back;
  304. hhEmu->emu_clearattr = hhEmu->attrState[CSCLEAR_STATE];
  305. hhEmu->emu_clearattr_sav = hhEmu->emu_clearattr;
  306. hhEmu->attrState[CS_STATE].txtclr = (unsigned)fore;
  307. hhEmu->attrState[CS_STATE].bkclr = (unsigned)back;
  308. if (hhEmu->iCurAttrState == CS_STATE)
  309. hhEmu->emu_charattr = hhEmu->attrState[CS_STATE];
  310. return;
  311. }
  312. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  313. * FUNCTION:
  314. *
  315. * DESCRIPTION:
  316. *
  317. * ARGUMENTS:
  318. *
  319. * RETURNS:
  320. *
  321. */
  322. void std_getcolors(const HHEMU hhEmu, int *fore, int *back)
  323. {
  324. *fore = hhEmu->attrState[hhEmu->iCurAttrState].txtclr;
  325. *back = hhEmu->attrState[hhEmu->iCurAttrState].bkclr;
  326. }
  327. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  328. * std_initcolors
  329. *
  330. * DESCRIPTION: Sets the entire attr image to the current colors
  331. *
  332. * ARGUMENTS: none
  333. *
  334. * RETURNS: nothing
  335. */
  336. void std_initcolors(const HHEMU hhEmu)
  337. {
  338. register int row, col;
  339. for (row = 0; row < MAX_EMUROWS; row++)
  340. for (col = 0 ; col <= MAX_EMUCOLS ; ++col)
  341. {
  342. hhEmu->emu_apAttr[row][col].txtclr = hhEmu->emu_clearattr.txtclr;
  343. hhEmu->emu_apAttr[row][col].bkclr = hhEmu->emu_clearattr.bkclr;
  344. }
  345. }
  346. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  347. * FUNCTION:
  348. *
  349. * DESCRIPTION:
  350. *
  351. * ARGUMENTS:
  352. *
  353. * RETURNS:
  354. *
  355. */
  356. void std_restorescreen(const HHEMU hhEmu)
  357. {
  358. updateLine(sessQueryUpdateHdl(hhEmu->hSession), 0, hhEmu->emu_maxrow);
  359. hhEmu->iCurAttrState = CS_STATE;
  360. }
  361. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  362. * std_clearscreen
  363. *
  364. * DESCRIPTION:
  365. * Erases some or all of the virtual screen image.
  366. *
  367. * ARGUMENTS:
  368. * select -- 0 to erase from cursor to end of screen
  369. * -- 1 to erase from start of screen to cursor
  370. * -- 2 to erase entire screen
  371. *
  372. * RETURNS:
  373. * nothing
  374. */
  375. void std_clearscreen(const HHEMU hhEmu, const int nClearSelect)
  376. {
  377. register int r;
  378. int trow, tcol;
  379. PSTATTR pstAttr;
  380. ECHAR aechBuf[10];
  381. BOOL fSave;
  382. trow = hhEmu->emu_currow;
  383. tcol = hhEmu->emu_curcol;
  384. switch (nClearSelect)
  385. {
  386. /* cursor to end of screen */
  387. case 0:
  388. fSave = (hhEmu->emu_currow == 0 &&
  389. hhEmu->emu_curcol == 0) ? TRUE : FALSE;
  390. for (r = hhEmu->emu_currow + (fSave ? 0 : 1) ; r < MAX_EMUROWS; ++r)
  391. {
  392. if (fSave)
  393. {
  394. backscrlAdd(sessQueryBackscrlHdl(hhEmu->hSession),
  395. hhEmu->emu_apText[row_index(hhEmu, r)],
  396. hhEmu->emu_maxcol+1);
  397. CaptureLine(sessQueryCaptureFileHdl(hhEmu->hSession),
  398. CF_CAP_SCREENS,
  399. hhEmu->emu_apText[row_index(hhEmu, r)],
  400. emuRowLen(hhEmu, row_index(hhEmu, r)));
  401. printEchoScreen(hhEmu->hPrintEcho,
  402. hhEmu->emu_apText[row_index(hhEmu, r)],
  403. emuRowLen(hhEmu, row_index(hhEmu, r)));
  404. CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), TEXT("\r\n"), StrCharGetByteCount(TEXT("\r\n")));
  405. printEchoScreen(hhEmu->hPrintEcho,
  406. aechBuf,
  407. sizeof(ECHAR) * 2);
  408. }
  409. clear_imgrow(hhEmu, r);
  410. }
  411. // Clear the partial row now.
  412. //
  413. ECHAR_Fill(hhEmu->emu_apText[row_index(hhEmu, hhEmu->emu_currow)] +
  414. hhEmu->emu_curcol,
  415. EMU_BLANK_CHAR,
  416. (size_t)(MAX_EMUCOLS - hhEmu->emu_curcol + 1));
  417. if (hhEmu->emu_curcol <= hhEmu->emu_aiEnd[hhEmu->emu_imgrow])
  418. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_curcol - 1;
  419. pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, hhEmu->emu_currow)];
  420. for (r = hhEmu->emu_curcol ; r <= MAX_EMUCOLS ; ++r)
  421. pstAttr[r] = hhEmu->emu_clearattr;
  422. // Tell the video image what to do. Use the emuDispRgnScrollUp() call
  423. // instead of RgnClear so edges of terminal get painted if
  424. // clear attribute changes.
  425. updateScroll(sessQueryUpdateHdl(hhEmu->hSession),
  426. 0,
  427. hhEmu->emu_maxrow,
  428. hhEmu->emu_maxrow + 1,
  429. hhEmu->emu_imgtop,
  430. TRUE);
  431. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, hhEmu->emu_curcol);
  432. // Added a global to save the clear attribute at the time of
  433. // notification. This is necessary since the message is posted
  434. // and a race condition can develop.
  435. hhEmu->emu_clearattr_sav = hhEmu->emu_clearattr;
  436. NotifyClient(hhEmu->hSession, EVENT_EMU_CLRATTR, 0);
  437. break;
  438. /* start of screen to cursor */
  439. case 1:
  440. for (r = 0; r < hhEmu->emu_currow; ++r)
  441. clear_imgrow(hhEmu, r);
  442. ECHAR_Fill(hhEmu->emu_apText[row_index(hhEmu, hhEmu->emu_currow)],
  443. EMU_BLANK_CHAR,
  444. (size_t)(hhEmu->emu_curcol + 1));
  445. if (hhEmu->emu_curcol >= hhEmu->emu_aiEnd[hhEmu->emu_imgrow])
  446. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = EMU_BLANK_LINE;
  447. pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, hhEmu->emu_currow)];
  448. for (r = 0 ; r <= hhEmu->emu_curcol ; ++r)
  449. pstAttr[r] = hhEmu->emu_clearattr;
  450. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, hhEmu->emu_curcol);
  451. updateLine(sessQueryUpdateHdl(hhEmu->hSession), 0, hhEmu->emu_currow);
  452. break;
  453. /* Entire screen */
  454. case 2:
  455. for (r = 0; r < MAX_EMUROWS; ++r)
  456. {
  457. backscrlAdd(sessQueryBackscrlHdl(hhEmu->hSession),
  458. hhEmu->emu_apText[row_index(hhEmu, r)],
  459. hhEmu->emu_maxcol+1);
  460. CaptureLine(sessQueryCaptureFileHdl(hhEmu->hSession),
  461. CF_CAP_SCREENS,
  462. hhEmu->emu_apText[row_index(hhEmu, r)],
  463. emuRowLen(hhEmu, row_index(hhEmu, r)));
  464. printEchoScreen(hhEmu->hPrintEcho,
  465. hhEmu->emu_apText[row_index(hhEmu, r)],
  466. emuRowLen(hhEmu, row_index(hhEmu, r)));
  467. CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), TEXT("\r\n"), StrCharGetByteCount(TEXT("\r\n")));
  468. printEchoScreen(hhEmu->hPrintEcho,
  469. aechBuf,
  470. sizeof(ECHAR) * 2);
  471. clear_imgrow(hhEmu, r);
  472. }
  473. updateScroll(sessQueryUpdateHdl(hhEmu->hSession),
  474. 0,
  475. hhEmu->emu_maxrow,
  476. hhEmu->emu_maxrow + 1,
  477. hhEmu->emu_imgtop,
  478. TRUE);
  479. // Save the clear attribute at the time of
  480. // notification. This is necessary since the message is posted
  481. // and a race condition can develop.
  482. hhEmu->emu_clearattr_sav = hhEmu->emu_clearattr;
  483. NotifyClient(hhEmu->hSession, EVENT_EMU_CLRATTR, 0);
  484. break;
  485. default:
  486. commanderror(hhEmu);
  487. }
  488. (*hhEmu->emu_setcurpos)(hhEmu, trow, tcol);
  489. }
  490. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  491. * std_clearline
  492. *
  493. * DESCRIPTION:
  494. * Erases some or all of the current virtual screen line and corresponding
  495. * real screen line.
  496. *
  497. * ARGUMENTS:
  498. * select -- 0 to erase from cursor to end of line
  499. * -- 1 to erase from start of line to cursor
  500. * -- 2 to erase entire line
  501. *
  502. * RETURNS:
  503. * nothing
  504. */
  505. void std_clearline(const HHEMU hhEmu, const int nClearSelect)
  506. {
  507. register int i;
  508. PSTATTR pstAttr;
  509. switch (nClearSelect)
  510. {
  511. /* to end of line */
  512. case 0:
  513. if (hhEmu->emu_curcol == 0)
  514. {
  515. backscrlAdd(sessQueryBackscrlHdl(hhEmu->hSession),
  516. hhEmu->emu_apText[row_index(hhEmu, hhEmu->emu_currow)],
  517. hhEmu->emu_maxcol+1);
  518. }
  519. updateLine(sessQueryUpdateHdl(hhEmu->hSession),
  520. hhEmu->emu_currow,
  521. hhEmu->emu_currow);
  522. ECHAR_Fill(hhEmu->emu_apText[row_index(hhEmu, hhEmu->emu_currow)] +
  523. hhEmu->emu_curcol,
  524. EMU_BLANK_CHAR,
  525. (size_t)(hhEmu->emu_maxcol - hhEmu->emu_curcol + 1));
  526. if (hhEmu->emu_curcol <= hhEmu->emu_aiEnd[hhEmu->emu_imgrow])
  527. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_curcol - 1;
  528. pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, hhEmu->emu_currow)];
  529. for (i = hhEmu->emu_curcol ; i <= hhEmu->emu_maxcol ; ++i)
  530. pstAttr[i] = hhEmu->emu_clearattr;
  531. break;
  532. /* from start of line to cursor */
  533. case 1:
  534. updateLine(sessQueryUpdateHdl(hhEmu->hSession),
  535. hhEmu->emu_currow,
  536. hhEmu->emu_currow);
  537. ECHAR_Fill(hhEmu->emu_apText[row_index(hhEmu, hhEmu->emu_currow)],
  538. EMU_BLANK_CHAR,
  539. (size_t)(hhEmu->emu_curcol+1));
  540. if (hhEmu->emu_curcol < hhEmu->emu_aiEnd[hhEmu->emu_imgrow])
  541. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_curcol + 1;
  542. else if (hhEmu->emu_curcol == hhEmu->emu_aiEnd[hhEmu->emu_imgrow])
  543. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = EMU_BLANK_LINE;
  544. pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, hhEmu->emu_currow)];
  545. for (i = 0 ; i <= hhEmu->emu_curcol ; ++i)
  546. pstAttr[i] = hhEmu->emu_clearattr;
  547. break;
  548. /* Entire line */
  549. case 2:
  550. backscrlAdd(sessQueryBackscrlHdl(hhEmu->hSession),
  551. hhEmu->emu_apText[row_index(hhEmu, hhEmu->emu_currow)],
  552. hhEmu->emu_maxcol + 1);
  553. updateLine(sessQueryUpdateHdl(hhEmu->hSession),
  554. hhEmu->emu_currow,
  555. hhEmu->emu_currow);
  556. clear_imgrow(hhEmu, hhEmu->emu_currow);
  557. break;
  558. default:
  559. commanderror(hhEmu);
  560. }
  561. }
  562. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  563. * std_clearrgn
  564. *
  565. * DESCRIPTION:
  566. * Erases a region of the current virtual screen and corresponding
  567. * real screen region.
  568. *
  569. * ARGUMENTS:
  570. * toprow -- top row of region
  571. * leftcol -- column of region's left edge
  572. * botmrow -- bottom row of region
  573. * rightcol -- column of region's right edge
  574. *
  575. * RETURNS:
  576. * nothing
  577. */
  578. void std_clearrgn(const HHEMU hhEmu,
  579. int toprow,
  580. int leftcol,
  581. int botmrow,
  582. int rightcol)
  583. {
  584. int irow, num, idx;
  585. PSTATTR pstAttr;
  586. /* make sure region is within the screen */
  587. toprow = max(toprow, 0);
  588. leftcol = max(leftcol, 0);
  589. botmrow = min(botmrow, hhEmu->emu_maxrow);
  590. rightcol = min(rightcol, hhEmu->emu_maxcol);
  591. updateLine(sessQueryUpdateHdl(hhEmu->hSession),
  592. toprow,
  593. botmrow);
  594. num = (rightcol - leftcol) + 1;
  595. /* copy image to memory */
  596. for (irow = toprow; irow <= botmrow; irow++)
  597. {
  598. ECHAR_Fill(hhEmu->emu_apText[row_index(hhEmu, irow)]+leftcol,
  599. EMU_BLANK_CHAR,
  600. (size_t)num);
  601. // If the current end of line position is within the range
  602. // being cleared, we need to find the last character in the
  603. // row array working backwards from position leftcol - 1;
  604. //
  605. if (hhEmu->emu_aiEnd[row_index(hhEmu, irow)] >= leftcol &&
  606. hhEmu->emu_aiEnd[row_index(hhEmu, irow)] <= rightcol)
  607. {
  608. idx = min(0, leftcol - 1);
  609. while (idx >= 0)
  610. {
  611. if (*hhEmu->emu_apText[row_index(hhEmu, irow)] + idx != EMU_BLANK_CHAR)
  612. break;
  613. idx --;
  614. }
  615. hhEmu->emu_aiEnd[row_index(hhEmu, irow)] = idx;
  616. }
  617. pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, irow)]+leftcol;
  618. for (pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, irow)]+leftcol;
  619. num > 0 ; --num)
  620. *pstAttr++ = hhEmu->emu_clearattr;
  621. }
  622. }
  623. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  624. * std_deinstall
  625. *
  626. * DESCRIPTION:
  627. * Uninstalls current emulator by freeing used memory.
  628. *
  629. * ARGUMENTS:
  630. * none
  631. *
  632. * RETURNS:
  633. * nothing
  634. */
  635. /* ARGSUSED */
  636. void std_deinstall(const HHEMU hhEmu)
  637. {
  638. return;
  639. }
  640. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  641. * std_scroll
  642. *
  643. * DESCRIPTION:
  644. * Scrolls the screen or portions of the screen.
  645. *
  646. * ARGUMENTS:
  647. * nlines -- number of lines to scroll
  648. * direction -- TRUE if scroll is up
  649. *
  650. * RETURNS:
  651. * nothing
  652. */
  653. void std_scroll(const HHEMU hhEmu, const int nlines, const BOOL direction)
  654. {
  655. if (direction)
  656. scrollup(hhEmu, nlines);
  657. else
  658. scrolldown(hhEmu, nlines);
  659. }
  660. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  661. * FUNCTION:
  662. * EmuStdSetCursorType
  663. *
  664. * DESCRIPTION:
  665. * Sets the cursor type.
  666. *
  667. * ARGUMENTS:
  668. *
  669. * RETURNS:
  670. *
  671. */
  672. void EmuStdSetCursorType(const HHEMU hhEmu, int iCurType)
  673. {
  674. hhEmu->iCurType = iCurType;
  675. NotifyClient(hhEmu->hSession, EVENT_EMU_SETTINGS, 0);
  676. return;
  677. }
  678. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  679. * EmuChkChar
  680. *
  681. * DESCRIPTION: Called from all of the emulators when codes to process are
  682. * outside of the displayable range. If the code translates
  683. * to a character in the displayable range, the emulator's
  684. * display function is called with the translated character.
  685. *
  686. * ARGUMENTS: none
  687. *
  688. * RETURNS: nothing
  689. */
  690. /* ARGSUSED */
  691. void EmuChkChar(const HHEMU hhEmu)
  692. {
  693. }
  694. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  695. * EmuStdChkZmdm
  696. *
  697. * DESCRIPTION: Called when the current emulator picks up rz/r. Starts
  698. * receiving with Zmodem.
  699. *
  700. * ARGUMENTS: none
  701. *
  702. * RETURNS: nothing
  703. *
  704. * GOOD FOR: nothing
  705. */
  706. void EmuStdChkZmdm(const HHEMU hhEmu)
  707. {
  708. ECHAR old_emu_code;
  709. switch(hhEmu->iZmodemState++)
  710. {
  711. case 0:
  712. // Got the Ctrl-X
  713. // DbgOutStr("ZMDM - case 0\r\n", 0, 0, 0, 0, 0);
  714. DbgOutStr("ZMDM - case 0\r\n", 0, 0, 0, 0, 0);
  715. break;
  716. case 1:
  717. // Got the B?
  718. //DbgOutStr("ZMDM - case 1(0x%x)(%c)\r\n", emu_code, emu_code, 0, 0, 0);
  719. if (hhEmu->emu_code != ETEXT('B'))
  720. {
  721. hhEmu->state = 0;
  722. old_emu_code = hhEmu->emu_code;
  723. if ((hhEmu->stUserSettings.nEmuId == EMU_ANSI) ||
  724. (hhEmu->stUserSettings.nEmuId == EMU_ANSIW))
  725. {
  726. hhEmu->emu_code = CAN;
  727. (*hhEmu->emu_graphic)(hhEmu);
  728. }
  729. hhEmu->emu_code = old_emu_code;
  730. #if defined(EXTENDED_FEATURES)
  731. (void)(*hhEmu->emu_datain)(hhEmu, old_emu_code);
  732. #else
  733. (void)(*hhEmu->emu_datain)((HEMU)hhEmu, old_emu_code);
  734. #endif
  735. hhEmu->iZmodemState = 0;
  736. }
  737. break;
  738. case 2:
  739. // Got a 0?
  740. //DbgOutStr("ZMDM - case 2(0x%x)(%c)\r\n", emu_code, emu_code, 0, 0, 0);
  741. if (hhEmu->emu_code != ETEXT('0'))
  742. {
  743. hhEmu->state = 0;
  744. old_emu_code = hhEmu->emu_code;
  745. if ((hhEmu->stUserSettings.nEmuId == EMU_ANSI) ||
  746. (hhEmu->stUserSettings.nEmuId == EMU_ANSIW))
  747. {
  748. hhEmu->emu_code = CAN;
  749. (*hhEmu->emu_graphic)(hhEmu);
  750. }
  751. hhEmu->emu_code = ETEXT('B');
  752. (*hhEmu->emu_graphic)(hhEmu);
  753. hhEmu->emu_code = old_emu_code;
  754. #if defined(EXTENDED_FEATURES)
  755. (void)(*hhEmu->emu_datain)(hhEmu, old_emu_code);
  756. #else
  757. (void)(*hhEmu->emu_datain)((HEMU)hhEmu, old_emu_code);
  758. #endif
  759. hhEmu->iZmodemState = 0;
  760. }
  761. break;
  762. case 3:
  763. // Got a 0?
  764. //DbgOutStr("ZMDM - case 3(0x%x)(%c)\r\n", emu_code, emu_code, 0, 0, 0);
  765. if (hhEmu->emu_code == ETEXT('0'))
  766. {
  767. emuComDone((HEMU)hhEmu);
  768. NotifyClient(hhEmu->hSession,
  769. EVENT_HOST_XFER_REQ,
  770. XF_ZMODEM);
  771. }
  772. else
  773. {
  774. old_emu_code = hhEmu->emu_code;
  775. //TODO Put in a better way to display these codes.
  776. if ((hhEmu->stUserSettings.nEmuId == EMU_ANSI) ||
  777. (hhEmu->stUserSettings.nEmuId == EMU_ANSIW))
  778. {
  779. hhEmu->emu_code = CAN;
  780. (*hhEmu->emu_graphic)(hhEmu);
  781. }
  782. hhEmu->emu_code = ETEXT('B');
  783. (*hhEmu->emu_graphic)(hhEmu);
  784. hhEmu->emu_code = ETEXT('0');
  785. (*hhEmu->emu_graphic)(hhEmu);
  786. hhEmu->emu_code = old_emu_code;
  787. #if defined(EXTENDED_FEATURES)
  788. (void)(*hhEmu->emu_datain)(hhEmu, old_emu_code);
  789. #else
  790. (void)(*hhEmu->emu_datain)((HEMU)hhEmu, old_emu_code);
  791. #endif
  792. }
  793. hhEmu->state = 0;
  794. hhEmu->iZmodemState = 0;
  795. break;
  796. default:
  797. // DbgOutStr("ZMDM - default\r\n", 0, 0, 0, 0, 0);
  798. hhEmu->state = 0;
  799. hhEmu->iZmodemState = 0;
  800. break;
  801. }
  802. }
  803. void std_dsptbl(const HHEMU hhEmu, int bit8)
  804. {
  805. register INT x;
  806. for (x = 0; x < 128; ++x)
  807. hhEmu->dspchar[x] = (UCHAR)x;
  808. if (bit8)
  809. for (x = 128; x < 256; ++x)
  810. hhEmu->dspchar[x] = (UCHAR)x;
  811. else
  812. for (x = 128; x < 256; ++x)
  813. hhEmu->dspchar[x] = (UCHAR)(x - 128);
  814. }
  815. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  816. * FUNCTION:
  817. * std_emu_ntfy
  818. *
  819. * DESCRIPTION:
  820. * Function called when session notified of a connection. Place holder
  821. * for function pointer.
  822. *
  823. * ARGUMENTS:
  824. * hhEmu - private emulator handle
  825. *
  826. * RETURNS:
  827. * void
  828. *
  829. */
  830. /* ARGSUSED */
  831. void std_emu_ntfy(const HHEMU hhEmu, const int nNtfy)
  832. {
  833. return;
  834. }
  835. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  836. * FUNCTION:
  837. * emuHomeHostCursor
  838. *
  839. * DESCRIPTION:
  840. * Most terminal's home position is 0,0.
  841. *
  842. * ARGUMENTS:
  843. * hhEmu - private emulator handle.
  844. *
  845. * RETURNS:
  846. * 0=OK, else error
  847. *
  848. */
  849. int std_HomeHostCursor(const HHEMU hhEmu)
  850. {
  851. if (hhEmu == 0)
  852. {
  853. assert(0);
  854. return -1;
  855. }
  856. (*hhEmu->emu_setcurpos)(hhEmu, 0, 0);
  857. return 0;
  858. }
  859. #ifdef INCL_TERMINAL_SIZE_AND_COLORS
  860. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  861. * FUNCTION:
  862. * std_setscrsize
  863. *
  864. * DESCRIPTION:
  865. * This function is called from emuSetSettings. It sets up the emulator
  866. * to use the number of rows and columns defined un the user settings
  867. * structure of the emulator handle.
  868. *
  869. * ARGUMENTS:
  870. * hhEmu - The internal emulator handle.
  871. *
  872. * RETURNS:
  873. * void
  874. *
  875. * AUTHOR: Bob Kundrat, 19-Feb-1996
  876. */
  877. void std_setscrsize(const HHEMU hhEmu)
  878. {
  879. register int r, c;
  880. int iClearRow;
  881. PSTATTR pstAttr = 0;
  882. const int iOldRows = hhEmu->emu_maxrow + 1;
  883. const int iOldCols = hhEmu->emu_maxcol + 1;
  884. int iRows = hhEmu->stUserSettings.nUserDefRows;
  885. int iCols = hhEmu->stUserSettings.nUserDefCols;
  886. // Don't do anything if the values have not changed.
  887. //
  888. if (iRows == iOldRows && iCols == iOldCols)
  889. return;
  890. // Range check the requested screen size. A minimum of 2 is
  891. // used to avoid a divide by zero error in row_index().
  892. //
  893. iRows = min(MAX_EMUROWS, iRows);
  894. iRows = max(iRows, MIN_EMUROWS);
  895. iCols = min(MAX_EMUCOLS, iCols);
  896. iCols = max(iCols, MIN_EMUCOLS);
  897. // Adjust global values to accomodate screen size change. Remember,
  898. // most of the globals are zero based.
  899. //
  900. hhEmu->emu_maxrow = iRows - 1;
  901. hhEmu->emu_maxcol = iCols - 1;
  902. hhEmu->bottom_margin = hhEmu->emu_maxrow;
  903. // In the case of changing from a larger screen to a smaller one,
  904. // the cursor may have been at a location that isn't on the new
  905. // size. Put it as close as possible on the new screen.
  906. //
  907. hhEmu->emu_currow = min(hhEmu->emu_currow, hhEmu->emu_maxrow);
  908. hhEmu->emu_curcol = min(hhEmu->emu_curcol, hhEmu->emu_maxcol);
  909. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, hhEmu->emu_curcol);
  910. // If the screen size got smaller, we need to clear the cells out
  911. // of the part of the buffer that is no longer being used.
  912. //
  913. if ((iOldRows - 1) > hhEmu->emu_maxrow)
  914. {
  915. for (r = hhEmu->emu_maxrow + 1; r < MAX_EMUROWS; ++r)
  916. {
  917. iClearRow = row_index(hhEmu, r);
  918. pstAttr = hhEmu->emu_apAttr[iClearRow];
  919. for (c = 0; c < MAX_EMUCOLS; c++)
  920. pstAttr[c] = hhEmu->emu_clearattr;
  921. }
  922. }
  923. if ((iOldCols - 1) > hhEmu->emu_maxcol)
  924. {
  925. for (r = 0; r < MAX_EMUROWS; ++r)
  926. {
  927. pstAttr = hhEmu->emu_apAttr[r];
  928. for (c = hhEmu->emu_maxcol + 1; c < MAX_EMUCOLS ; ++c)
  929. pstAttr[c] = hhEmu->emu_clearattr;
  930. }
  931. }
  932. // Telnet has a negotiated option to let the server know whenever the
  933. // terminal size changes. In case it has been enabled, we must let
  934. // the com driver know about this change.
  935. ComDriverSpecial(sessQueryComHdl(hhEmu->hSession), "Update Terminal Size", NULL, 0);
  936. return;
  937. }
  938. #endif
  939. /* end of emu_std.c */