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.

1693 lines
44 KiB

  1. /* File: \wacker\emu\vt220.c (Created: 28-Jan-1998)
  2. *
  3. * Copyright 1998 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 8 $
  7. * $Date: 5/09/01 4:48p $
  8. */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. #include <tdll\stdtyp.h>
  12. #include <tdll\tdll.h>
  13. #include <tdll\htchar.h>
  14. #include <tdll\session.h>
  15. #include <tdll\cloop.h>
  16. #include <tdll\assert.h>
  17. #include <tdll\print.h>
  18. #include <tdll\update.h>
  19. #include <tdll\capture.h>
  20. #include <tdll\backscrl.h>
  21. #include <tdll\chars.h>
  22. #include <tdll\mc.h>
  23. #include "emu.h"
  24. #include "emu.hh"
  25. #include "emudec.hh"
  26. #if defined(INCL_VT220)
  27. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  28. * vt220_hostreset
  29. *
  30. * DESCRIPTION:
  31. * Calls vt220_reset() when told by the host to reset.
  32. *
  33. * ARGUMENTS:
  34. * none
  35. *
  36. * RETURNS:
  37. * nothing
  38. */
  39. void vt220_hostreset(const HHEMU hhEmu)
  40. {
  41. vt220_reset(hhEmu, TRUE);
  42. }
  43. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  44. * vt220_reset
  45. *
  46. * DESCRIPTION:
  47. * Calls vt220_reset() when told by the host to reset.
  48. *
  49. * ARGUMENTS:
  50. * host_request -- TRUE if told by host to reset
  51. *
  52. * RETURNS:
  53. * nothing
  54. */
  55. int vt220_reset(const HHEMU hhEmu, const int host_request)
  56. {
  57. hhEmu->mode_KAM = hhEmu->mode_IRM = hhEmu->mode_VEM =
  58. hhEmu->mode_HEM = hhEmu->mode_LNM = hhEmu->mode_DECCKM =
  59. hhEmu->mode_DECOM = hhEmu->mode_DECCOLM = hhEmu->mode_DECPFF =
  60. // hhEmu->mode_DECSCNM = hhEmu->mode_25enab = hhEmu->mode_blank =
  61. hhEmu->mode_DECSCNM = hhEmu->mode_25enab =
  62. hhEmu->mode_block = hhEmu->mode_local = RESET;
  63. hhEmu->mode_SRM = hhEmu->mode_DECPEX = hhEmu->mode_DECTCEM = SET;
  64. hhEmu->mode_AWM = TRUE;
  65. // hhEmu->mode_protect = hhEmu->vt220_protectmode = FALSE;
  66. hhEmu->mode_protect = FALSE;
  67. if (host_request)
  68. {
  69. ANSI_RIS(hhEmu);
  70. hhEmu->mode_AWM = RESET;
  71. }
  72. hhEmu->fUse8BitCodes = FALSE;
  73. hhEmu->mode_vt220 = TRUE;
  74. hhEmu->mode_vt320 = FALSE;
  75. if (hhEmu->nEmuLoaded == EMU_VT320)
  76. {
  77. hhEmu->mode_vt320 = TRUE;
  78. }
  79. vt_charset_init(hhEmu);
  80. hhEmu->emu_code = '>';
  81. vt_alt_kpmode(hhEmu);
  82. return 0;
  83. }
  84. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  85. * vt220_softreset
  86. *
  87. * DESCRIPTION:
  88. * Does a soft reset.
  89. *
  90. * ARGUMENTS:
  91. * none
  92. *
  93. * RETURNS:
  94. * nothing
  95. */
  96. void vt220_softreset(const HHEMU hhEmu)
  97. {
  98. hhEmu->mode_KAM = hhEmu->mode_IRM = hhEmu->mode_DECCKM =
  99. hhEmu->mode_DECOM = hhEmu->mode_DECKPAM = RESET;
  100. hhEmu->mode_AWM = RESET;
  101. DEC_STBM(hhEmu, 0,0);
  102. ANSI_Pn_Clr(hhEmu);
  103. ANSI_SGR(hhEmu);
  104. hhEmu->emu_code = 0;
  105. vt100_savecursor(hhEmu);
  106. vt_charset_init(hhEmu);
  107. hhEmu->emu_code = '>';
  108. vt_alt_kpmode(hhEmu);
  109. hhEmu->mode_protect = FALSE;
  110. }
  111. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  112. * vt220mode_reset
  113. *
  114. * DESCRIPTION:
  115. * Sets the VT220 emulator to the proper conditions when switching
  116. * from vt100 mode.
  117. *
  118. * ARGUMENTS:
  119. * none
  120. *
  121. * RETURNS:
  122. * nothing
  123. */
  124. void vt220mode_reset(const HHEMU hhEmu)
  125. {
  126. hhEmu->mode_KAM = hhEmu->mode_IRM = hhEmu->mode_VEM =
  127. hhEmu->mode_HEM = hhEmu->mode_DECCKM = hhEmu->mode_DECOM =
  128. hhEmu->mode_25enab = hhEmu->mode_AWM = RESET;
  129. hhEmu->mode_DECPEX = hhEmu-> mode_DECTCEM = SET;
  130. hhEmu->fUse8BitCodes = FALSE;
  131. hhEmu->mode_vt220 = TRUE;
  132. hhEmu->mode_vt320 = FALSE;
  133. vt_charset_init(hhEmu);
  134. hhEmu->emu_code = '>';
  135. vt_alt_kpmode(hhEmu);
  136. DEC_STBM(hhEmu, 0, hhEmu->emu_maxrow + 1);
  137. hhEmu->emu_code = 0;
  138. vt100_savecursor(hhEmu);
  139. hhEmu->mode_protect = FALSE;
  140. }
  141. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  142. * vt220_DA
  143. *
  144. * DESCRIPTION:
  145. * Sends the primary device attribute (DA) information to the host.
  146. *
  147. * ARGUMENTS:
  148. * none
  149. *
  150. * RETURNS:
  151. * nothing
  152. */
  153. void vt220_DA(const HHEMU hhEmu)
  154. {
  155. int fOldValue;
  156. char achStr[50];
  157. ECHAR ech[50];
  158. //if (emuProjSuppressEmuReporting(hhEmu))
  159. // return;
  160. // Build the 7-bit or 8-bit response.
  161. //
  162. if (hhEmu->fUse8BitCodes)
  163. {
  164. achStr[0] = '\x9B';
  165. achStr[1] = '\x00';
  166. }
  167. else
  168. {
  169. achStr[0] = '\x1B';
  170. achStr[1] = '[';
  171. achStr[2] = '\x00';
  172. }
  173. // Add the VT220 or VT320 part of the response.
  174. //
  175. if (hhEmu->mode_vt320)
  176. StrCharCat(achStr, TEXT("?63"));
  177. else
  178. StrCharCat(achStr, TEXT("?62"));
  179. // Add the rest of the respnse and send the result.
  180. //
  181. StrCharCat(achStr, TEXT(";1;2;6;8;9;14c"));
  182. CnvrtMBCStoECHAR(ech, sizeof(ech), achStr,
  183. StrCharGetByteCount(achStr));
  184. fOldValue = CLoopGetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession));
  185. CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), FALSE);
  186. emuSendString(hhEmu, ech, (int)StrCharGetEcharByteCount(ech));
  187. CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), fOldValue);
  188. }
  189. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  190. * vt220_2ndDA
  191. *
  192. * DESCRIPTION:
  193. * Sends the secondary device attribute (DA) information to the host.
  194. *
  195. * ARGUMENTS:
  196. * none
  197. *
  198. * RETURNS:
  199. * nothing
  200. */
  201. void vt220_2ndDA(const HHEMU hhEmu)
  202. {
  203. int fOldValue;
  204. char achStr[50];
  205. ECHAR ech[50];
  206. // Build the 7-bit or 8-bit response.
  207. //
  208. if (hhEmu->fUse8BitCodes)
  209. {
  210. achStr[0] = '\x9B';
  211. achStr[1] = '\x00';
  212. }
  213. else
  214. {
  215. achStr[0] = '\x1B';
  216. achStr[1] = '[';
  217. achStr[2] = '\x00';
  218. }
  219. // Add the VT220 or VT320 part of the response.
  220. //
  221. if (hhEmu->mode_vt320)
  222. {
  223. StrCharCat(achStr, TEXT(">24;14;0c"));
  224. }
  225. else
  226. {
  227. StrCharCat(achStr, TEXT(">1;23;0c"));
  228. }
  229. CnvrtMBCStoECHAR(ech, sizeof(ech), achStr,
  230. StrCharGetByteCount(achStr));
  231. fOldValue = CLoopGetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession));
  232. CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), FALSE);
  233. emuSendString(hhEmu, ech, (int)StrCharGetEcharByteCount(ech));
  234. CLoopSetLocalEcho(sessQueryCLoopHdl(hhEmu->hSession), fOldValue);
  235. }
  236. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  237. * FUNCTION:
  238. * emuDecClearUDK
  239. *
  240. * DESCRIPTION:
  241. * This function clears (frees) all of the user defined key sequences
  242. * that may have been previously stored.
  243. *
  244. * ARGUMENTS:
  245. * HHEMU hhEmu - The internal emulator handle.
  246. *
  247. * NOTES:
  248. * This function is called in response to the following escape sequence.
  249. * Esc Pc;Pl |
  250. *
  251. * RETURNS:
  252. * void
  253. *
  254. * AUTHOR: John Masters, 05-Sep-1995
  255. */
  256. void emuDecClearUDK(const HHEMU hhEmu)
  257. {
  258. const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
  259. PSTEMUKEYDATA pstKey = pstPRI->pstUDK;
  260. int idx;
  261. // Set a flag that identifies the locked or unlocked status of the
  262. // UDK's that will be set after the definition of the keys has
  263. // completed.
  264. //
  265. if (hhEmu->selector[1] == 1)
  266. pstPRI->fUnlockedUDK = 1; // Keys are unlocked after definition.
  267. else
  268. pstPRI->fUnlockedUDK = 0; // Keys are locked after definition.
  269. // This function is called in response to an escape sequence that tells
  270. // the emulator to either clear each key sequence when a new one is
  271. // defined, or to clear all of the key sequences before any are defined.
  272. //
  273. // emuDecStoreUDK always clears the current sequence before assigning
  274. // a new one. So, this function will clear all of the keys only
  275. // if that's what we were asked to do. If the first selector is Zero,
  276. // then we will go ahead and clear all of the User Defined Keys.
  277. //
  278. if (hhEmu->selector[0] != 0)
  279. return;
  280. // Cycle through the user defined key table and free
  281. // any memory that may have been allocated for sequences.
  282. //
  283. if (pstKey)
  284. {
  285. for (idx = 0; idx < MAX_UDK_KEYS; idx++, pstKey++)
  286. {
  287. if (pstKey->iSequenceLen != 0)
  288. {
  289. free(pstKey->pSequence);
  290. pstKey->iSequenceLen = 0;
  291. }
  292. }
  293. }
  294. }
  295. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  296. * emuDecDefineUDK
  297. *
  298. * DESCRIPTION:
  299. * Redefines the string output by a key.
  300. *
  301. * ARGUMENTS:
  302. * none
  303. *
  304. * RETURNS:
  305. * nothing
  306. */
  307. void emuDecDefineUDK(const HHEMU hhEmu)
  308. {
  309. const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
  310. TCHAR acAscii[16] = { TEXT('0'), TEXT('1'), TEXT('2'), TEXT('3'),
  311. TEXT('4'), TEXT('5'), TEXT('6'), TEXT('7'),
  312. TEXT('8'), TEXT('9'), TEXT('A'), TEXT('B'),
  313. TEXT('C'), TEXT('D'), TEXT('E'), TEXT('F') };
  314. unsigned int aiHex[16] = { 0x00, 0x01, 0x02, 0x03,
  315. 0x04, 0x05, 0x06, 0x07,
  316. 0x08, 0x09, 0x0A, 0x0B,
  317. 0x0C, 0x0D, 0x0E, 0x0F };
  318. int idx;
  319. ECHAR emuCode;
  320. emuCode = hhEmu->emu_code;
  321. switch(pstPRI->iUDKState)
  322. {
  323. case(KEY_NUMBER_NEXT):
  324. TCHAR_Fill(pstPRI->acUDKSequence,
  325. 0, sizeof(pstPRI->acUDKSequence) / sizeof(TCHAR));
  326. pstPRI->iUDKSequenceLen = 0;
  327. pstPRI->chUDKAssignment = 0;
  328. pstPRI->iUDKState = KEY_DIGIT2_NEXT;
  329. if (IN_RANGE(emuCode,TEXT('1'),TEXT('3')))
  330. {
  331. for (idx = 0; idx < 16; idx++)
  332. {
  333. if (emuCode == acAscii[idx])
  334. break;
  335. }
  336. pstPRI->chUDKAssignment = (TCHAR)(aiHex[idx] << 4);
  337. }
  338. else
  339. {
  340. goto UDKexit;
  341. }
  342. break;
  343. case(KEY_DIGIT2_NEXT):
  344. if (isdigit(emuCode))
  345. {
  346. for (idx = 0; idx < 16; idx++)
  347. {
  348. if (emuCode == acAscii[idx])
  349. break;
  350. }
  351. pstPRI->chUDKAssignment += (TCHAR)aiHex[idx];
  352. // The key to which the following sequence will be assigned
  353. // has been identified. Lookup that key in a table and
  354. // store an index that corresponds to the key table index.
  355. // See the initialization function for the emulator for
  356. // further clarification.
  357. //
  358. for (idx = 0; idx < MAX_UDK_KEYS; idx++)
  359. {
  360. if (pstPRI->chUDKAssignment == pstPRI->pacUDKSelectors[idx])
  361. break;
  362. }
  363. // Process a possible error.
  364. //
  365. if (idx >= MAX_UDK_KEYS)
  366. {
  367. goto UDKexit;
  368. }
  369. // When the sequence is saved in the key table,
  370. // this index will be used to identify which
  371. // key in that table will get the user defined sequence.
  372. //
  373. pstPRI->iUDKTableIndex = idx;
  374. pstPRI->iUDKState = SLASH_NEXT;
  375. }
  376. else
  377. {
  378. goto UDKexit;
  379. }
  380. break;
  381. case (SLASH_NEXT):
  382. if (emuCode == TEXT('/'))
  383. {
  384. pstPRI->iUDKState = CHAR_DIGIT1_NEXT;
  385. }
  386. else
  387. {
  388. goto UDKexit;
  389. }
  390. break;
  391. case (CHAR_DIGIT1_NEXT):
  392. switch(emuCode)
  393. {
  394. case(TEXT(';')):
  395. case 0x9C:
  396. if (emuDecStoreUDK(hhEmu) != 0)
  397. goto UDKexit;
  398. if (emuCode == TEXT('\x9C'))
  399. goto UDKexit;
  400. pstPRI->iUDKState = KEY_NUMBER_NEXT;
  401. break;
  402. case(TEXT('\x1B')):
  403. pstPRI->iUDKState = ESC_SEEN;
  404. break;
  405. default:
  406. if (!isxdigit(emuCode))
  407. {
  408. goto UDKexit;
  409. }
  410. // Collect the first half of the key comming in.
  411. //
  412. for (idx = 0; idx < 16; idx++)
  413. {
  414. if (emuCode == acAscii[idx])
  415. break;
  416. }
  417. pstPRI->chUDKAssignment = 0;
  418. pstPRI->chUDKAssignment = (TCHAR)(aiHex[idx] << 4);
  419. pstPRI->iUDKState = CHAR_DIGIT2_NEXT;
  420. break;
  421. }
  422. break;
  423. case(CHAR_DIGIT2_NEXT):
  424. if (!isxdigit(emuCode))
  425. {
  426. goto UDKexit;
  427. }
  428. // This is the second half of the key comming in.
  429. //
  430. for (idx = 0; idx < 16; idx++)
  431. {
  432. if (emuCode == acAscii[idx])
  433. break;
  434. }
  435. pstPRI->chUDKAssignment += (TCHAR)aiHex[idx];
  436. if (pstPRI->chUDKAssignment >= 127)
  437. {
  438. goto UDKexit;
  439. }
  440. pstPRI->acUDKSequence[pstPRI->iUDKSequenceLen] =
  441. pstPRI->chUDKAssignment;
  442. pstPRI->iUDKSequenceLen += 1;
  443. pstPRI->iUDKState = CHAR_DIGIT1_NEXT;
  444. break;
  445. case(ESC_SEEN):
  446. if ((emuCode = TEXT('\\')) == 0)
  447. {
  448. goto UDKexit;
  449. }
  450. if (emuDecStoreUDK(hhEmu) != 0)
  451. {
  452. assert(FALSE);
  453. }
  454. // We have completed defining the user defined key sequences.
  455. // A flag set in emuDecClearUDK was set to identify the locked
  456. // or unlocked status of the sequences after their definition.
  457. // Promote that setting up to the variable used by the user
  458. // interface.
  459. //
  460. hhEmu->fAllowUserKeys = pstPRI->fUnlockedUDK;
  461. goto UDKexit;
  462. default:
  463. goto UDKexit;
  464. }
  465. // Returning from here allows the state table to pass control
  466. // back to this function, where the internal state (pstPRI->iUDKState)
  467. // will be used to control flow through the case statement above.
  468. //
  469. return;
  470. UDKexit:
  471. // The sequence is complete or we're dropping out because of
  472. // an error.
  473. //
  474. // Initialize the UDK state and the emulators state.
  475. //
  476. pstPRI->iUDKState = KEY_NUMBER_NEXT;
  477. hhEmu->state = 0;
  478. return;
  479. }
  480. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  481. * FUNCTION:
  482. * emuDecStoreUDK
  483. *
  484. * DESCRIPTION:
  485. *
  486. * ARGUMENTS:
  487. *
  488. * RETURNS:
  489. *
  490. * Author: John Masters
  491. *
  492. */
  493. int emuDecStoreUDK(const HHEMU hhEmu)
  494. {
  495. const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
  496. PSTEMUKEYDATA pstKey = pstPRI->pstUDK + pstPRI->iUDKTableIndex;
  497. // There may be a user settings that disables user defined keys.
  498. // If this feature in not enabled, get outta town.
  499. //
  500. if (!hhEmu->fAllowUserKeys)
  501. {
  502. return(0);
  503. }
  504. // First, free a previously allocated key for this entry, if
  505. // necessary.
  506. //
  507. if (pstKey->iSequenceLen != 0)
  508. {
  509. free(pstKey->pSequence);
  510. pstKey->iSequenceLen = 0;
  511. }
  512. // Now allocate the space for the key sequence.
  513. //
  514. pstKey->pSequence = malloc( sizeof(TCHAR) *
  515. (unsigned int)pstPRI->iUDKSequenceLen);
  516. if (pstKey->pSequence == 0)
  517. {
  518. assert(FALSE);
  519. return(-1);
  520. }
  521. // Now, copy the previously collected sequence into the key table
  522. // and initialize the length variable.
  523. //
  524. MemCopy(pstKey->pSequence,
  525. pstPRI->acUDKSequence,
  526. (unsigned int)pstPRI->iUDKSequenceLen);
  527. pstKey->iSequenceLen = (unsigned int)pstPRI->iUDKSequenceLen;
  528. return(0);
  529. }
  530. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  531. * vt220_level
  532. *
  533. * DESCRIPTION:
  534. * Sets the compatibility level of the VT220.
  535. *
  536. * ARGUMENTS:
  537. * none
  538. *
  539. * RETURNS:
  540. * nothing
  541. */
  542. void vt220_level(const HHEMU hhEmu)
  543. {
  544. int term, level;
  545. term = hhEmu->num_param[0];
  546. level = hhEmu->num_param_cnt > 0 ? hhEmu->num_param[1] : 0;
  547. if (level < 1)
  548. level = 0;
  549. if (term == 61)
  550. {
  551. if (hhEmu->mode_vt220)
  552. vt100_init(hhEmu);
  553. }
  554. else if (term == 62 || term == 63)
  555. {
  556. if (!hhEmu->mode_vt220)
  557. vt220_init(hhEmu); /* sets mode_vt220 & mode_vt320 */
  558. if (level == 1)
  559. hhEmu->fUse8BitCodes = FALSE;
  560. if (level == 0 || level == 2)
  561. hhEmu->fUse8BitCodes = TRUE;
  562. if (term == 62 && hhEmu->mode_vt320)
  563. hhEmu->mode_vt320 = FALSE;
  564. }
  565. }
  566. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  567. * vt220_protmode
  568. *
  569. * DESCRIPTION:
  570. * Sets up and clears protect mode -- called selective erase on vt220.
  571. *
  572. * ARGUMENTS:
  573. * none
  574. *
  575. * RETURNS:
  576. * nothing
  577. */
  578. void vt220_protmode(const HHEMU hhEmu)
  579. {
  580. hhEmu->mode_protect = (hhEmu->num_param[0] == 1);
  581. hhEmu->emu_charattr.protect = (unsigned int)hhEmu->mode_protect;
  582. }
  583. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  584. * FUNCTION:
  585. * emuDecKeyboardIn
  586. *
  587. * DESCRIPTION:
  588. * This function processes the keyboard keys for all the DEC terminal
  589. * emulators.
  590. *
  591. * Please note that both emuSendKeyString, and emuDecSendKeyString are
  592. * used in this function. emuDecSendKeyString is a function that will
  593. * convert the 8-bit sequence from the key table to a 7-bit value, if
  594. * necessary.
  595. *
  596. * Keys Used to Emulate a DEC Terminal's PF1-PF4 Keys
  597. *
  598. * The keys normally used in HyperACCESS to emulate a DEC terminal's
  599. * PF1-PF4 keys are F1-F4. Some people, however, prefer to use the
  600. * keys at the top of the PC's numeric keypad (Num Lock, /, *, -),
  601. * because these keys' physical location matches that of a DEC
  602. * terminal's PF1-PF4 keys. If you prefer using these keys, select
  603. * the "PF1-PF4 mapped to top row of keypad" checkbox in the
  604. * terminal settings dialog for the DEC terminal you are using.
  605. *
  606. * When "PF1-PF4 mapped to top row of keypad" is checked ...
  607. *
  608. * The keys at the top of the keypad act as PF1-PF4, and F1-F4
  609. * revert to performing functions defined by the operating system.
  610. * For example, F1 displays help, and Num Lock sends the character
  611. * sequence that the DEC terminal associates with PF1. The operating
  612. * system will also sense that Num Lock has been pressed, and toggle
  613. * the keyboard's Num Lock state. The Num Lock state, however, has
  614. * no effect on the behavior of the DEC terminal emulator when
  615. * PF1-PF4 are mapped to the top row of the keypad.
  616. *
  617. * When "PF1-PF4 mapped to top row of keypad" is NOT checked...
  618. *
  619. * F1-F4 act as PF1-PF4, and the keys at the top of the keypad (Num
  620. * Lock, /, *, -) perform their normal functions. For example, F1
  621. * sends the character sequence that the DEC terminal associates
  622. * with PF1, and Num Lock toggles the keyboard's Num Lock state.
  623. * When Num Lock is on, your PC's keypad (except the top row)
  624. * emulates the numeric keypad of a DEC terminal. When Num Lock is
  625. * off, your keypad's arrow keys emulate a DEC terminal's arrow
  626. * keys. (If your keyboard has a separate set of arrow keys, that
  627. * set will always emulate a DEC terminal's arrow keys, regardless
  628. * Num Lock's state.)
  629. *
  630. * ARGUMENTS:
  631. * HHEMU hhEmu - The Internal emulator handle.
  632. * int Key - The key to process.
  633. * int fTest - Are we testing, or processing the key.
  634. *
  635. * RETURNS:
  636. * This function returns the index of the table in which the key was
  637. * found.
  638. *
  639. * AUTHOR: John Masters, 12-Sep-1995
  640. */
  641. int emuDecKeyboardIn(const HHEMU hhEmu, int Key, const int fTest)
  642. {
  643. const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
  644. int index;
  645. int fNumlock;
  646. int fMovedPfKeys;
  647. int fSearchKeypad;
  648. int fCursorKeyMode;
  649. int fKeypadNumeric;
  650. int fKeypadApplication;
  651. int fSearchUDK;
  652. if (!fTest)
  653. {
  654. #if 0
  655. DbgOutStr("VT100_KBDIN", 0, 0, 0, 0, 0);
  656. DbgOutStr("Key: Char :0x%x", hKey.VKchar, 0, 0, 0, 0);
  657. DbgOutStr(" Virtual :%d", hKey.Virtual, 0, 0, 0, 0);
  658. DbgOutStr(" Ctrl :%d", hKey.Ctrl, 0, 0, 0, 0);
  659. DbgOutStr(" Alt :%d", hKey.Alt, 0, 0, 0, 0);
  660. DbgOutStr(" Shift :%d", hKey.Shift, 0, 0, 0, 0);
  661. DbgOutStr(" Extended :%d", hKey.Extended, 0, 0, 0, 0);
  662. #endif
  663. }
  664. // Initialize some locals. The keypad is either in Numeric Mode,
  665. // or Application Mode. So, the first two locals below are mutually
  666. // exclusive variables. They have been defined only to improve
  667. // readability in this code.
  668. //
  669. fKeypadApplication = hhEmu->mode_DECKPAM;
  670. fKeypadNumeric = !fKeypadApplication;
  671. //fMovedPfKeys = hhEmu->stUserSettings.fMapPFkeys;
  672. fMovedPfKeys = FALSE;
  673. fNumlock = QUERY_NUMLOCK();
  674. fSearchKeypad = (fMovedPfKeys || fNumlock);
  675. fCursorKeyMode = (hhEmu->mode_DECCKM == SET) &&
  676. (hhEmu->nEmuLoaded != EMU_VT52);
  677. fSearchUDK = hhEmu->fAllowUserKeys &&
  678. ((hhEmu->nEmuLoaded == EMU_VT220) ||
  679. (hhEmu->nEmuLoaded == EMU_VT320));
  680. assert(fKeypadApplication != fKeypadNumeric);
  681. /* -------------- Check Backspace & Delete keys ------------- */
  682. if (hhEmu->stUserSettings.fReverseDelBk && ((Key == VK_BACKSPACE) ||
  683. (Key == DELETE_KEY) || (Key == DELETE_KEY_EXT)))
  684. {
  685. Key = (Key == VK_BACKSPACE) ? DELETE_KEY : VK_BACKSPACE;
  686. }
  687. // F1 thru F4 from either function keys on the top of the keyboard,
  688. // or from the function key pad on the left. (They have not been
  689. // mapped to the top row of the numeric keypad).
  690. //
  691. if (!fMovedPfKeys && (index = emuDecKbdKeyLookup(hhEmu,
  692. Key, pstPRI->pstcEmuKeyTbl1, pstPRI->iKeyTable1Entries)) != -1)
  693. {
  694. if (!fTest)
  695. emuDecSendKeyString(hhEmu, index,
  696. pstPRI->pstcEmuKeyTbl1, pstPRI->iKeyTable1Entries);
  697. }
  698. // F1 thru F4, if they have been mapped to the top row of the
  699. // numeric keypad (Numlock, /, *, -).
  700. //
  701. else if (fMovedPfKeys && (index = emuDecKbdKeyLookup(hhEmu,
  702. Key, pstPRI->pstcEmuKeyTbl2, pstPRI->iKeyTable2Entries)) != -1)
  703. {
  704. if (!fTest)
  705. emuDecSendKeyString(hhEmu, index,
  706. pstPRI->pstcEmuKeyTbl2, pstPRI->iKeyTable2Entries);
  707. }
  708. #if FALSE // HT doesn't know the state of the numlock.
  709. // Keypad Numeric Mode.
  710. //
  711. else if (fSearchKeypad && fKeypadNumeric &&
  712. (index = emuDecKbdKeyLookup(hhEmu, Key, pstPRI->pstcEmuKeyTbl3,
  713. pstPRI->iKeyTable3Entries)) != -1)
  714. {
  715. if (!fTest)
  716. emuDecSendKeyString(hhEmu, index,
  717. pstPRI->pstcEmuKeyTbl3, pstPRI->iKeyTable3Entries);
  718. }
  719. #endif
  720. // Keypad Application Mode.
  721. //
  722. else if (fSearchKeypad && fKeypadApplication &&
  723. (index = emuDecKbdKeyLookup(hhEmu, Key, pstPRI->pstcEmuKeyTbl4,
  724. pstPRI->iKeyTable4Entries)) != -1)
  725. {
  726. if (!fTest)
  727. emuDecSendKeyString(hhEmu, index,
  728. pstPRI->pstcEmuKeyTbl4, pstPRI->iKeyTable4Entries);
  729. }
  730. // Cursor Key Mode.
  731. //
  732. else if (fCursorKeyMode &&
  733. (index = emuDecKbdKeyLookup(hhEmu, Key, pstPRI->pstcEmuKeyTbl5,
  734. pstPRI->iKeyTable5Entries)) != -1)
  735. {
  736. if (!fTest)
  737. emuDecSendKeyString(hhEmu, index,
  738. pstPRI->pstcEmuKeyTbl5, pstPRI->iKeyTable5Entries);
  739. }
  740. // User defined keys.
  741. //
  742. else if (fSearchUDK &&
  743. (index = emuDecKbdKeyLookup(hhEmu, Key, pstPRI->pstUDK,
  744. pstPRI->iUDKTableEntries)) != -1)
  745. {
  746. if (!fTest)
  747. emuDecSendKeyString(hhEmu, index, pstPRI->pstUDK,
  748. pstPRI->iUDKTableEntries);
  749. }
  750. // Standard keys.
  751. //
  752. else if ((index = emuDecKbdKeyLookup(hhEmu, Key,
  753. pstPRI->pstcEmuKeyTbl6, pstPRI->iKeyTable6Entries)) != -1)
  754. {
  755. if (!fTest)
  756. {
  757. emuDecSendKeyString(hhEmu, index,
  758. pstPRI->pstcEmuKeyTbl6, pstPRI->iKeyTable6Entries);
  759. }
  760. }
  761. // Standard characters.
  762. //
  763. else
  764. {
  765. //DbgOutStr("VT100Kbdin calling std_kbdin", 0, 0, 0, 0, 0);
  766. index = std_kbdin(hhEmu, Key, fTest);
  767. }
  768. return index;
  769. }
  770. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  771. * FUNCTION:
  772. * emuDecKbdKeyLookup
  773. *
  774. * DESCRIPTION:
  775. * Main keyboard translation routine for all emulators. Note, this
  776. * routine will not lookup keys unless the iUseTermKeys flag is set.
  777. *
  778. * ARGUMENTS:
  779. * HHEMU hhEmu - Internal emulator handle
  780. * UINT key - lower byte is char or virtual key, upper byte has flags
  781. *
  782. * RETURNS:
  783. * Index if translated, else minus one.
  784. *
  785. */
  786. int emuDecKbdKeyLookup(const HHEMU hhEmu,
  787. const KEYDEF Key,
  788. PSTCEMUKEYDATA pstKeyTbl,
  789. const int iMaxEntries)
  790. {
  791. PSTCEMUKEYDATA pstKey = pstKeyTbl;
  792. int idx,
  793. iRet;
  794. // There is no need to look for the key if the user has
  795. // the terminal set up for accelerator keys.
  796. //
  797. if (hhEmu->stUserSettings.nTermKeys == EMU_KEYS_ACCEL)
  798. {
  799. return -1;
  800. }
  801. // Do a linear search through the supplied table for the given
  802. // key. Once it is found, return that index, or return (-1) if
  803. // the key is not located.
  804. //
  805. iRet = (-1);
  806. // The VT220 and VT320 key tables have user defined key tables
  807. // that have empty sequence entries in them, unless they have been
  808. // defined by the host. So, if they're empty, we're not going to
  809. // report them as keys that have been found.
  810. //
  811. for (idx = 0; idx < iMaxEntries; idx++, pstKey++)
  812. {
  813. if (pstKey->Key == Key && pstKey->iSequenceLen != 0)
  814. {
  815. iRet = idx;
  816. break;
  817. }
  818. }
  819. return iRet;
  820. }
  821. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  822. * emuDecSendKeyString
  823. *
  824. * DESCRIPTION:
  825. *
  826. * ARGUMENTS:
  827. *
  828. * RETURNS:
  829. * nothing
  830. */
  831. void emuDecSendKeyString(const HHEMU hhEmu, const int iIndex,
  832. PSTCEMUKEYDATA pstcKeyTbl, const int iMaxEntries)
  833. {
  834. PSTCEMUKEYDATA pstKeyData = pstcKeyTbl + iIndex;
  835. const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
  836. const int fUDK = (pstcKeyTbl == pstPRI->pstUDK) ? 1 : 0;
  837. int iLen;
  838. unsigned int iLeadByte;
  839. TCHAR * pchLeadChar = NULL;
  840. ECHAR str[80];
  841. if (pstcKeyTbl == 0)
  842. {
  843. assert(FALSE);
  844. return;
  845. }
  846. ECHAR_Fill(str, TEXT('\0'), sizeof(str)/sizeof(ECHAR));
  847. // If we are processing VT52 or VT100 keys, call the standard
  848. // send string function. The VT100 doesn't switch between 7 and 8
  849. // bit controls.
  850. //
  851. if (hhEmu->nEmuLoaded == EMU_VT100 || hhEmu->nEmuLoaded == EMU_VT52)
  852. {
  853. emuVT220SendKeyString(hhEmu, iIndex, pstcKeyTbl, iMaxEntries);
  854. return;
  855. }
  856. // 7-bit controls don't apply to the user defined sequences.
  857. // Also, because empty key sequences are defined in the User Defined
  858. // Key Table, it is possible that the key sequence value is NULL. So,
  859. // we'll process the User Defined Key here, checking the sequence
  860. // before we try to operate on it.
  861. //
  862. if (fUDK)
  863. {
  864. if (pstKeyData->pSequence)
  865. {
  866. emuVT220SendKeyString(hhEmu, iIndex, pstcKeyTbl, iMaxEntries);
  867. }
  868. return;
  869. }
  870. // If we are are sending 8 bit codes, process the key directly
  871. // from the key table, as usual.
  872. //
  873. if (hhEmu->fUse8BitCodes)
  874. {
  875. emuVT220SendKeyString(hhEmu, iIndex, pstcKeyTbl, iMaxEntries);
  876. return;
  877. }
  878. // If we are processing 7 bit codes, the first character in the
  879. // sequence defined in the key table will be replaced with its 7-bit
  880. // value, sometimes.
  881. //
  882. iLeadByte = *(pstKeyData->pSequence);
  883. switch(iLeadByte)
  884. {
  885. case 0x84:
  886. // Send Esc - D
  887. //
  888. pchLeadChar = TEXT("\x1B\x44\x00");
  889. break;
  890. case 0x8F:
  891. // Send Esc - O
  892. //
  893. pchLeadChar = TEXT("\x1B\x4F\x00");
  894. break;
  895. case 0x9B:
  896. // Send Esc - [
  897. //
  898. pchLeadChar = TEXT("\x1B\x5B\x00");
  899. break;
  900. default:
  901. // Send sequence as defined in the key table.
  902. //
  903. pchLeadChar = TEXT("\x00");
  904. break;
  905. }
  906. // If we are sending a 7-bit version of the sequence, it gets sent out
  907. // in two pieces, otherwise send the sequence as it is defined
  908. // in the key table.
  909. //
  910. if (*pchLeadChar)
  911. {
  912. CnvrtMBCStoECHAR(str, sizeof(str), pchLeadChar,
  913. StrCharGetByteCount(pchLeadChar));
  914. iLen = StrCharGetEcharByteCount(str);
  915. CnvrtMBCStoECHAR(&str[iLen], sizeof(str) - iLen,
  916. pstKeyData->pSequence + 1,
  917. StrCharGetByteCount(pstKeyData->pSequence + 1));
  918. emuSendString(hhEmu, str, StrCharGetEcharByteCount(str));
  919. }
  920. else
  921. {
  922. emuVT220SendKeyString(hhEmu, iIndex, pstcKeyTbl, iMaxEntries);
  923. }
  924. return;
  925. }
  926. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  927. * FUNCTION:
  928. * emuVT220SendKeyString
  929. *
  930. * DESCRIPTION:
  931. * Sends the specified string.
  932. *
  933. * This is a VT220 specific replacement for emuSendKeyString in emu.c. It's
  934. * the emuSendKeyString from \shared\emulator\emu.c.
  935. *
  936. * ARGUMENTS:
  937. * hhEmu - The internal emulator handle.
  938. * nIndex - Position of key in keytable array.
  939. * pstKeyTbl - Address of key strings table.
  940. *
  941. * RETURNS:
  942. * nothing
  943. *
  944. */
  945. void emuVT220SendKeyString(const HHEMU hhEmu,
  946. const int iIndex,
  947. PSTCEMUKEYDATA pstcKeyTbl,
  948. const int iMaxEntries)
  949. {
  950. ECHAR str[80];
  951. PSTCEMUKEYDATA pstKeyData = pstcKeyTbl + iIndex;
  952. memset(str, 0, sizeof(str));
  953. if (iIndex < 0 || iIndex >= iMaxEntries)
  954. {
  955. assert(FALSE);
  956. return;
  957. }
  958. pstKeyData = pstcKeyTbl + iIndex;
  959. #if defined(_DEBUG)
  960. DbgOutStr("%s", pstcKeyTbl[iIndex].pszKeyName, 0, 0, 0, 0);
  961. #endif
  962. if (pstKeyData->iSequenceLen > 0)
  963. {
  964. CnvrtMBCStoECHAR(str, sizeof(str), pstKeyData->pSequence,
  965. StrCharGetByteCount(pstKeyData->pSequence));
  966. emuSendString(hhEmu, str, StrCharGetEcharByteCount(str));
  967. }
  968. }
  969. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  970. * emuDecEL
  971. *
  972. * DESCRIPTION:
  973. * Erase In Line (EL). This control function erases characters from
  974. * part or all of the current line. When you erase complete lines, they
  975. * become single height and single width, with all character attributes
  976. * cleared.
  977. *
  978. * Selective Erase in Display (SED). This control function lets you
  979. * erase some or all of the erasable characters in the display. DECSED
  980. * cam only erase characters defined as erasable by the DECSCA control
  981. * function. A selective erase is controled by the DEC_private flag
  982. * in the emulator handle. This is dealt with in the lower level
  983. * function that does the actual erasing.
  984. *
  985. * ARGUMENTS:
  986. * hhEmu - The internal emulator handle.
  987. *
  988. * RETURNS:
  989. * nothing
  990. */
  991. void emuDecEL(const HHEMU hhEmu)
  992. {
  993. int iClearType;
  994. switch (hhEmu->selector[0])
  995. {
  996. case 0:
  997. case 0x0F:
  998. case 0xF0:
  999. if (hhEmu->emu_curcol == 0)
  1000. iClearType = CLEAR_ENTIRE_LINE;
  1001. else
  1002. iClearType = CLEAR_CURSOR_TO_LINE_END;
  1003. break;
  1004. case 1:
  1005. case 0xF1:
  1006. iClearType = CLEAR_LINE_START_TO_CURSOR;
  1007. break;
  1008. case 2:
  1009. case 0xF2:
  1010. iClearType = CLEAR_ENTIRE_LINE;
  1011. break;
  1012. default:
  1013. commanderror(hhEmu);
  1014. return;
  1015. }
  1016. emuDecClearLine(hhEmu, iClearType);
  1017. }
  1018. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1019. * FUNCTION:
  1020. * emuDecClearLine
  1021. *
  1022. * DESCRIPTION:
  1023. * Erases some or all of the virtual screen image.
  1024. *
  1025. * ARGUMENTS:
  1026. * HHEMU hhEmu - The internal emulator handle.
  1027. *
  1028. * int iClearSelect - CLEAR_CURSOR_TO_LINE_END 0
  1029. * - CLEAR_LINE_START_TO_CURSOR 1
  1030. * - CLEAR_ENTIRE_LINE 2
  1031. *
  1032. *
  1033. * RETURNS:
  1034. * nothing
  1035. *
  1036. */
  1037. void emuDecClearLine(const HHEMU hhEmu, const int iClearSelect)
  1038. {
  1039. register int iCurrentImgRow, iCol;
  1040. ECHAR * pechText = 0;
  1041. PSTATTR pstCell = 0;
  1042. const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
  1043. iCurrentImgRow = row_index(hhEmu, hhEmu->emu_currow);
  1044. pstCell = hhEmu->emu_apAttr[iCurrentImgRow];
  1045. pechText = hhEmu->emu_apText[iCurrentImgRow];
  1046. switch (iClearSelect)
  1047. {
  1048. case CLEAR_CURSOR_TO_LINE_END:
  1049. // Clear the current line from the current cursor position
  1050. // through the end of the user's maximum screen width.
  1051. //
  1052. for(iCol = hhEmu->emu_curcol; iCol <= hhEmu->emu_maxcol; iCol++)
  1053. {
  1054. // If we're in DEC private mode and the character is
  1055. // protected, don't do anything with it.
  1056. //
  1057. if (hhEmu->DEC_private && pstCell[iCol].protect)
  1058. {
  1059. continue;
  1060. }
  1061. // OK, clear the character and it's attribute at this column
  1062. // location.
  1063. //
  1064. pechText[iCol] = (ECHAR)EMU_BLANK_CHAR;
  1065. pstCell[iCol] = hhEmu->emu_clearattr;
  1066. }
  1067. // Adjust the array that contains the column number of the last
  1068. // character in this row.
  1069. //
  1070. if (hhEmu->emu_curcol <= hhEmu->emu_aiEnd[iCurrentImgRow])
  1071. {
  1072. hhEmu->emu_aiEnd[iCurrentImgRow] = max(hhEmu->emu_curcol - 1, 0);
  1073. }
  1074. break;
  1075. case CLEAR_LINE_START_TO_CURSOR:
  1076. // Clear the range from the beginning of the line, through the
  1077. // current cursor position.
  1078. //
  1079. for(iCol = 0; iCol <= hhEmu->emu_curcol; iCol++)
  1080. {
  1081. // If we're in DEC private mode and the character is
  1082. // protected, don't do anything with it.
  1083. //
  1084. if (hhEmu->DEC_private && pstCell[iCol].protect)
  1085. {
  1086. continue;
  1087. }
  1088. // OK, clear the character and it's attribute at this column
  1089. // location.
  1090. //
  1091. pechText[iCol] = (ECHAR)EMU_BLANK_CHAR;
  1092. pstCell[iCol] = hhEmu->emu_clearattr;
  1093. }
  1094. // Adjust the array value that contains the column number
  1095. // of the last character in this row.
  1096. //
  1097. if (hhEmu->emu_curcol >= hhEmu->emu_aiEnd[iCurrentImgRow])
  1098. {
  1099. hhEmu->emu_aiEnd[iCurrentImgRow] = EMU_BLANK_LINE;
  1100. }
  1101. break;
  1102. case CLEAR_ENTIRE_LINE:
  1103. // The entire line needs to be cleared, but we only want
  1104. // to put the user defined size of the emulator into the
  1105. // backscroll buffer.
  1106. //
  1107. backscrlAdd(sessQueryBackscrlHdl(hhEmu->hSession),
  1108. pechText, hhEmu->emu_maxcol + 1);
  1109. if (hhEmu->DEC_private)
  1110. emuDecClearImageRowSelective(hhEmu, hhEmu->emu_currow);
  1111. else
  1112. clear_imgrow(hhEmu, hhEmu->emu_currow);
  1113. pstPRI->aiLineAttr[iCurrentImgRow] = NO_LINE_ATTR;
  1114. break;
  1115. default:
  1116. commanderror(hhEmu);
  1117. }
  1118. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, hhEmu->emu_curcol);
  1119. // Added a global to save the clear attribute at the time of
  1120. // notification. This is necessary since the message is posted
  1121. // and a race condition can develop.
  1122. //
  1123. hhEmu->emu_clearattr_sav = hhEmu->emu_clearattr;
  1124. updateLine(sessQueryUpdateHdl(hhEmu->hSession), 0, hhEmu->emu_currow);
  1125. }
  1126. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1127. * emuVT220ED
  1128. *
  1129. * DESCRIPTION:
  1130. * Erase In Display (ED). This control function erases characters from
  1131. * part or all of the display. When you erase complete lines, they
  1132. * become single height and single width, with all character attributes
  1133. * cleared.
  1134. *
  1135. * Selective Erase in Display (SED). This control function lets you
  1136. * erase some or all of the erasable characters in the display. DECSED
  1137. * cam only erase characters defined as erasable by the DECSCA control
  1138. * function. A selective erase is controled by the DEC_private flag
  1139. * in the emulator handle. This is dealt with in the lower level
  1140. * function that does the actual erasing.
  1141. *
  1142. * ARGUMENTS:
  1143. * hhEmu - The internal emulator handle.
  1144. *
  1145. * RETURNS:
  1146. * nothing
  1147. */
  1148. void emuVT220ED(const HHEMU hhEmu)
  1149. {
  1150. int iClearType;
  1151. switch (hhEmu->selector[0])
  1152. {
  1153. case 0:
  1154. case 0x0F:
  1155. case 0xF0:
  1156. if (hhEmu->emu_currow == 0 && hhEmu->emu_curcol == 0)
  1157. iClearType = CLEAR_ENTIRE_SCREEN;
  1158. else
  1159. iClearType = CLEAR_CURSOR_TO_SCREEN_END;
  1160. break;
  1161. case 1:
  1162. case 0xF1:
  1163. iClearType = CLEAR_SCREEN_START_TO_CURSOR;
  1164. break;
  1165. case 2:
  1166. case 0xF2:
  1167. iClearType = CLEAR_ENTIRE_SCREEN;
  1168. break;
  1169. default:
  1170. commanderror(hhEmu);
  1171. return;
  1172. }
  1173. emuDecEraseScreen(hhEmu, iClearType);
  1174. }
  1175. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1176. * FUNCTION:
  1177. * emuDecEraseScreen
  1178. *
  1179. * DESCRIPTION:
  1180. * Erases some or all of the virtual screen image.
  1181. *
  1182. * ARGUMENTS:
  1183. * HHEMU hhEmu - The internal emulator handle.
  1184. *
  1185. * int iClearSelect - CLEAR_CURSOR_TO_SCREEN_END 0
  1186. * - CLEAR_SCREEN_START_TO_CURSOR 1
  1187. * - CLEAR_ENTIRE_SCREEN 2
  1188. *
  1189. *
  1190. * RETURNS:
  1191. * nothing
  1192. *
  1193. */
  1194. void emuDecEraseScreen(const HHEMU hhEmu, const int iClearSelect)
  1195. {
  1196. register int iRow;
  1197. int trow,
  1198. iStartRow, iEndRow,
  1199. tcol,
  1200. iVirtualRow,
  1201. iLineLen;
  1202. ECHAR aechBuf[10];
  1203. ECHAR * pechText = 0;
  1204. PSTATTR pstCell = 0;
  1205. const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
  1206. trow = hhEmu->emu_currow;
  1207. tcol = hhEmu->emu_curcol;
  1208. switch (iClearSelect)
  1209. {
  1210. case CLEAR_CURSOR_TO_SCREEN_END:
  1211. // Note that the calling function (emuDecED) changes iClearSelect
  1212. // to CLEAR_ENTIRE_SCREEN if CLEAR_CURSOR_TO_SCREEN_END was
  1213. // issued with a current cursor position at (0,0). Clearing
  1214. // the entire screen pushes the screen image into the backscroll
  1215. // buffer, the capture file, and to the printer. Anything less
  1216. // than that simply gets cleared from the display. Now...
  1217. // Clear the range from one line below the current cursor position
  1218. // through the end of the user's maximum screen size.
  1219. //
  1220. for (iRow = hhEmu->emu_currow + 1; iRow <= hhEmu->emu_maxrow; iRow++)
  1221. {
  1222. if (hhEmu->DEC_private)
  1223. emuDecClearImageRowSelective(hhEmu, iRow);
  1224. else
  1225. clear_imgrow(hhEmu, iRow);
  1226. }
  1227. // Now clear the characters and attributes from the partial
  1228. // row that the cursor was on.
  1229. //
  1230. emuDecClearLine(hhEmu, CLEAR_CURSOR_TO_LINE_END);
  1231. // Identify the range of line attributes that need to be cleared,
  1232. // and clear them.
  1233. //
  1234. if (hhEmu->emu_curcol == 0)
  1235. iStartRow = hhEmu->emu_currow;
  1236. else
  1237. iStartRow = hhEmu->emu_currow + 1;
  1238. iStartRow = min(iStartRow, hhEmu->emu_maxrow);
  1239. iEndRow = hhEmu->emu_maxrow;
  1240. if (iStartRow >= 0)
  1241. {
  1242. for(iRow = iStartRow; iRow <= iEndRow; iRow++)
  1243. pstPRI->aiLineAttr[iRow] = NO_LINE_ATTR;
  1244. }
  1245. // Finally, update the image.
  1246. //
  1247. updateScroll(sessQueryUpdateHdl(hhEmu->hSession),
  1248. 0,
  1249. hhEmu->emu_maxrow,
  1250. hhEmu->emu_maxrow + 1,
  1251. hhEmu->emu_imgtop,
  1252. TRUE);
  1253. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, hhEmu->emu_curcol);
  1254. // Added a global to save the clear attribute at the time of
  1255. // notification. This is necessary since the message is posted
  1256. // and a race condition can develop.
  1257. //
  1258. hhEmu->emu_clearattr_sav = hhEmu->emu_clearattr;
  1259. NotifyClient(hhEmu->hSession, EVENT_EMU_CLRATTR, 0);
  1260. break;
  1261. case CLEAR_SCREEN_START_TO_CURSOR:
  1262. // Clear the range from the first row, to one row above the
  1263. // current cursor position.
  1264. //
  1265. for (iRow = 0; iRow < hhEmu->emu_currow; iRow++)
  1266. {
  1267. if (hhEmu->DEC_private)
  1268. emuDecClearImageRowSelective(hhEmu, iRow);
  1269. else
  1270. clear_imgrow(hhEmu, iRow);
  1271. }
  1272. // Now clear the partial (current) row.
  1273. //
  1274. emuDecClearLine(hhEmu, CLEAR_LINE_START_TO_CURSOR);
  1275. // Identify the range of line attributes that need to be cleared,
  1276. // and clear them.
  1277. //
  1278. iStartRow = 0;
  1279. if (hhEmu->emu_curcol == hhEmu->emu_maxcol)
  1280. iEndRow = hhEmu->emu_currow;
  1281. else
  1282. iEndRow = hhEmu->emu_currow - 1;
  1283. iEndRow = max(iEndRow, 0);
  1284. if (iStartRow >= 0)
  1285. {
  1286. for(iRow = iStartRow; iRow <= iEndRow; iRow++)
  1287. pstPRI->aiLineAttr[iRow] = NO_LINE_ATTR;
  1288. }
  1289. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow, hhEmu->emu_curcol);
  1290. updateLine(sessQueryUpdateHdl(hhEmu->hSession), 0, hhEmu->emu_currow);
  1291. break;
  1292. case CLEAR_ENTIRE_SCREEN:
  1293. // The entire buffer needs to be cleared, but we only want
  1294. // to put the user defined size of the emualtor into the
  1295. // backscroll buffer, capture file and print file.
  1296. //
  1297. for (iRow = 0; iRow < MAX_EMUROWS; iRow++)
  1298. {
  1299. if (iRow <= hhEmu->emu_maxrow)
  1300. {
  1301. iVirtualRow = row_index(hhEmu, iRow);
  1302. iLineLen = emuRowLen(hhEmu, iVirtualRow);
  1303. pechText = hhEmu->emu_apText[iVirtualRow];
  1304. backscrlAdd(sessQueryBackscrlHdl(hhEmu->hSession),
  1305. pechText, iLineLen);
  1306. CaptureLine(sessQueryCaptureFileHdl(hhEmu->hSession),
  1307. CF_CAP_SCREENS, pechText, iLineLen);
  1308. printEchoScreen(hhEmu->hPrintEcho, pechText, iVirtualRow);
  1309. CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), TEXT("\r\n"),
  1310. StrCharGetByteCount(TEXT("\r\n")));
  1311. printEchoScreen(hhEmu->hPrintEcho, aechBuf, sizeof(ECHAR) * 2);
  1312. if (hhEmu->DEC_private)
  1313. emuDecClearImageRowSelective(hhEmu, iRow);
  1314. else
  1315. clear_imgrow(hhEmu, iRow);
  1316. }
  1317. else
  1318. {
  1319. clear_imgrow(hhEmu, iRow);
  1320. }
  1321. pstPRI->aiLineAttr[iRow] = NO_LINE_ATTR;
  1322. }
  1323. // Scroll the imgae.
  1324. //
  1325. updateScroll(sessQueryUpdateHdl(hhEmu->hSession),
  1326. 0,
  1327. hhEmu->emu_maxrow,
  1328. hhEmu->emu_maxrow + 1,
  1329. hhEmu->emu_imgtop,
  1330. TRUE);
  1331. // Added a global to save the clear attribute at the time of
  1332. // notification. This is necessary since the message is posted
  1333. // and a race condition can develop.
  1334. hhEmu->emu_clearattr_sav = hhEmu->emu_clearattr;
  1335. NotifyClient(hhEmu->hSession, EVENT_EMU_CLRATTR, 0);
  1336. break;
  1337. default:
  1338. commanderror(hhEmu);
  1339. }
  1340. (*hhEmu->emu_setcurpos)(hhEmu, trow, tcol);
  1341. }
  1342. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1343. * FUNCTION:
  1344. * emuDecClearImageRowSelective
  1345. *
  1346. * DESCRIPTION:
  1347. * This function clears the characters and attributes from the supplied
  1348. * row, taking into account the protected bit in the character
  1349. * attributes. It only clears those characters that are NOT protected.
  1350. *
  1351. * ARGUMENTS:
  1352. * HHEMU hhEmu - The internal emulator handle.
  1353. *
  1354. * int iRow - The row to clear.
  1355. *
  1356. * RETURNS:
  1357. * nothing
  1358. */
  1359. void emuDecClearImageRowSelective(const HHEMU hhEmu, const int iImageRow)
  1360. {
  1361. register int i, iRow;
  1362. ECHAR *pechText = 0;
  1363. PSTATTR pstCell = 0;
  1364. iRow = row_index(hhEmu, iImageRow);
  1365. pstCell = hhEmu->emu_apAttr[iRow];
  1366. pechText = hhEmu->emu_apText[iRow];
  1367. // Clear only the characters (and attributes) of the non-protected
  1368. // characters.
  1369. //
  1370. for (i = 0; i < MAX_EMUCOLS; i++)
  1371. {
  1372. if ( pstCell[i].protect == 0 )
  1373. {
  1374. pstCell[i] = hhEmu->emu_clearattr;
  1375. pechText[i] = EMU_BLANK_CHAR;
  1376. }
  1377. if (pechText[i] != EMU_BLANK_CHAR)
  1378. hhEmu->emu_aiEnd[iRow] = i;
  1379. }
  1380. return;
  1381. }
  1382. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1383. * emuDecUnload
  1384. *
  1385. * DESCRIPTION:
  1386. * Unloads current emulator by freeing used memory.
  1387. *
  1388. * ARGUMENTS:
  1389. * none
  1390. *
  1391. * RETURNS:
  1392. * nothing
  1393. */
  1394. void emuDecUnload(const HHEMU hhEmu)
  1395. {
  1396. const PSTDECPRIVATE pstPRI = (PSTDECPRIVATE)hhEmu->pvPrivate;
  1397. PSTEMUKEYDATA pstKey = pstPRI->pstUDK;
  1398. int idx;
  1399. if (pstPRI)
  1400. {
  1401. // Clear the line attribute array.
  1402. //
  1403. if (pstPRI->aiLineAttr)
  1404. {
  1405. free(pstPRI->aiLineAttr);
  1406. pstPRI->aiLineAttr = 0;
  1407. }
  1408. // Cycle through the user defined key table and free
  1409. // any memory that may have been allocated for sequences.
  1410. //
  1411. if (pstKey)
  1412. {
  1413. for (idx = 0; idx < MAX_UDK_KEYS; idx++, pstKey++)
  1414. {
  1415. if (pstKey->iSequenceLen != 0)
  1416. {
  1417. free(pstKey->pSequence);
  1418. pstKey->iSequenceLen = 0;
  1419. }
  1420. }
  1421. }
  1422. free(pstPRI);
  1423. //pstPRI = NULL; //mpt:12-21-98 cannot modify a const object
  1424. hhEmu->pvPrivate = NULL;
  1425. }
  1426. return;
  1427. }
  1428. #endif // INCL_VT220
  1429. /* end of VT220.C */