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.

1367 lines
30 KiB

  1. /* File: D:\WACKER\emu\minitelf.c (Created: 12-Apr-1994)
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 1 $
  7. * $Date: 10/05/98 12:28p $
  8. */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. #include <tdll\stdtyp.h>
  12. #include <tdll\tdll.h>
  13. #include <tdll\session.h>
  14. #include <tdll\print.h>
  15. #include <tdll\capture.h>
  16. #include <tdll\assert.h>
  17. #include <tdll\mc.h>
  18. #include <tdll\update.h>
  19. #include "emu.h"
  20. #include "emu.hh"
  21. #include "emuid.h"
  22. #include "minitel.hh"
  23. static void minitel_clear_imgrow(const HHEMU hhEmu, const int row);
  24. #if defined(INCL_MINITEL)
  25. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  26. * FUNCTION:
  27. * minitelLinefeed
  28. *
  29. * DESCRIPTION:
  30. * Linefeeds work differently in minitel. In page mode we wrap to line
  31. * one (not zero) when at the bottom.
  32. *
  33. * ARGUMENTS:
  34. * hhEmu - private emulator handle.
  35. *
  36. * RETURNS:
  37. * void
  38. *
  39. */
  40. void minitelLinefeed(const HHEMU hhEmu)
  41. {
  42. const PSTMTPRIVATE pstPRI = hhEmu->pvPrivate;
  43. const ECHAR *tp = hhEmu->emu_apText[hhEmu->emu_imgrow];
  44. const PSTATTR ap = hhEmu->emu_apAttr[hhEmu->emu_imgrow];
  45. printEchoString(hhEmu->hPrintEcho, (ECHAR *)tp,
  46. emuRowLen(hhEmu, hhEmu->emu_currow)); // mrw,3/1/95
  47. // see page 97, bottom of page
  48. //
  49. if (hhEmu->emu_currow == 0)
  50. {
  51. hhEmu->emu_charattr = pstPRI->minitel_saved_attr;
  52. (*hhEmu->emu_setcurpos)(hhEmu, pstPRI->minitel_saved_row,
  53. pstPRI->minitel_saved_col);
  54. pstPRI->minitelG1Active = pstPRI->minitel_saved_minitelG1Active;
  55. pstPRI->stLatentAttr = pstPRI->saved_stLatentAttr;
  56. pstPRI->minitelUseSeparatedMosaics =
  57. pstPRI->saved_minitelUseSeparatedMosaics;
  58. }
  59. else if (hhEmu->emu_currow == hhEmu->bottom_margin)
  60. {
  61. if (pstPRI->fScrollMode)
  62. minitel_scrollup(hhEmu, 1);
  63. else
  64. (*hhEmu->emu_setcurpos)(hhEmu, 1, hhEmu->emu_curcol);
  65. }
  66. else
  67. {
  68. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow + 1,
  69. hhEmu->emu_curcol);
  70. }
  71. return;
  72. }
  73. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  74. * FUNCTION:
  75. * minitelBackspace
  76. *
  77. * DESCRIPTION:
  78. * Backspaces are goofy. They wrap to the previous line. In scroll mode
  79. * they cause scrolling if in line 1
  80. *
  81. * ARGUMENTS:
  82. * void
  83. *
  84. * RETURNS:
  85. * void
  86. *
  87. */
  88. void minitelBackspace(const HHEMU hhEmu)
  89. {
  90. const PSTMTPRIVATE pstPRI = hhEmu->pvPrivate;
  91. if (hhEmu->emu_curcol > 0)
  92. {
  93. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow,
  94. hhEmu->emu_curcol-1);
  95. }
  96. else if (hhEmu->emu_currow == 1)
  97. {
  98. if (pstPRI->fScrollMode)
  99. {
  100. minitel_scrolldown(hhEmu, (hhEmu->emu_charattr.dblhilo) ? 2 : 1);
  101. }
  102. else
  103. {
  104. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_maxrow,
  105. hhEmu->emu_maxcol);
  106. }
  107. }
  108. else
  109. {
  110. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow-1,
  111. hhEmu->emu_maxcol);
  112. }
  113. return;
  114. }
  115. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  116. * FUNCTION:
  117. * minitelVerticalTab
  118. *
  119. * DESCRIPTION:
  120. * Vertical tabs work differently. They move the cursor up and wrap or
  121. * scroll depending on the mode.
  122. *
  123. * ARGUMENTS:
  124. * void
  125. *
  126. * RETURNS:
  127. * void
  128. *
  129. */
  130. void minitelVerticalTab(const HHEMU hhEmu)
  131. {
  132. const PSTMTPRIVATE pstPRI = hhEmu->pvPrivate;
  133. // VT sequence not available in row 0
  134. //
  135. if (hhEmu->emu_currow == 0)
  136. return;
  137. if (hhEmu->emu_currow == 1)
  138. {
  139. if (pstPRI->fScrollMode)
  140. {
  141. minitel_scrolldown(hhEmu, (hhEmu->emu_charattr.dblhilo) ? 2 : 1);
  142. }
  143. else
  144. {
  145. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_maxrow,
  146. hhEmu->emu_curcol);
  147. }
  148. }
  149. else
  150. {
  151. (*hhEmu->emu_setcurpos)(hhEmu, hhEmu->emu_currow-1,
  152. hhEmu->emu_curcol);
  153. }
  154. return;
  155. }
  156. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  157. * FUNCTION:
  158. * minitelCursorUp
  159. *
  160. * DESCRIPTION:
  161. * Moves cursor up n rows but not into row 00
  162. *
  163. * ARGUMENTS:
  164. * void
  165. *
  166. * RETURNS:
  167. * void
  168. *
  169. */
  170. void minitelCursorUp(const HHEMU hhEmu)
  171. {
  172. int nlines, row;
  173. // CSI sequences not available in row 0
  174. //
  175. if (hhEmu->emu_currow == 0)
  176. return;
  177. nlines = hhEmu->num_param[hhEmu->num_param_cnt];
  178. if (nlines < 1)
  179. nlines = 1;
  180. row = hhEmu->emu_currow;
  181. row -= nlines;
  182. if (row < 1)
  183. row = 1;
  184. (*hhEmu->emu_setcurpos)(hhEmu, row, hhEmu->emu_curcol);
  185. ANSI_Pn_Clr(hhEmu);
  186. return;
  187. }
  188. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  189. * FUNCTION:
  190. * minitelCursorDirect
  191. *
  192. * DESCRIPTION:
  193. * Moves cursor to specified coordinates but not row 00
  194. *
  195. * ARGUMENTS:
  196. * void
  197. *
  198. * RETURNS:
  199. * void
  200. *
  201. */
  202. void minitelCursorDirect(const HHEMU hhEmu)
  203. {
  204. int row, col;
  205. // CSI functions not available in row 0
  206. //
  207. if (hhEmu->emu_currow == 0)
  208. return;
  209. row = hhEmu->num_param[0];
  210. col = hhEmu->num_param_cnt > 0 ? hhEmu->num_param[1] : 0;
  211. if (row < 1)
  212. row = 1;
  213. if (col < 1)
  214. col = 1;
  215. if (row > hhEmu->emu_maxrow + 1)
  216. row = hhEmu->emu_maxrow + 1;
  217. if (col > hhEmu->emu_maxcol + 1)
  218. col = hhEmu->emu_maxcol + 1;
  219. // Again, can't go to row 00 with this call.
  220. (*hhEmu->emu_setcurpos)(hhEmu, row, col - 1);
  221. ANSI_Pn_Clr(hhEmu);
  222. return;
  223. }
  224. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  225. * FUNCTION:
  226. * minitelFormFeed
  227. *
  228. * DESCRIPTION:
  229. * Clears rows 1 thru 24 leaving row 00 alone.
  230. *
  231. * ARGUMENTS:
  232. * void
  233. *
  234. * RETURNS:
  235. * void
  236. *
  237. */
  238. void minitelFormFeed(const HHEMU hhEmu)
  239. {
  240. (*hhEmu->emu_setcurpos)(hhEmu, 1, 0);
  241. minitelClearScreen(hhEmu, 0);
  242. minitelReset(hhEmu);
  243. return;
  244. }
  245. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  246. * FUNCTION:
  247. * minitelClearScreen
  248. *
  249. * DESCRIPTION:
  250. * Works similar to the standard function but also has to clear the
  251. * latent attribute and all serial attributes.
  252. *
  253. * ARGUMENTS:
  254. * int iHow - dirction to clear screen.
  255. *
  256. * RETURNS:
  257. * void
  258. *
  259. */
  260. void minitelClearScreen(const HHEMU hhEmu, const int iHow)
  261. {
  262. #define BLACK_MOSAIC ETEXT('\xff')
  263. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  264. int i;
  265. int r;
  266. PSTMINITEL pstMT;
  267. STMINITEL stMT;
  268. ECHAR *pText;
  269. PSTATTR pstAttr;
  270. STATTR stAttr;
  271. // CSI sequences not available in row 0
  272. //
  273. if (hhEmu->emu_currow == 0)
  274. return;
  275. memset(&stMT, 0, sizeof(stMT));
  276. stMT.ismosaic = 1;
  277. memset(&stAttr, 0, sizeof(stAttr));
  278. stAttr.txtclr = VC_BRT_WHITE;
  279. stAttr.bkclr = VC_BLACK;
  280. switch (iHow)
  281. {
  282. case 0: // cursor to end of screen inclusive
  283. default:
  284. pstMT = pstPRI->apstMT[hhEmu->emu_imgrow];
  285. pText = hhEmu->emu_apText[hhEmu->emu_imgrow];
  286. pstAttr = hhEmu->emu_apAttr[hhEmu->emu_imgrow];
  287. for (i = hhEmu->emu_curcol ; i < MAX_EMUCOLS ; ++i)
  288. {
  289. *pstMT++ = stMT;
  290. *pText++ = BLACK_MOSAIC;
  291. *pstAttr++ = stAttr;
  292. }
  293. for (r = hhEmu->emu_currow+1 ; r < MAX_EMUROWS ; ++r)
  294. {
  295. i = row_index(hhEmu, r);
  296. pstMT = pstPRI->apstMT[i];
  297. pText = hhEmu->emu_apText[i];
  298. pstAttr = hhEmu->emu_apAttr[i];
  299. for (i = 0 ; i < MAX_EMUCOLS ; ++i)
  300. {
  301. *pstMT++ = stMT;
  302. *pText++ = BLACK_MOSAIC;
  303. *pstAttr++ = stAttr;
  304. }
  305. }
  306. updateLine(sessQueryUpdateHdl(hhEmu->hSession), hhEmu->emu_currow,
  307. hhEmu->emu_maxrow);
  308. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_curcol;
  309. break;
  310. case 1: // beginning of screen to cursor inclusive
  311. for (r = 1 ; r < hhEmu->emu_currow ; ++r)
  312. {
  313. i = row_index(hhEmu, r);
  314. pstMT = pstPRI->apstMT[i];
  315. pText = hhEmu->emu_apText[i];
  316. pstAttr = hhEmu->emu_apAttr[i];
  317. for (i = 0 ; i < MAX_EMUCOLS ; ++i)
  318. {
  319. *pstMT++ = stMT;
  320. *pText++ = BLACK_MOSAIC;
  321. *pstAttr++ = stAttr;
  322. }
  323. }
  324. pstMT = pstPRI->apstMT[hhEmu->emu_imgrow];
  325. pText = hhEmu->emu_apText[hhEmu->emu_imgrow];
  326. pstAttr = hhEmu->emu_apAttr[hhEmu->emu_imgrow];
  327. for (i = 0 ; i <= hhEmu->emu_curcol ; ++i)
  328. {
  329. *pstMT++ = stMT;
  330. *pText++ = BLACK_MOSAIC;
  331. *pstAttr++ = stAttr;
  332. }
  333. updateLine(sessQueryUpdateHdl(hhEmu->hSession),
  334. 0, hhEmu->emu_currow);
  335. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_curcol + 1;
  336. break;
  337. case 2: // entire screen (cursor position not changed)
  338. for (r = 1 ; r < MAX_EMUROWS ; ++r)
  339. {
  340. i = row_index(hhEmu, r);
  341. pstMT = pstPRI->apstMT[i];
  342. pText = hhEmu->emu_apText[i];
  343. pstAttr = hhEmu->emu_apAttr[i];
  344. hhEmu->emu_aiEnd[r] = EMU_BLANK_LINE;
  345. for (i = 0 ; i < MAX_EMUCOLS ; ++i)
  346. {
  347. *pstMT++ = stMT;
  348. *pText++ = BLACK_MOSAIC;
  349. *pstAttr++ = stAttr;
  350. }
  351. }
  352. updateLine(sessQueryUpdateHdl(hhEmu->hSession),
  353. 0, hhEmu->emu_maxrow);
  354. break;
  355. }
  356. minitelRecordSeparator(hhEmu);
  357. return;
  358. }
  359. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  360. * FUNCTION:
  361. * minitelClrScrn
  362. *
  363. * DESCRIPTION:
  364. * Front end for minitelClearScreen() that reads the PSN argument,
  365. * converts it, and passes it to minitelClearScreen. Called from
  366. * the state tables.
  367. *
  368. * ARGUMENTS:
  369. * void
  370. *
  371. * RETURNS:
  372. * void
  373. *
  374. */
  375. void minitelClrScrn(const HHEMU hhEmu)
  376. {
  377. minitelClearScreen(hhEmu, hhEmu->selector[0]);
  378. return;
  379. }
  380. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  381. * FUNCTION:
  382. * minitelRecordSepartor
  383. *
  384. * DESCRIPTION:
  385. * Record Separtor has special duties in Minitel. In general it homes
  386. * the cursor and returns the emulator to what's called an SI condition.
  387. *
  388. * ARGUMENTS:
  389. * void
  390. *
  391. * RETURNS:
  392. * void
  393. *
  394. */
  395. void minitelRecordSeparator(const HHEMU hhEmu)
  396. {
  397. (*hhEmu->emu_setcurpos)(hhEmu, 1, 0);
  398. minitelReset(hhEmu);
  399. return;
  400. }
  401. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  402. * FUNCTION:
  403. * minitelClearLine
  404. *
  405. * DESCRIPTION:
  406. * Handles the various clear line functions like cursor to end, beg to
  407. * cursor, etc.
  408. *
  409. * ARGUMENTS:
  410. * void
  411. *
  412. * RETURNS:
  413. * void
  414. *
  415. */
  416. void minitelClearLine(const HHEMU hhEmu, const int iHow)
  417. {
  418. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  419. int i;
  420. ECHAR *pText = hhEmu->emu_apText[hhEmu->emu_imgrow];
  421. PSTMINITEL pstMT = pstPRI->apstMT[hhEmu->emu_imgrow];
  422. PSTATTR pstAttr = hhEmu->emu_apAttr[hhEmu->emu_imgrow];
  423. const HUPDATE hUpdate= sessQueryUpdateHdl(hhEmu->hSession);
  424. STMINITEL stMT;
  425. STATTR stAttr;
  426. // CSI sequences not available in row 0
  427. //
  428. if (hhEmu->emu_currow == 0)
  429. return;
  430. memset(&stMT, 0, sizeof(stMT));
  431. stMT.ismosaic = 1;
  432. memset(&stAttr, 0, sizeof(stAttr));
  433. stAttr.txtclr = VC_BRT_WHITE;
  434. stAttr.bkclr = VC_BLACK;
  435. switch (iHow)
  436. {
  437. case 0: // cursor to end of line inclusive
  438. default:
  439. for (i = hhEmu->emu_curcol ; i < MAX_EMUCOLS ; ++i)
  440. {
  441. *pText++ = BLACK_MOSAIC;
  442. *pstMT++ = stMT;
  443. *pstAttr++ = stAttr;
  444. }
  445. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_curcol - 1;
  446. updateChar(hUpdate, hhEmu->emu_currow,
  447. hhEmu->emu_curcol, MAX_EMUCOLS);
  448. break;
  449. case 1: // beginning of line to cursor inclusive
  450. for (i = 0 ; i <= hhEmu->emu_curcol ; ++i)
  451. {
  452. *pText++ = BLACK_MOSAIC;
  453. *pstMT++ = stMT;
  454. *pstAttr++ = stAttr;
  455. }
  456. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_curcol + 1;
  457. updateChar(hUpdate, hhEmu->emu_currow, 0, hhEmu->emu_curcol);
  458. break;
  459. case 2: // entire line
  460. for (i = 0 ; i < MAX_EMUCOLS ; ++i)
  461. {
  462. *pText++ = BLACK_MOSAIC;
  463. *pstMT++ = stMT;
  464. *pstAttr++ = stAttr;
  465. }
  466. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = EMU_BLANK_LINE;
  467. updateLine(hUpdate, hhEmu->emu_currow, hhEmu->emu_currow);
  468. break;
  469. }
  470. return;
  471. }
  472. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  473. * FUNCTION:
  474. * minitelClrLn
  475. *
  476. * DESCRIPTION:
  477. * Driver for minitelClearLine().
  478. *
  479. * ARGUMENTS:
  480. * void
  481. *
  482. * RETURNS:
  483. * void
  484. *
  485. */
  486. void minitelClrLn(const HHEMU hhEmu)
  487. {
  488. minitelClearLine(hhEmu, hhEmu->selector[0]);
  489. return;
  490. }
  491. #if 0
  492. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  493. * FUNCTION:
  494. * minitelDel
  495. *
  496. * DESCRIPTION:
  497. * code 0x7F (Del) deletes the cursor location and moves the cursor
  498. * one position right.
  499. *
  500. * ARGUMENTS:
  501. * void
  502. *
  503. * RETURNS:
  504. * void
  505. *
  506. */
  507. void minitelDel(const HHEMU hhEmu)
  508. {
  509. hhEmu->emu_apText[hhEmu->emu_imgrow][hhEmu->emu_curcol] = ETEXT('\x5F');
  510. hhEmu->emu_ap
  511. if (hhEmu->emu_aiEnd[hhEmu->emu_imgrow] == hhEmu->emu_curcol)
  512. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_curcol - 1;
  513. minitelHorzTab(hhEmu);
  514. return;
  515. }
  516. #endif
  517. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  518. * FUNCTION:
  519. * minitelHorzTab
  520. *
  521. * DESCRIPTION:
  522. * minitel cursor has some special characteristics. Minitel is always
  523. * in wrap mode, so we wrap to begining of next row when beyond the
  524. * last column. Also, when at bottom, wrap to line 1. Also, if in
  525. * row 0, column 40, ignore.
  526. *
  527. * ARGUMENTS:
  528. * void
  529. *
  530. * RETURNS:
  531. * void
  532. *
  533. */
  534. void minitelHorzTab(const HHEMU hhEmu)
  535. {
  536. int row = hhEmu->emu_currow;
  537. int col = hhEmu->emu_curcol;
  538. if (col >= hhEmu->emu_maxcol)
  539. {
  540. if (hhEmu->emu_currow == 0)
  541. return;
  542. if (hhEmu->emu_currow >= hhEmu->emu_maxrow)
  543. row = 1;
  544. else
  545. row += 1;
  546. col = 0;
  547. }
  548. else
  549. {
  550. col += 1;
  551. }
  552. (*hhEmu->emu_setcurpos)(hhEmu, row, col);
  553. return;
  554. }
  555. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  556. * FUNCTION:
  557. * minitelRepeat
  558. *
  559. * DESCRIPTION:
  560. * Repeat code displays the last displayed character x number of
  561. * times where x is the current emu_code coming in.
  562. * I don't think wrapping is effective here.
  563. *
  564. * ARGUMENTS:
  565. * void
  566. *
  567. * RETURNS:
  568. * void
  569. *
  570. */
  571. void minitelRepeat(const HHEMU hhEmu)
  572. {
  573. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  574. int x;
  575. // Already did range checking in state table to get here.
  576. // Repeat number is only the first six significant bits.
  577. x = max(0, hhEmu->emu_code-0x40);
  578. hhEmu->emu_code = pstPRI->minitel_last_char;
  579. while (x-- > 0)
  580. minitelGraphic(hhEmu);
  581. return;
  582. }
  583. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  584. * FUNCTION:
  585. * minitelCancel
  586. *
  587. * DESCRIPTION:
  588. * Fills current row from cursor position to end of row with spaces
  589. * in the current character set current attributes. Cursor doesn't move.
  590. * Doco says this is not a delimiter.
  591. *
  592. * ARGUMENTS:
  593. * void
  594. *
  595. * RETURNS:
  596. * void
  597. *
  598. */
  599. void minitelCancel(const HHEMU hhEmu)
  600. {
  601. int i;
  602. int iMax;
  603. int fModified;
  604. const int row = hhEmu->emu_currow;
  605. const int col = hhEmu->emu_curcol;
  606. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  607. hhEmu->emu_code = ETEXT('\x20');
  608. // Ah, the life of the undocumented. The documentation says
  609. // that this guys does not validate, colors, act as a delimiter
  610. // and fills with spaces. Wrong. It does validate the color.
  611. // As such its a delimiter. If the the current active char
  612. // set is G1, then it fills with mosaics, not spaces.
  613. //
  614. fModified = pstPRI->stLatentAttr.fModified;
  615. iMax = hhEmu->emu_maxcol;
  616. // minitelGraphic checks the InCancel flag and if TRUE suppresses
  617. // linewrap. mrw:5/3/95
  618. //
  619. pstPRI->fInCancel = TRUE;
  620. for (i = hhEmu->emu_curcol ; i <= iMax ; ++i)
  621. {
  622. minitelGraphic(hhEmu);
  623. }
  624. pstPRI->fInCancel = FALSE;
  625. // Ok, even though we validated the background color, we haven't
  626. // changed the state of the latent attribute (also undocumented).
  627. // So set it back to whatever is was before we entered this lovely
  628. // mess of a function - mrw
  629. //
  630. pstPRI->stLatentAttr.fModified = fModified;
  631. (*hhEmu->emu_setcurpos)(hhEmu, row, col);
  632. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = hhEmu->emu_maxcol;
  633. return;
  634. }
  635. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  636. * FUNCTION:
  637. * minitelUSRow
  638. *
  639. * DESCRIPTION:
  640. * Intermediate function that collects the row number
  641. *
  642. * ARGUMENTS:
  643. * void
  644. *
  645. * RETURNS:
  646. * void
  647. *
  648. */
  649. void minitelUSRow(const HHEMU hhEmu)
  650. {
  651. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  652. pstPRI->us_row_code = hhEmu->emu_code;
  653. }
  654. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  655. * FUNCTION:
  656. * minitelUSCol
  657. *
  658. * DESCRIPTION:
  659. * Interestingly, columns are numbered from 1 to 40. Unit seperators
  660. * are ugly little beasts. They indicate a row, col combo, but only
  661. * if in a certain range. Also, an obsolite sequence US,3/X,3/Y where
  662. * 0 < X < 3, 0 < Y < 9 and XY < 24 is not suppose to be used but
  663. * often is.
  664. *
  665. * ARGUMENTS:
  666. * void
  667. *
  668. * RETURNS:
  669. * void
  670. *
  671. */
  672. void minitelUSCol(const HHEMU hhEmu)
  673. {
  674. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  675. int us_col_code = hhEmu->emu_code;
  676. int us_col = us_col_code - 0x41;
  677. int us_row = pstPRI->us_row_code - 0x40;
  678. if (us_row >= 0 && us_row <= hhEmu->emu_maxrow &&
  679. us_col >= 0 && us_col <= hhEmu->emu_maxcol)
  680. {
  681. if (us_row == 0)
  682. {
  683. // p.97, bottom of page
  684. //
  685. if (hhEmu->emu_currow != 0)
  686. {
  687. pstPRI->minitel_saved_attr = hhEmu->emu_charattr;
  688. pstPRI->minitel_saved_row = hhEmu->emu_currow;
  689. pstPRI->minitel_saved_col = hhEmu->emu_curcol;
  690. pstPRI->saved_stLatentAttr = pstPRI->stLatentAttr;
  691. pstPRI->minitel_saved_minitelG1Active =
  692. pstPRI->minitelG1Active;
  693. pstPRI->saved_minitelUseSeparatedMosaics =
  694. pstPRI->minitelUseSeparatedMosaics;
  695. }
  696. }
  697. (*hhEmu->emu_setcurpos)(hhEmu, us_row, us_col);
  698. minitelReset(hhEmu);
  699. }
  700. else if (pstPRI->us_row_code >= 0x30 &&
  701. pstPRI->us_row_code < 0x33 &&
  702. us_col_code >= 0x30 &&
  703. us_col_code <= 0x39)
  704. {
  705. us_row = ((pstPRI->us_row_code - 0x30) * 10) + (us_col_code - 0x30);
  706. if (us_row > 24)
  707. return;
  708. if (us_row == 0)
  709. {
  710. if (hhEmu->emu_currow != 0)
  711. {
  712. pstPRI->minitel_saved_attr = hhEmu->emu_charattr;
  713. pstPRI->minitel_saved_row = hhEmu->emu_currow;
  714. pstPRI->minitel_saved_col = hhEmu->emu_curcol;
  715. pstPRI->saved_stLatentAttr = pstPRI->stLatentAttr;
  716. pstPRI->minitel_saved_minitelG1Active =
  717. pstPRI->minitelG1Active;
  718. pstPRI->saved_minitelUseSeparatedMosaics =
  719. pstPRI->minitelUseSeparatedMosaics;
  720. }
  721. }
  722. (*hhEmu->emu_setcurpos)(hhEmu, us_row, 0);
  723. minitelReset(hhEmu);
  724. }
  725. return;
  726. }
  727. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  728. * FUNCTION:
  729. * minitelDelChars
  730. *
  731. * DESCRIPTION:
  732. * Deletes n characters from cursor position inclusive.
  733. *
  734. * ARGUMENTS:
  735. * void
  736. *
  737. * RETURNS:
  738. * void
  739. *
  740. */
  741. void minitelDelChars(const HHEMU hhEmu)
  742. {
  743. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  744. int i, n;
  745. ECHAR *tp = hhEmu->emu_apText[hhEmu->emu_imgrow]+hhEmu->emu_curcol;
  746. STATTR stAttr;
  747. PSTATTR ap = hhEmu->emu_apAttr[hhEmu->emu_imgrow]+hhEmu->emu_curcol;
  748. STMINITEL stMT;
  749. PSTMINITEL pstMT = pstPRI->apstMT[hhEmu->emu_imgrow];
  750. // CSI sequences not available in row 0
  751. //
  752. if (hhEmu->emu_currow == 0)
  753. return;
  754. n = min(hhEmu->emu_maxcol, hhEmu->num_param[0]);
  755. i = max(0, hhEmu->emu_maxcol - hhEmu->emu_curcol - n);
  756. /* --- Move characters down --- */
  757. memmove(tp, tp+n, (unsigned)i * sizeof(ECHAR));
  758. memmove(ap, ap+n, (unsigned)i * sizeof(STATTR));
  759. memmove(pstMT, pstMT+n, (unsigned)i * sizeof(STMINITEL));
  760. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] =
  761. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] - i;
  762. /* --- Fill remainder of line --- */
  763. tp += i;
  764. ap += i;
  765. memset(&stAttr, 0, sizeof(stAttr));
  766. stAttr.txtclr = VC_BRT_WHITE;
  767. stAttr.bkclr = VC_BLACK;
  768. memset(&stMT, 0, sizeof(stMT));
  769. stMT.ismosaic = (unsigned)pstPRI->minitelG1Active;
  770. for (n = max(0, hhEmu->emu_maxcol - i) ; n > 0 ; --n)
  771. {
  772. *tp++ = EMU_BLANK_CHAR;
  773. *ap++ = stAttr;
  774. *pstMT++ = stMT;
  775. }
  776. updateChar(sessQueryUpdateHdl(hhEmu->hSession),
  777. hhEmu->emu_currow,
  778. hhEmu->emu_curcol,
  779. hhEmu->emu_maxcol);
  780. ANSI_Pn_Clr(hhEmu);
  781. return;
  782. }
  783. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  784. * FUNCTION:
  785. * minitelInsChars
  786. *
  787. * DESCRIPTION:
  788. * Inserts n characters from cursor position inclusive
  789. *
  790. * ARGUMENTS:
  791. * void
  792. *
  793. * RETURNS:
  794. * void
  795. *
  796. */
  797. void minitelInsChars(const HHEMU hhEmu)
  798. {
  799. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  800. int i, n;
  801. ECHAR *tp = hhEmu->emu_apText[hhEmu->emu_imgrow]+hhEmu->emu_curcol;
  802. STATTR stAttr;
  803. PSTATTR ap = hhEmu->emu_apAttr[hhEmu->emu_imgrow]+hhEmu->emu_curcol;
  804. STMINITEL stMT;
  805. PSTMINITEL pstMT = pstPRI->apstMT[hhEmu->emu_imgrow];
  806. // CSI sequences not available in row 0
  807. //
  808. if (hhEmu->emu_currow == 0)
  809. return;
  810. n = min(hhEmu->emu_maxcol, hhEmu->num_param[0]);
  811. i = max(0, hhEmu->emu_maxcol - hhEmu->emu_curcol - n);
  812. /* --- Move stuff down --- */
  813. memmove(tp+n, tp, (unsigned)i * sizeof(ECHAR));
  814. memmove(ap+n, tp, (unsigned)i * sizeof(STATTR));
  815. memmove(pstMT+n, pstMT, (unsigned)i * sizeof(STMINITEL));
  816. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] =
  817. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] + i;
  818. /* --- Fill the gap --- */
  819. memset(&stAttr, 0, sizeof(stAttr));
  820. stAttr.txtclr = VC_BRT_WHITE;
  821. stAttr.bkclr = VC_BLACK;
  822. memset(&stMT, 0, sizeof(stMT));
  823. stMT.ismosaic = (unsigned)pstPRI->minitelG1Active;
  824. while (--i >= 0)
  825. {
  826. *tp++ = EMU_BLANK_CHAR;
  827. *ap++ = stAttr;
  828. *pstMT++ = stMT;
  829. }
  830. updateChar(sessQueryUpdateHdl(hhEmu->hSession),
  831. hhEmu->emu_currow,
  832. hhEmu->emu_curcol,
  833. hhEmu->emu_maxcol);
  834. ANSI_Pn_Clr(hhEmu);
  835. return;
  836. }
  837. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  838. * FUNCTION:
  839. * minitelDelRows
  840. *
  841. * DESCRIPTION:
  842. * Deletes n rows from the current row.
  843. *
  844. * ARGUMENTS:
  845. * void
  846. *
  847. * RETURNS:
  848. * void
  849. *
  850. */
  851. void minitelDelRows(const HHEMU hhEmu)
  852. {
  853. int r, r1;
  854. int c, i, n;
  855. STATTR stAttr;
  856. STMINITEL stMT;
  857. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  858. // CSI sequences not available in row 0
  859. //
  860. if (hhEmu->emu_currow == 0)
  861. return;
  862. n = min(hhEmu->emu_maxrow, hhEmu->num_param[0]);
  863. i = max(0, hhEmu->emu_maxrow - hhEmu->emu_currow - n);
  864. for (i = 0 ; i < n ; ++i)
  865. {
  866. if ((hhEmu->emu_currow+i+n) > hhEmu->emu_maxrow)
  867. break;
  868. r = row_index(hhEmu, hhEmu->emu_currow+i);
  869. r1 = row_index(hhEmu, hhEmu->emu_currow+i+n);
  870. MemCopy(hhEmu->emu_apText[r],
  871. hhEmu->emu_apText[r1],
  872. sizeof(ECHAR) * (unsigned)(hhEmu->emu_maxcol+1));
  873. MemCopy(hhEmu->emu_apAttr[r],
  874. hhEmu->emu_apAttr[r1],
  875. sizeof(STATTR) * (unsigned)(hhEmu->emu_maxcol+1));
  876. MemCopy(pstPRI->apstMT[r],
  877. pstPRI->apstMT[r1],
  878. sizeof(STMINITEL) * (unsigned)(hhEmu->emu_maxcol+1));
  879. hhEmu->emu_aiEnd[r] = hhEmu->emu_aiEnd[r1];
  880. }
  881. memset(&stAttr, 0, sizeof(stAttr));
  882. stAttr.txtclr = VC_BRT_WHITE;
  883. stAttr.bkclr = VC_BLACK;
  884. memset(&stMT, 0, sizeof(stMT));
  885. stMT.ismosaic = (unsigned)pstPRI->minitelG1Active;
  886. for (n = max(0, hhEmu->emu_maxrow - i) ; n <= hhEmu->emu_maxrow ; ++n)
  887. {
  888. r = row_index(hhEmu, n);
  889. for (c = 0 ; c <= hhEmu->emu_maxcol ; ++c)
  890. {
  891. hhEmu->emu_apText[r][c] = EMU_BLANK_CHAR;
  892. hhEmu->emu_apAttr[r][c] = stAttr;
  893. pstPRI->apstMT[r][c] = stMT;
  894. hhEmu->emu_aiEnd[r] = EMU_BLANK_LINE;
  895. }
  896. }
  897. updateLine(sessQueryUpdateHdl(hhEmu->hSession),
  898. hhEmu->emu_currow,
  899. hhEmu->emu_maxrow);
  900. return;
  901. }
  902. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  903. * FUNCTION:
  904. * minitelInsRows
  905. *
  906. * DESCRIPTION:
  907. * Inserts n rows from current row inclusive
  908. *
  909. * ARGUMENTS:
  910. * void
  911. *
  912. * RETURNS:
  913. * void
  914. *
  915. */
  916. void minitelInsRows(const HHEMU hhEmu)
  917. {
  918. int r, r1;
  919. int c, i, n;
  920. STATTR stAttr;
  921. STMINITEL stMT;
  922. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  923. if (hhEmu->emu_currow == 0)
  924. return;
  925. n = min(hhEmu->emu_maxrow, hhEmu->num_param[0]);
  926. i = max(0, hhEmu->emu_maxrow - hhEmu->emu_currow - n);
  927. for (i = 0 ; i < n ; ++i)
  928. {
  929. if ((hhEmu->emu_currow+i+n) > hhEmu->emu_maxrow)
  930. break;
  931. r = row_index(hhEmu, hhEmu->emu_currow+i);
  932. r1 = row_index(hhEmu, hhEmu->emu_currow+i+n);
  933. MemCopy(hhEmu->emu_apText[r1],
  934. hhEmu->emu_apText[r],
  935. sizeof(ECHAR) * (unsigned)(hhEmu->emu_maxcol+1));
  936. MemCopy(hhEmu->emu_apAttr[r1],
  937. hhEmu->emu_apAttr[r],
  938. sizeof(STATTR) * (unsigned)(hhEmu->emu_maxcol+1));
  939. MemCopy(pstPRI->apstMT[r1],
  940. pstPRI->apstMT[r],
  941. sizeof(STMINITEL) * (unsigned)(hhEmu->emu_maxcol+1));
  942. hhEmu->emu_aiEnd[r1] = hhEmu->emu_aiEnd[r];
  943. }
  944. memset(&stAttr, 0, sizeof(stAttr));
  945. stAttr.txtclr = VC_BRT_WHITE;
  946. stAttr.bkclr = VC_BLACK;
  947. memset(&stMT, 0, sizeof(stMT));
  948. stMT.ismosaic = (unsigned)pstPRI->minitelG1Active;
  949. for (n = hhEmu->emu_currow ; n < (hhEmu->emu_maxrow - i) ; ++n)
  950. {
  951. r = row_index(hhEmu, n);
  952. for (c = 0 ; c <= hhEmu->emu_maxcol ; ++c)
  953. {
  954. hhEmu->emu_apText[r][c] = EMU_BLANK_CHAR;
  955. hhEmu->emu_apAttr[r][c] = stAttr;
  956. pstPRI->apstMT[r][c] = stMT;
  957. hhEmu->emu_aiEnd[r] = EMU_BLANK_LINE;
  958. }
  959. }
  960. updateLine(sessQueryUpdateHdl(hhEmu->hSession),
  961. hhEmu->emu_currow,
  962. hhEmu->emu_maxrow);
  963. return;
  964. }
  965. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  966. * FUNCTION:
  967. * minitelHomeHostCursor
  968. *
  969. * DESCRIPTION:
  970. * Sets cursor to home position which is 1, 0 in this case.
  971. *
  972. * ARGUMENTS:
  973. * hhEmu - private emulator handle
  974. *
  975. * RETURNS:
  976. * 0=OK,else error.
  977. *
  978. */
  979. int minitelHomeHostCursor(const HHEMU hhEmu)
  980. {
  981. if (hhEmu == 0)
  982. {
  983. assert(0);
  984. return -1;
  985. }
  986. (*hhEmu->emu_setcurpos)(hhEmu, 1, 0);
  987. return 0;
  988. }
  989. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  990. * FUNCTION:
  991. * minitel_scrollup
  992. *
  993. * DESCRIPTION:
  994. * Mintels of course scroll differently. Actually, its the way they
  995. * clear lines that keeps us from using the standard stuff.
  996. *
  997. * ARGUMENTS:
  998. * hhEmu - private emulator handle.
  999. * nlines - number of lines to scroll.
  1000. *
  1001. * RETURNS:
  1002. * void
  1003. *
  1004. */
  1005. void minitel_scrollup(const HHEMU hhEmu, int nlines)
  1006. {
  1007. register INT row;
  1008. INT nrows, iLen, iThisRow;
  1009. ECHAR *lp; /* line pointer */
  1010. INT nScrlInc; /* needed for call to Vid routine at bottom of func */
  1011. if (nlines <= 0)
  1012. return;
  1013. hhEmu->scr_scrollcnt += nlines;
  1014. nScrlInc = nlines = min(nlines,
  1015. hhEmu->bottom_margin - hhEmu->top_margin + 1);
  1016. for (row = hhEmu->top_margin; row < (hhEmu->top_margin + nlines); ++row)
  1017. {
  1018. iThisRow = row_index(hhEmu, row);
  1019. lp = hhEmu->emu_apText[iThisRow];
  1020. iLen = emuRowLen(hhEmu, iThisRow);
  1021. minitel_clear_imgrow(hhEmu, row);
  1022. }
  1023. if (hhEmu->top_margin == 0 && hhEmu->bottom_margin == hhEmu->emu_maxrow)
  1024. {
  1025. hhEmu->emu_imgtop = row_index(hhEmu, nlines);
  1026. }
  1027. else if (nlines < (hhEmu->bottom_margin - hhEmu->top_margin + 1))
  1028. {
  1029. nrows = hhEmu->bottom_margin - hhEmu->top_margin + 1 - nlines;
  1030. for (row = hhEmu->top_margin; nrows > 0; --nrows, ++row)
  1031. {
  1032. INT c;
  1033. PSTATTR pstAttr, pstAttr2;
  1034. PSTMINITEL pstMT, pstMT2;
  1035. memmove(hhEmu->emu_apText[row_index(hhEmu, row)],
  1036. hhEmu->emu_apText[row_index(hhEmu, row + nlines)],
  1037. (size_t)hhEmu->emu_maxcol + 2);
  1038. hhEmu->emu_aiEnd[row_index(hhEmu, row + nlines)] =
  1039. hhEmu->emu_aiEnd[row_index(hhEmu, row)];
  1040. pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, row)];
  1041. pstAttr2 = hhEmu->emu_apAttr[row_index(hhEmu, row + nlines)];
  1042. for (c = 0 ; c <= hhEmu->emu_maxcol ; ++c)
  1043. pstAttr[c] = pstAttr2[c];
  1044. pstMT = ((PSTMTPRIVATE)hhEmu->pvPrivate)->apstMT[row_index(hhEmu, row)];
  1045. pstMT2= ((PSTMTPRIVATE)hhEmu->pvPrivate)->apstMT[row_index(hhEmu, row + nlines)];
  1046. for (c = 0 ; c <= hhEmu->emu_maxcol ; ++c)
  1047. pstMT[c] = pstMT2[c];
  1048. }
  1049. for (row = hhEmu->bottom_margin; nlines > 0; --nlines, --row)
  1050. minitel_clear_imgrow(hhEmu, row);
  1051. }
  1052. hhEmu->emu_imgrow = row_index(hhEmu, hhEmu->emu_currow);
  1053. updateScroll(sessQueryUpdateHdl(hhEmu->hSession),
  1054. hhEmu->top_margin,
  1055. hhEmu->bottom_margin,
  1056. nScrlInc,
  1057. hhEmu->emu_imgtop,
  1058. TRUE);
  1059. return;
  1060. }
  1061. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1062. * FUNCTION:
  1063. * minitel_scrolldown
  1064. *
  1065. * DESCRIPTION:
  1066. * Minitel of course works differently. Mostly is has more work to
  1067. * clear a line.
  1068. *
  1069. * ARGUMENTS:
  1070. * hhEmu - private emulator handle
  1071. * nlines - number of lines to scroll
  1072. *
  1073. * RETURNS:
  1074. * void
  1075. *
  1076. */
  1077. void minitel_scrolldown(const HHEMU hhEmu, int nlines)
  1078. {
  1079. register int row, nrows;
  1080. int toprow, botmrow;
  1081. int nScrlInc;
  1082. if (nlines <= 0)
  1083. return;
  1084. hhEmu->scr_scrollcnt -= nlines;
  1085. nScrlInc = nlines;
  1086. toprow = hhEmu->top_margin;
  1087. botmrow = hhEmu->bottom_margin;
  1088. if (hhEmu->top_margin == 0 && hhEmu->bottom_margin == hhEmu->emu_maxrow)
  1089. {
  1090. hhEmu->emu_imgtop = row_index(hhEmu, -nlines);
  1091. }
  1092. else if (nlines < hhEmu->bottom_margin - hhEmu->top_margin + 1)
  1093. {
  1094. nrows = hhEmu->bottom_margin - hhEmu->top_margin + 1 - nlines;
  1095. for (row = hhEmu->bottom_margin; nrows > 0; --nrows, --row)
  1096. {
  1097. int c;
  1098. PSTATTR pstAttr, pstAttr2;
  1099. PSTMINITEL pstMT, pstMT2;
  1100. memmove(hhEmu->emu_apText[row_index(hhEmu, row)],
  1101. hhEmu->emu_apText[row_index(hhEmu, row - nlines)],
  1102. (size_t)(hhEmu->emu_maxcol+2));
  1103. hhEmu->emu_aiEnd[row_index(hhEmu, row - nlines)] =
  1104. hhEmu->emu_aiEnd[row_index(hhEmu, row)];
  1105. pstAttr = hhEmu->emu_apAttr[row_index(hhEmu, row)];
  1106. pstAttr2 = hhEmu->emu_apAttr[row_index(hhEmu, row - nlines)];
  1107. for (c = 0 ; c <= hhEmu->emu_maxcol ; ++c)
  1108. pstAttr[c] = pstAttr2[c];
  1109. pstMT = ((PSTMTPRIVATE)hhEmu->pvPrivate)->apstMT[row_index(hhEmu, row)];
  1110. pstMT2= ((PSTMTPRIVATE)hhEmu->pvPrivate)->apstMT[row_index(hhEmu, row + nlines)];
  1111. for (c = 0 ; c <= hhEmu->emu_maxcol ; ++c)
  1112. pstMT[c] = pstMT2[c];
  1113. }
  1114. }
  1115. for (row = hhEmu->top_margin; nlines > 0; --nlines, ++row)
  1116. minitel_clear_imgrow(hhEmu, row);
  1117. hhEmu->emu_imgrow = row_index(hhEmu, hhEmu->emu_currow);
  1118. updateScroll(sessQueryUpdateHdl(hhEmu->hSession),
  1119. toprow, botmrow, -nScrlInc, hhEmu->emu_imgtop, TRUE);
  1120. }
  1121. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1122. * FUNCTION:
  1123. * minitel_clear_imgrow
  1124. *
  1125. * DESCRIPTION:
  1126. * minitel's have to do more work to clear a line.
  1127. *
  1128. * ARGUMENTS:
  1129. * hhEmu - private minitel handle.
  1130. * row - row to clear
  1131. *
  1132. * RETURNS:
  1133. * void
  1134. *
  1135. */
  1136. static void minitel_clear_imgrow(const HHEMU hhEmu, const int row)
  1137. {
  1138. const int save_row = hhEmu->emu_currow;
  1139. const int save_imgrow = hhEmu->emu_imgrow;
  1140. hhEmu->emu_currow = row;
  1141. hhEmu->emu_imgrow = row_index(hhEmu, row);
  1142. minitelClearLine(hhEmu, 2);
  1143. hhEmu->emu_currow = save_row;
  1144. hhEmu->emu_imgrow = save_imgrow;
  1145. return;
  1146. }
  1147. #endif // INCL_MINITEL