Source code of Windows XP (NT5)
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.

838 lines
23 KiB

  1. #define WIN32_ONLY
  2. #include <posix/sys/types.h>
  3. #include <posix/termios.h>
  4. #include "psxses.h"
  5. #include "ansiio.h"
  6. #include <io.h>
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. extern DWORD OutputModeFlags; /* Console Output Mode */
  10. extern DWORD InputModeFlags;
  11. extern unsigned char AnsiNewMode;
  12. extern struct termios SavedTermios;
  13. /* DFC: New globals (from trans.h) */
  14. WORD ansi_attr; /* attribute of TTY */
  15. WORD ansi_attr1; /* MSKK : leave space for 3 attr */
  16. WORD ansi_attr2; /* MSKK : leave space for 3 attr */
  17. SHORT ScreenColNum; /* col number */
  18. SHORT ScreenRowNum; /* row number */
  19. BYTE CarriageReturn;
  20. COORD TrackedCoord,
  21. CurrentCoord;
  22. DWORD TTYConBeep(void);
  23. static BYTE ColorTable[8] = { 0, /* Black */
  24. 4, /* Red */
  25. 2, /* Green */
  26. 6, /* Yellow */
  27. 1, /* Blue */
  28. 5, /* Magenta */
  29. 3, /* Cyan */
  30. 7}; /* White */
  31. DWORD
  32. TermioInit(void)
  33. {
  34. CONSOLE_SCREEN_BUFFER_INFO ScreenInfo1;
  35. BOOL Success;
  36. ansi_state = NOCMD; /* state of machine */
  37. ignore_next_char = 0;
  38. #if 0
  39. ansi_base = ansi_attr = 0x07; /* white on black */
  40. #endif
  41. ansi_reverse = 0;
  42. InputModeFlags = (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
  43. OutputModeFlags ^= ENABLE_WRAP_AT_EOL_OUTPUT;
  44. AnsiNewMode = FALSE;
  45. if (!SetConsoleMode(hConsoleInput, InputModeFlags)) {
  46. KdPrint(("posix - can't set console mode: 0x%x\n", GetLastError()));
  47. }
  48. /* Set default termio parameters */
  49. SavedTermios.c_iflag = BRKINT|ICRNL;
  50. SavedTermios.c_oflag = OPOST|ONLCR;
  51. SavedTermios.c_cflag = CREAD|CS8;
  52. SavedTermios.c_lflag = ICANON|ECHO|ECHOE|ECHOK|ISIG;
  53. SavedTermios.c_cc[VEOF] = CTRL('Z');
  54. SavedTermios.c_cc[VEOL] = 0; // _POSIX_VDISABLE
  55. SavedTermios.c_cc[VERASE] = CTRL('H');
  56. SavedTermios.c_cc[VINTR] = CTRL('C');
  57. SavedTermios.c_cc[VKILL] = CTRL('X');
  58. SavedTermios.c_cc[VQUIT] = CTRL('\\');
  59. SavedTermios.c_cc[VSUSP] = CTRL('Y');
  60. SavedTermios.c_cc[VSTOP] = CTRL('S');
  61. SavedTermios.c_cc[VSTART] = CTRL('Q');
  62. SavedTermios.c_ospeed = B9600;
  63. SavedTermios.c_ispeed = B9600;
  64. Success = GetConsoleScreenBufferInfo(hConsoleOutput, &ScreenInfo1);
  65. if (!Success) {
  66. return Success;
  67. }
  68. ansi_base = ansi_attr = ScreenInfo1.wAttributes;
  69. ansi_attr1 = ansi_attr2 = 0;
  70. ScreenRowNum = ScreenInfo1.dwSize.Y;
  71. ScreenColNum = ScreenInfo1.dwSize.X;
  72. CurrentCoord.Y = TrackedCoord.Y = ScreenInfo1.dwCursorPosition.Y + 1;
  73. CurrentCoord.X = TrackedCoord.X = ScreenInfo1.dwCursorPosition.X + 1;
  74. return (DWORD) 0;
  75. }
  76. /*
  77. ** TermOutput(SourStr, cnt) - pass characters to the finite state machine
  78. ** SourStr points to the array of characters
  79. ** cnt indicates how many characters are being passed.
  80. */
  81. DWORD
  82. TermOutput(
  83. IN HANDLE cs,
  84. IN LPSTR SourStr,
  85. IN DWORD cnt)
  86. {
  87. register CHAR c;
  88. USHORT NewCoord, ToFlash;
  89. DWORD Rc = 0, orig_cnt = cnt;
  90. BOOL SetModeOn, OldWrap, NewWrap;
  91. CONSOLE_SCREEN_BUFFER_INFO ScreenInfo1;
  92. //
  93. // Kludge because we don't know how many carriage returns we received
  94. // as input, thereby impeding TermOutput()'s ability to track the
  95. // cursor coordinate accurately
  96. //
  97. GetConsoleScreenBufferInfo(cs, &ScreenInfo1);
  98. CurrentCoord.Y = TrackedCoord.Y = ScreenInfo1.dwCursorPosition.Y + 1;
  99. CurrentCoord.X = TrackedCoord.X = ScreenInfo1.dwCursorPosition.X + 1;
  100. NewCoord = 0;
  101. CarriageReturn = 0;
  102. TTYOldCtrlCharInStr = TRUE;
  103. TTYCtrlCharInStr = FALSE;
  104. TTYcs = cs;
  105. TTYTextPtr = SourStr;
  106. TTYNumBytes = 0;
  107. //
  108. // Stop output, if VSTOP has been encountered
  109. //
  110. if (bStop) {
  111. RtlEnterCriticalSection(&StopMutex);
  112. if (bStop) {
  113. RtlLeaveCriticalSection(&StopMutex);
  114. WaitForSingleObject(hStopEvent, INFINITE);
  115. } else {
  116. RtlLeaveCriticalSection(&StopMutex);
  117. }
  118. }
  119. SetModeOn = FALSE;
  120. while (cnt--) {
  121. c = *SourStr++;
  122. switch (ansi_state) {
  123. case NOCMD:
  124. if (c == ANSI_ESC) {
  125. //
  126. // Make sure buffer is flushed and cursor position is
  127. // up-to-date before processing next esc-seq
  128. //
  129. if ( (Rc = TTYFlushStr(&NewCoord, "1")) != 0 ) {
  130. KdPrint(("PSXSES(trans-TTY): failed on "
  131. "TTYFlushStr #1\n"));
  132. return (DWORD) -1;
  133. }
  134. ansi_state = ESCED;
  135. break;
  136. } else {
  137. if (isprint(c)) { /* Printable char found */
  138. TTYNumBytes++;
  139. TrackedCoord.X++;
  140. } else {
  141. /* Non-printable char found */
  142. ToFlash = TRUE;
  143. switch ( c ) {
  144. case '\n':
  145. new_line:
  146. if (SavedTermios.c_oflag & OPOST) {
  147. if (c == '\n' &&
  148. (SavedTermios.c_oflag & ONLCR)) {
  149. TrackedCoord.Y++;
  150. goto carriage_return;
  151. }
  152. if (SavedTermios.c_oflag & ONLRET) {
  153. #if 0
  154. TrackedCoord.X = 1;
  155. #endif
  156. CarriageReturn = 1;
  157. }
  158. }
  159. TrackedCoord.Y++;
  160. NewCoord = 1;
  161. break;
  162. case '\r':
  163. carriage_return:
  164. if ( SavedTermios.c_oflag & OPOST ) {
  165. if ( c == '\r' &&
  166. (SavedTermios.c_oflag & OCRNL) ) {
  167. goto new_line;
  168. } else if ( ! (SavedTermios.c_oflag & ONOCR) ||
  169. TrackedCoord.X != 1 ) {
  170. #if 0
  171. TrackedCoord.X = 1;
  172. #endif
  173. NewCoord = 1;
  174. CarriageReturn = 1;
  175. }
  176. } else {
  177. if ( TrackedCoord.X > 1 ) {
  178. TrackedCoord.X = 1;
  179. NewCoord = 1;
  180. CarriageReturn = 1;
  181. }
  182. }
  183. break;
  184. case '\b':
  185. if ( TrackedCoord.X > 1 ) {
  186. TrackedCoord.X--;
  187. NewCoord = 1;
  188. }
  189. break;
  190. case '\t':
  191. TrackedCoord.X += (8 - ((TrackedCoord.X - 1) % 8));
  192. // Handle wrap after tab
  193. if (TrackedCoord.X > ScreenColNum) {
  194. if (OutputModeFlags & ENABLE_WRAP_AT_EOL_OUTPUT) {
  195. TrackedCoord.Y += ((TrackedCoord.X) / ScreenColNum);
  196. TrackedCoord.X = (TrackedCoord.X % ScreenColNum);
  197. } else {
  198. TrackedCoord.X = ScreenColNum;
  199. }
  200. }
  201. NewCoord = 1;
  202. break;
  203. case '\a':
  204. if ( (Rc = TTYConBeep()) != 0 ) {
  205. KdPrint(("PSXSES(trans-TTY): failed on "
  206. "BEEP\n"));
  207. return (DWORD) -1;
  208. }
  209. break;
  210. default:
  211. TTYCtrlCharInStr = TRUE;
  212. ToFlash = FALSE;
  213. #if 0
  214. TTYNumBytes++;
  215. TrackedCoord.X++;
  216. #endif
  217. break;
  218. } /* switch */
  219. if ( ToFlash ) { /* Flush */
  220. //
  221. // Flush carriage control chars to update cursor
  222. // position
  223. //
  224. if ((Rc = TTYFlushStr(&NewCoord, "2")) != 0) {
  225. return (DWORD)-1;
  226. }
  227. TTYTextPtr = SourStr;
  228. }
  229. } /* isprint */
  230. } /* ANSI_ESC */
  231. break;
  232. case ESCED:
  233. switch ( c ) {
  234. case '[':
  235. ansi_state = PARAMS;
  236. SetModeOn = TRUE;
  237. clrparam();
  238. break;
  239. default:
  240. ansi_state = NOCMD;
  241. TTYTextPtr = SourStr - 1;
  242. cnt++ ;
  243. SourStr--;
  244. break;
  245. }
  246. break;
  247. case PARAMS:
  248. if ( isdigit(c) ) {
  249. ansi_param[ansi_pnum] *= 10;
  250. ansi_param[ansi_pnum] += (c - '0');
  251. SetModeOn = FALSE;
  252. } else if ( c == ';' ) {
  253. if ( ansi_pnum < (NPARMS - 1) )
  254. ++ansi_pnum;
  255. else {
  256. ansi_state = NOCMD;
  257. TTYTextPtr = SourStr;
  258. }
  259. } else if ( (c == '=') && SetModeOn ) { /* maybe set/reset mode */
  260. ansi_state = MODCMD;
  261. } else {
  262. ansi_state = NOCMD;
  263. if ( (Rc = ansicmd(cs, c)) != 0 ) {
  264. return (DWORD) -1;
  265. }
  266. TTYTextPtr = SourStr;
  267. NewCoord = 1;
  268. if ( (Rc = TTYFlushStr(&NewCoord, "3")) != 0 ) {
  269. #if 0
  270. return (DWORD) -1;
  271. #endif
  272. }
  273. }
  274. break;
  275. case MODCMD:
  276. if ( ansi_pnum == 1 ) {
  277. if ( c == 'h' || c == 'l' ) {
  278. if ( ansi_param[0] == 7 ) {
  279. OldWrap = ((OutputModeFlags &
  280. ENABLE_WRAP_AT_EOL_OUTPUT) != 0);
  281. NewWrap = (c == 'h');
  282. if ( OldWrap != NewWrap ) {
  283. if ( (Rc = !SetConsoleMode(cs,
  284. OutputModeFlags^ENABLE_WRAP_AT_EOL_OUTPUT))
  285. != 0 ) {
  286. return (DWORD) -1;
  287. }
  288. OutputModeFlags ^= ENABLE_WRAP_AT_EOL_OUTPUT;
  289. #if 0
  290. } else {
  291. OutputModeFlags ~= ENABLE_WRAP_AT_EOL_OUTPUT;
  292. #endif
  293. }
  294. }
  295. TTYTextPtr = SourStr;
  296. } else {
  297. TTYTextPtr = SourStr - 5;
  298. TTYNumBytes = 5;
  299. }
  300. } else if ( c >= '0' && c <= '7' ) {
  301. ansi_param[0] = (USHORT) (c - '0');
  302. ansi_pnum = 1;
  303. break;
  304. } else {
  305. TTYTextPtr = SourStr - 4;
  306. TTYNumBytes = 4;
  307. }
  308. ansi_state = NOCMD;
  309. break;
  310. case MODDBCS:
  311. TTYNumBytes++;
  312. TrackedCoord.X++;
  313. ansi_state = NOCMD;
  314. break;
  315. } /* switch ansi_state */
  316. } /* while cnt */
  317. /* Flush */
  318. if ( (Rc = TTYFlushStr(&NewCoord, "4")) != 0 ) {
  319. return (DWORD) -1;
  320. }
  321. return(orig_cnt);
  322. }
  323. /*
  324. ** clrparam(lp) - clear the parameters for a screen
  325. ** lp points to the screen's crt struct
  326. */
  327. VOID
  328. clrparam(void)
  329. {
  330. register int i;
  331. for ( i = 0; i < NPARMS; i += 1 )
  332. ansi_param[i] = 0;
  333. ansi_pnum = 0;
  334. }
  335. //
  336. // lscroll - scroll the sceen
  337. //
  338. void
  339. lscroll(
  340. HANDLE h, // handle on the console buffer to scroll
  341. int lines // number of lines to scroll (negative means
  342. // scroll text down)
  343. )
  344. {
  345. COORD coordDest;
  346. SMALL_RECT ScrollRect;
  347. CHAR_INFO ScrollChar;
  348. BOOLEAN Success;
  349. if (0 == lines) {
  350. // already done
  351. return;
  352. }
  353. if (lines < 0) {
  354. // scroll text down
  355. ScrollRect.Top = 0;
  356. ScrollRect.Bottom = ScreenRowNum + lines;
  357. coordDest.X = 0;
  358. coordDest.Y = 0 - lines;
  359. } else {
  360. // scroll text up
  361. ScrollRect.Top = (SHORT)lines;
  362. ScrollRect.Bottom = ScreenRowNum;
  363. coordDest.X = 0;
  364. coordDest.Y = 0;
  365. }
  366. ScrollRect.Left = 0;
  367. ScrollRect.Right = ScreenColNum;
  368. ScrollChar.Attributes = (ansi_attr);
  369. ScrollChar.Char.AsciiChar = ' ';
  370. Success = ScrollConsoleScreenBufferA(h, &ScrollRect, NULL,
  371. coordDest, &ScrollChar) ? TRUE : FALSE;
  372. if (!Success) {
  373. KdPrint(("POSIX: ScrollConsole: 0x%x\n", GetLastError()));
  374. }
  375. return;
  376. }
  377. //
  378. // ansicmd - perform some ANSI 3.64 function, using the parameters
  379. // we've just gathered.
  380. //
  381. // c is the character that indicates the function to be performed
  382. //
  383. DWORD
  384. ansicmd(
  385. IN HANDLE cs,
  386. IN CHAR c
  387. )
  388. {
  389. DWORD NumFilled, Rc = 0;
  390. USHORT j;
  391. COORD Coord;
  392. switch (c) {
  393. case ANSI_CUB: /* cursor backward */
  394. TrackedCoord.X -= (short) range(ansi_param[0], 1, 1, TrackedCoord.X - 1);
  395. break;
  396. case ANSI_CUF: /* cursor forward */
  397. TrackedCoord.X += (short) range(ansi_param[0], 1, 1,
  398. ScreenColNum - TrackedCoord.X );
  399. break;
  400. case ANSI_CUU: /* cursor up */
  401. TrackedCoord.Y -= (short) range(ansi_param[0], 1, 1, TrackedCoord.Y - 1);
  402. break;
  403. case ANSI_CUD: /* cursor down */
  404. TrackedCoord.Y += (short) range(ansi_param[0], 1, 1,
  405. ScreenRowNum - TrackedCoord.Y);
  406. break;
  407. case ANSI_CUP: /* cursor position */
  408. case ANSI_CUP1:
  409. TrackedCoord.Y = (USHORT) range(ansi_param[0], 1, 1, ScreenRowNum);
  410. TrackedCoord.X = (USHORT) range(ansi_param[1], 1, 1, ScreenColNum);
  411. break;
  412. case ANSI_ED: /* erase display */
  413. switch ( ansi_param[0] ) {
  414. case 2:
  415. TrackedCoord.Y = TrackedCoord.X = 1;
  416. Coord.X = (SHORT) (TrackedCoord.X - 1);
  417. Coord.Y = (SHORT) (TrackedCoord.Y - 1);
  418. if ( (Rc = (!FillConsoleOutputCharacterA(cs, ' ',
  419. (DWORD) ScreenRowNum * ScreenColNum, Coord, &NumFilled)))
  420. != 0 ) {
  421. return (Rc);
  422. }
  423. if ( (Rc = (!FillConsoleOutputAttribute(cs, (ansi_attr),
  424. NumFilled, Coord, &NumFilled))) != 0 ) {
  425. return (Rc);
  426. }
  427. break;
  428. default:
  429. break;
  430. }
  431. break;
  432. case ANSI_EL:
  433. Coord.X = (SHORT)(TrackedCoord.X - 1);
  434. Coord.Y = (SHORT)(TrackedCoord.Y - 1);
  435. switch ( ansi_param[0] ) {
  436. case 0: /* up to end */
  437. if ( (Rc = (!FillConsoleOutputCharacterA(cs, ' ',
  438. (DWORD) (ScreenColNum - Coord.X), Coord, &NumFilled))) != 0 ) {
  439. return (Rc);
  440. }
  441. if ( (Rc = (!FillConsoleOutputAttribute(cs, (ansi_attr),
  442. NumFilled, Coord, &NumFilled))) != 0 ) {
  443. return (Rc);
  444. }
  445. break;
  446. default:
  447. break;
  448. }
  449. break;
  450. case ANSI_SGR:
  451. // SGR = Select Graphic Rendition
  452. for ( j = 0; (SHORT) j <= (SHORT) ansi_pnum; j++ ) {
  453. SetTTYAttr(cs, ansi_param[j]);
  454. }
  455. break;
  456. #if 0
  457. case ANSI_SCP:
  458. ansi_scp = TrackedCoord;
  459. break;
  460. case ANSI_RCP:
  461. TrackedCoord = ansi_scp;
  462. break;
  463. case ANSI_CPL: /* cursor to previous line */
  464. TrackedCoord.Y -= range(ansi_param[0], 1, 1, ScreenRowNum);
  465. TrackedCoord.X = 1;
  466. break;
  467. case ANSI_CNL: /* cursor to next line */
  468. TrackedCoord.Y += range(ansi_param[0], 1, 1, ScreenRowNum);
  469. TrackedCoord.X = 1;
  470. break;
  471. case ANSI_CBT: /* tab backwards */
  472. col = TrackedCoord.X - 1;
  473. i = range(ansi_param[0], 1, 1, (col + 7) >> 3);
  474. if ( col & 7 ) {
  475. TrackedCoord.X = (col & ~7) + 1;
  476. --i;
  477. }
  478. TrackedCoord.X -= (i << 3);
  479. break;
  480. case ANSI_DCH: /* delete character */
  481. ansi_param[0] = range(ansi_param[0], 1, 1,
  482. (ScreenColNum - TrackedCoord.X) + 1);
  483. if ( TrackedCoord.X + ansi_param[0] <= ScreenColNum ) {
  484. lcopy(cs, lp, TrackedCoord.X+ansi_param[0]-1, TrackedCoord.Y-1,
  485. TrackedCoord.X-1, TrackedCoord.Y-1,
  486. ScreenColNum-(TrackedCoord.X+ansi_param[0]-1));
  487. }
  488. lclear(cs, lp, ScreenColNum-ansi_param[0], TrackedCoord.Y-1,
  489. ansi_param[0], SA_BONW);
  490. break;
  491. case ANSI_DL: /* delete line */
  492. ansi_param[0] = range(ansi_param[0], 1, 1,
  493. (ScreenRowNum - TrackedCoord.Y) + 1);
  494. /* copy lines up */
  495. if ( TrackedCoord.Y + ansi_param[0] <= ScreenRowNum ) {
  496. lcopy(cs, lp, 0, TrackedCoord.Y+ansi_param[0]-1, 0,
  497. TrackedCoord.Y-1,
  498. ScreenColNum*(ScreenRowNum-(TrackedCoord.Y+ansi_param[0]-1)));
  499. }
  500. /* clear new stuff */
  501. lclear(cs, lp, 0, ScreenRowNum-ansi_param[0],
  502. ScreenColNum*ansi_param[0], SA_BONW);
  503. break;
  504. case ANSI_ECH: /* erase character */
  505. ansi_param[0] = range( ansi_param[0], 1, 1,
  506. (ScreenColNum - TrackedCoord.X) + 1);
  507. lclear(cs, lp, TrackedCoord.X-1, TrackedCoord.Y-1, ansi_param[0],
  508. SA_BONW);
  509. break;
  510. case ANSI_ICH: /* insert character */
  511. ansi_param[0] = range( ansi_param[0], 1, 1,
  512. (ScreenColNum - TrackedCoord.X) + 1);
  513. if ( TrackedCoord.X + ansi_param[0] <= ScreenColNum ) {
  514. lcopy(cs, lp, TrackedCoord.X-1, TrackedCoord.Y-1,
  515. TrackedCoord.X+ansi_param[0]-1, TrackedCoord.Y-1,
  516. ScreenColNum-(TrackedCoord.X+ansi_param[0]-1));
  517. }
  518. lclear(cs, lp, TrackedCoord.X-1, TrackedCoord.Y-1, ansi_param[0],
  519. SA_BONW);
  520. break;
  521. case ANSI_IL: /* insert line */
  522. ansi_param[0] = range(ansi_param[0], 1, 1,
  523. (ScreenRowNum - TrackedCoord.Y) + 1);
  524. /* copy lines down */
  525. if ( TrackedCoord.Y + ansi_param[0] <= ScreenRowNum ) {
  526. lcopy(cs, lp, 0, TrackedCoord.Y-1, 0,
  527. TrackedCoord.Y+ansi_param[0]-1,
  528. ScreenColNum*(ScreenRowNum-(TrackedCoord.Y+ansi_param[0]-1)));
  529. }
  530. /* clear new stuff */
  531. lclear(cs, lp, 0, TrackedCoord.Y-1, ScreenColNum * ansi_param[0],
  532. SA_BONW);
  533. break;
  534. #endif
  535. case ANSI_SU: /* scroll up */
  536. ansi_param[0] = (short) range(ansi_param[0], 1, 1, ScreenRowNum);
  537. lscroll(cs, ansi_param[0]);
  538. break;
  539. case ANSI_SD: /* scroll down */
  540. {
  541. int i = -range(ansi_param[0], 1, 1, ScreenRowNum);
  542. lscroll(cs, i);
  543. }
  544. break;
  545. default:
  546. return (DWORD) 0;
  547. }
  548. return (Rc);
  549. }
  550. /*
  551. ** range(val, default, min, max) - restrict a value to a range, or supply a
  552. ** default
  553. ** val is the value to be restricted.
  554. ** default is the value to be returned if val is zero
  555. ** min is the minimum value
  556. ** max is the maximum value
  557. */
  558. int
  559. range(int val, int def, int min, int max)
  560. {
  561. if ( val == 0 )
  562. return def;
  563. if ( val < min )
  564. return min;
  565. if ( val > max )
  566. return max;
  567. return val;
  568. }
  569. DWORD
  570. SetTTYAttr(IN HANDLE cs, IN USHORT AnsiParm)
  571. {
  572. WORD NewAttr, LastAttr = ansi_attr; /* attribute of TTY */
  573. BOOL Rc;
  574. if ( AnsiParm == 0 ) { // BUGBUG ? or the default is according to Win
  575. ansi_base = 0x07; /* white on black */
  576. ansi_reverse = 0x00;
  577. } else if ( AnsiParm == 7 ) {
  578. ansi_reverse = 1;
  579. } else if ( ((AnsiParm >= 30) && (AnsiParm <= 37)) ||
  580. ((AnsiParm >= 40) && (AnsiParm <= 47)) ) {
  581. if ( AnsiParm >= 40 )
  582. ansi_base = (BYTE) ((ansi_base & 0x0F) | ( 4 << ColorTable[AnsiParm%10]));
  583. else
  584. ansi_base = (BYTE) ((ansi_base & 0xF0) | ColorTable[AnsiParm%10]);
  585. } else if ( AnsiParm == 8 ) {
  586. #if 0
  587. ansi_cancel = 1;
  588. #endif
  589. } else if ( AnsiParm == 1 ) {
  590. #if 0
  591. ansi_intensity = 1;
  592. #endif
  593. } else if ( AnsiParm == 4 ) {
  594. #if 0
  595. ansi_bold = 1;
  596. #endif
  597. } else if ( AnsiParm == 5 ) {
  598. #if 0
  599. ansi_underscore = 1;
  600. #endif
  601. }
  602. if ( ansi_reverse )
  603. NewAttr = (BYTE) (((ansi_base & 0x0F) << 4 ) |
  604. ((ansi_base & 0xF0) >> 4 ));
  605. else
  606. NewAttr = ansi_base;
  607. if ( LastAttr != NewAttr ) {
  608. /* new attribute */
  609. if ( (Rc = !SetConsoleTextAttribute(cs, (NewAttr))) != 0 ) {
  610. return (Rc);
  611. } else {
  612. ansi_attr = NewAttr;
  613. }
  614. }
  615. return (NO_ERROR);
  616. }
  617. DWORD
  618. TTYConBeep(void)
  619. {
  620. DWORD NumWritten, Rc;
  621. CHAR BeepChar = '\a';
  622. Rc = !WriteConsoleA(TTYcs, &BeepChar, 1, &NumWritten, NULL);
  623. return(Rc);
  624. }
  625. DWORD
  626. TTYFlushStr(USHORT *newcoord, const char *call)
  627. {
  628. DWORD NumWritten;
  629. BOOL Success;
  630. COORD coordDest, coord;
  631. SMALL_RECT ScrollRect;
  632. CHAR_INFO ScrollChar;
  633. if (TTYNumBytes) {
  634. if (TrackedCoord.X > ScreenColNum) {
  635. // Handle cursor tracking of text wrap-around
  636. if (OutputModeFlags & ENABLE_WRAP_AT_EOL_OUTPUT) {
  637. #if 0
  638. TrackedCoord.Y += ((CurrentCoord.X + TrackedCoord.X)
  639. / ScreenColNum);
  640. #else
  641. TrackedCoord.Y += ((TrackedCoord.X) / ScreenColNum);
  642. #endif
  643. TrackedCoord.X = (TrackedCoord.X % ScreenColNum);
  644. } else {
  645. TrackedCoord.X = ScreenColNum;
  646. }
  647. *newcoord = 1;
  648. } else if (TrackedCoord.X < 1) {
  649. TrackedCoord.X = 1;
  650. #if 0
  651. *newcoord = 1;
  652. #endif
  653. }
  654. }
  655. //
  656. // Handle scrolling when printing beyond bottom of screen
  657. //
  658. if (TrackedCoord.Y > ScreenRowNum) {
  659. #if 0
  660. ScrollRect.Top = TrackedCoord.Y - ScreenRowNum;
  661. ScrollRect.Bottom = (SHORT)ScreenRowNum;
  662. ScrollRect.Left = 0;
  663. ScrollRect.Right = (SHORT)ScreenColNum;
  664. coordDest.X = 0;
  665. coordDest.Y = 0;
  666. ScrollChar.Attributes = (ansi_attr);
  667. ScrollChar.Char.AsciiChar = ' ';
  668. Success = ScrollConsoleScreenBufferA(TTYcs, &ScrollRect, NULL,
  669. coordDest, &ScrollChar);
  670. if (!Success) {
  671. KdPrint(("POSIX: ScrollConsole: 0x%x\n", GetLastError()));
  672. return Success;
  673. }
  674. #else
  675. lscroll(TTYcs, TrackedCoord.Y - ScreenRowNum);
  676. #endif
  677. if (TTYNumBytes) {
  678. coord.X = CurrentCoord.X - 1;
  679. coord.Y = ScreenRowNum - (TrackedCoord.Y - ScreenRowNum) - 1;
  680. Success = WriteConsoleOutputCharacterA(TTYcs, (LPSTR)TTYTextPtr,
  681. TTYNumBytes, coord, &NumWritten);
  682. if (!Success) {
  683. KdPrint(("POSIX: WriteConsoleOutputChar: 0x%x\n", GetLastError()));
  684. return Success;
  685. }
  686. TTYNumBytes = 0;
  687. }
  688. TrackedCoord.Y = ScreenRowNum;
  689. #if 0
  690. *newcoord = 1;
  691. #endif
  692. } else if (TTYNumBytes) {
  693. // Not printing beyond bottom of screen.
  694. Success = WriteConsoleA(TTYcs, (LPSTR) TTYTextPtr, TTYNumBytes,
  695. &NumWritten, NULL);
  696. if (!Success) {
  697. return Success;
  698. }
  699. TTYNumBytes = 0;
  700. }
  701. if (*newcoord) {
  702. if (CarriageReturn) {
  703. CarriageReturn = 0;
  704. TrackedCoord.X = 1;
  705. }
  706. coord.X = TrackedCoord.X - 1;
  707. coord.Y = TrackedCoord.Y - 1;
  708. Success = SetConsoleCursorPosition(TTYcs, coord);
  709. if (!Success) {
  710. return Success;
  711. }
  712. *newcoord = 0;
  713. }
  714. CurrentCoord = TrackedCoord;
  715. return (DWORD)0;
  716. }