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.

890 lines
22 KiB

  1. /* $Header: /nw/tony/src/stevie/src/RCS/os2.c,v 1.7 89/08/07 05:49:19 tony Exp $
  2. *
  3. * NT System-dependent routines.
  4. */
  5. /*
  6. * Revision history:
  7. *
  8. * 6/1/93 - Joe Mitchell
  9. * Add support to create a new screen buffer. This fixes the
  10. * problem of scrolling the number of lines that "screen buffer size
  11. * height" is set to when a vertical scroll bar is present.
  12. * Allow filenames longer than 8.3 for use with HPFS/NTFS.
  13. */
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <signal.h>
  19. #include <conio.h>
  20. #include <io.h>
  21. #include <direct.h>
  22. #undef max
  23. #undef min
  24. #include "stevie.h"
  25. #define MAX_VK 0x7f
  26. #define UCHR unsigned char // so table looks nice
  27. UCHR RegularTable[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  28. /* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  29. /* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  30. /* 18 */ 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00,
  31. /* 20 */ 0x00, K_PU, K_PD, K_EN, K_HO, K_LE, K_UP, K_RI,
  32. /* 28 */ K_DO, 0x00, 0x00, 0x00, 0x00, K_IN, K_DE, 0x00,
  33. /* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  34. /* 38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  35. /* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  36. /* 48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  37. /* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  38. /* 58 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  39. /* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  40. /* 68 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  41. /* 70 */ K_F1, K_F2, K_F3, K_F4, K_F5, K_F6, K_F7, K_F8,
  42. /* 78 */ K_F9, K_FA, K_FB, K_FC, 0x00, 0x00, 0x00, 0x00 };
  43. UCHR ShiftedTable[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  44. /* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  45. /* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  46. /* 18 */ 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00,
  47. /* 20 */ 0x00, K_PU, K_PD, K_EN, K_HO, K_LE, K_UP, K_RI,
  48. /* 28 */ K_DO, 0x00, 0x00, 0x00, 0x00, K_IN, K_DE, 0x00,
  49. /* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  50. /* 38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51. /* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52. /* 48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  53. /* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  54. /* 58 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  55. /* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  56. /* 68 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  57. /* 70 */ K_S1, K_S2, K_S3, K_S4, K_S5, K_S6, K_S7, K_S8,
  58. /* 78 */ K_S9, K_SA, K_SB, K_SC, 0x00, 0x00, 0x00, 0x00 };
  59. UCHR ControlTable[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  60. /* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  61. /* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  62. /* 18 */ 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, K_CG, 0x00,
  63. /* 20 */ 0x00, K_PU, K_PD, K_EN, K_HO, K_LE, K_UP, K_RI,
  64. /* 28 */ K_DO, 0x00, 0x00, 0x00, 0x00, K_IN, K_DE, 0x00,
  65. /* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  66. /* 38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67. /* 40 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  68. /* 48 */ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  69. /* 50 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  70. /* 58 */ 0x18, 0x19, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
  71. /* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  72. /* 68 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  73. /* 70 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  74. /* 78 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  75. #define ALT_PRESSED (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)
  76. #define CTL_PRESSED (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)
  77. #define CONTROL_ALT (ALT_PRESSED | CTL_PRESSED)
  78. #define OMODE (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT)
  79. static HANDLE CurrConsole;
  80. static HANDLE ViConsole,ConsoleIn;
  81. static HANDLE PrevConsole; // [jrm 6/93] Save previous screen buffer
  82. static DWORD OldConsoleMode;
  83. static DWORD ViConsoleInputMode;
  84. /*
  85. * inchar() - get a character from the keyboard
  86. */
  87. int
  88. inchar()
  89. {
  90. INPUT_RECORD InputRec;
  91. DWORD NumRead;
  92. got_int = FALSE;
  93. flushbuf(); /* flush any pending output */
  94. while(1) { /* loop until we get a valid console event */
  95. ReadConsoleInput(ConsoleIn,&InputRec,1,&NumRead);
  96. if((InputRec.EventType == KEY_EVENT)
  97. && (InputRec.Event.KeyEvent.bKeyDown))
  98. {
  99. KEY_EVENT_RECORD *KE = &InputRec.Event.KeyEvent;
  100. unsigned char *Table;
  101. if(KE->dwControlKeyState & ALT_PRESSED) {
  102. continue; // no ALT keys allowed.
  103. } else if(KE->dwControlKeyState & CTL_PRESSED) {
  104. Table = ControlTable;
  105. } else if(KE->uChar.AsciiChar) { // no control, no alt
  106. return(KE->uChar.AsciiChar);
  107. } else if(KE->dwControlKeyState & SHIFT_PRESSED) {
  108. Table = ShiftedTable;
  109. } else {
  110. Table = RegularTable;
  111. }
  112. if((KE->wVirtualKeyCode > MAX_VK) || !Table[KE->wVirtualKeyCode]) {
  113. continue;
  114. }
  115. return(Table[KE->wVirtualKeyCode]);
  116. }
  117. }
  118. }
  119. #if 0
  120. switch (c = _getch()) {
  121. case 0x1e:
  122. return K_CGRAVE;
  123. case 0: /* special key */
  124. if (State != NORMAL) {
  125. c = _getch(); /* throw away next char */
  126. continue; /* and loop for another char */
  127. }
  128. switch (c = _getch()) {
  129. case 0x50:
  130. return K_DARROW;
  131. case 0x48:
  132. return K_UARROW;
  133. case 0x4b:
  134. return K_LARROW;
  135. case 0x4d:
  136. return K_RARROW;
  137. case 0x52:
  138. return K_INSERT;
  139. case 0x47:
  140. stuffin("1G");
  141. return -1;
  142. case 0x4f:
  143. stuffin("G");
  144. return -1;
  145. case 0x51:
  146. stuffin(mkstr(CTRL('F')));
  147. return -1;
  148. case 0x49:
  149. stuffin(mkstr(CTRL('B')));
  150. return -1;
  151. /*
  152. * Hard-code some useful function key macros.
  153. */
  154. case 0x3b: /* F1 */
  155. stuffin(":N\n");
  156. return -1;
  157. case 0x54: /* SF1 */
  158. stuffin(":N!\n");
  159. return -1;
  160. case 0x3c: /* F2 */
  161. stuffin(":n\n");
  162. return -1;
  163. case 0x55: /* SF2 */
  164. stuffin(":n!\n");
  165. return -1;
  166. case 0x3d: /* F3 */
  167. stuffin(":e #\n");
  168. return -1;
  169. case 0x3e: /* F4 */
  170. stuffin(":rew\n");
  171. return -1;
  172. case 0x57: /* SF4 */
  173. stuffin(":rew!\n");
  174. return -1;
  175. case 0x3f: /* F5 */
  176. stuffin("[[");
  177. return -1;
  178. case 0x40: /* F6 */
  179. stuffin("]]");
  180. return -1;
  181. case 0x41: /* F7 - explain C declaration */
  182. stuffin("yyp^iexplain \033!!cdecl\n");
  183. return -1;
  184. case 0x42: /* F8 - declare C variable */
  185. stuffin("yyp!!cdecl\n");
  186. return -1;
  187. case 0x43: /* F9 */
  188. stuffin(":x\n");
  189. return -1;
  190. case 0x44: /* F10 */
  191. stuffin(":help\n");
  192. return -1;
  193. default:
  194. break;
  195. }
  196. break;
  197. default:
  198. return c;
  199. }
  200. }
  201. }
  202. #endif
  203. #define BSIZE 2048
  204. static char outbuf[BSIZE];
  205. static int bpos = 0;
  206. DWORD CursorSize;
  207. DWORD OrgCursorSize;
  208. void
  209. flushbuf()
  210. {
  211. BOOL st; // [jrm 6/93]
  212. DWORD count; // [jrm 6/93]
  213. //
  214. // [jrm 6/93] Use WriteFile rather than "write" to take advantage of
  215. // new screen buffer.
  216. //
  217. if (bpos != 0) {
  218. //jrm write(1, outbuf, bpos);
  219. st = WriteFile(CurrConsole, outbuf, bpos, &count, NULL);
  220. if (!st) {
  221. fprintf(stderr, "vi: Error calling WriteFile");
  222. }
  223. }
  224. bpos = 0;
  225. }
  226. /*
  227. * Macro to output a character. Used within this file for speed.
  228. */
  229. #define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
  230. /*
  231. * Function version for use outside this file.
  232. */
  233. void
  234. outchar(c)
  235. register char c;
  236. {
  237. outbuf[bpos++] = c;
  238. if (bpos >= BSIZE)
  239. flushbuf();
  240. }
  241. /*
  242. * outstr(s) - write a string to the console
  243. */
  244. void
  245. outstr(s)
  246. register char *s;
  247. {
  248. while (*s) {
  249. outone(*s++);
  250. }
  251. }
  252. void
  253. beep()
  254. {
  255. Beep(500,50); // 500Hz for 1/4 sec
  256. }
  257. void sleep(n)
  258. int n;
  259. {
  260. Sleep(1000L * n);
  261. }
  262. void
  263. delay()
  264. {
  265. flushbuf();
  266. Sleep(300L);
  267. }
  268. void
  269. sig()
  270. {
  271. // signal(SIGINT, sig);
  272. got_int = TRUE;
  273. }
  274. WORD Attribute;
  275. WORD HighlightAttribute;
  276. void
  277. useviconsole()
  278. {
  279. flushbuf();
  280. SetConsoleActiveScreenBuffer(CurrConsole = ViConsole);
  281. CursorSize = P(P_CS);
  282. VisibleCursor();
  283. FlushConsoleInputBuffer(ConsoleIn);
  284. SetConsoleMode(ConsoleIn,ViConsoleInputMode);
  285. }
  286. void
  287. usecmdconsole()
  288. {
  289. flushbuf();
  290. SetConsoleActiveScreenBuffer(CurrConsole = PrevConsole);
  291. CursorSize = OrgCursorSize;
  292. VisibleCursor();
  293. FlushConsoleInputBuffer(ConsoleIn);
  294. SetConsoleMode(ConsoleIn,OldConsoleMode);
  295. }
  296. void
  297. windinit()
  298. {
  299. COORD coord;
  300. CONSOLE_SCREEN_BUFFER_INFO Info;
  301. CONSOLE_CURSOR_INFO Info2;
  302. DWORD NumRead;
  303. ConsoleIn=GetStdHandle(STD_INPUT_HANDLE);
  304. //
  305. // [jrm 6/93] Create a new screen buffer. This fixes the scroll problem
  306. // when there is a vertical scroll bar.
  307. //
  308. PrevConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  309. CurrConsole =
  310. ViConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
  311. FILE_SHARE_READ | FILE_SHARE_WRITE,
  312. NULL,
  313. CONSOLE_TEXTMODE_BUFFER,
  314. NULL);
  315. if (ViConsole == INVALID_HANDLE_VALUE) {
  316. printf("CreateConsoleScreenBuffer failed in windinit\n");
  317. printf("LastError = 0x%lx\n", GetLastError());
  318. exit(0);
  319. }
  320. SetConsoleActiveScreenBuffer(ViConsole);
  321. SetConsoleMode(ViConsole, OMODE);
  322. GetConsoleScreenBufferInfo(ViConsole,&Info);
  323. P(P_CO) = Columns = Info.dwSize.X;
  324. P(P_LI) = Rows = Info.dwSize.Y;
  325. P(P_SS) = Rows / 2;
  326. GetConsoleCursorInfo(ViConsole,&Info2);
  327. P(P_CS) = OrgCursorSize = CursorSize = Info2.dwSize;
  328. coord.X = coord.Y = 0;
  329. ReadConsoleOutputAttribute(ViConsole,
  330. &Attribute,
  331. sizeof(Attribute)/sizeof(WORD),
  332. coord,
  333. &NumRead);
  334. GetConsoleMode(ConsoleIn,&OldConsoleMode);
  335. ViConsoleInputMode = OldConsoleMode & ~(ENABLE_PROCESSED_INPUT |
  336. ENABLE_LINE_INPUT |
  337. ENABLE_ECHO_INPUT |
  338. ENABLE_WINDOW_INPUT |
  339. ENABLE_MOUSE_INPUT
  340. );
  341. SetConsoleMode(ConsoleIn,ViConsoleInputMode);
  342. setviconsoletitle();
  343. // signal(SIGINT, sig);
  344. //
  345. // Calculate a reasonable default search highlight
  346. // by flipping colors for the current screen.
  347. //
  348. HighlightAttribute = ((Attribute & 0xff00) | ((Attribute & 0x00f0) >> 4) |
  349. ((Attribute & 0x000f) << 4));
  350. }
  351. void
  352. setviconsoletitle()
  353. {
  354. char title[2000];
  355. strcpy(title, Appname);
  356. if (Filename) {
  357. strcat(title, " ");
  358. strcat(title, Filename);
  359. }
  360. SetConsoleTitle(title);
  361. }
  362. void
  363. wchangescreen(NewRows, NewColumns)
  364. int NewRows;
  365. int NewColumns;
  366. {
  367. #if 0
  368. CONSOLE_SCREEN_BUFFER_INFO info;
  369. #endif
  370. SMALL_RECT screenRect;
  371. COORD screenSize;
  372. #if 0
  373. GetConsoleScreenBufferInfo(ViConsole,&info);
  374. info.dwSize.X = NewRows;
  375. info.dwSize.Y = NewColumns;
  376. #endif
  377. screenSize.X = (short)NewColumns;
  378. screenSize.Y = (short)NewRows;
  379. SetConsoleScreenBufferSize(ViConsole, screenSize);
  380. screenRect.Top = 0;
  381. screenRect.Left = 0;
  382. screenRect.Right = NewColumns - 1;
  383. screenRect.Bottom = NewRows - 1;
  384. SetConsoleWindowInfo(ViConsole, TRUE, &screenRect);
  385. }
  386. void
  387. windexit(r)
  388. int r;
  389. {
  390. usecmdconsole();
  391. exit(r);
  392. }
  393. void
  394. windgoto(r, c)
  395. register int r, c;
  396. {
  397. COORD coord;
  398. flushbuf();
  399. coord.X = (SHORT)c;
  400. coord.Y = (SHORT)r;
  401. SetConsoleCursorPosition(ViConsole,coord);
  402. }
  403. FILE *
  404. fopenb(fname, mode)
  405. char *fname;
  406. char *mode;
  407. {
  408. char modestr[16];
  409. sprintf(modestr, "%sb", mode);
  410. return fopen(fname, modestr);
  411. }
  412. #define PSIZE 128
  413. /*
  414. * fixname(s) - fix up a dos name
  415. *
  416. * Takes a name like:
  417. *
  418. * d:\x\y\z\base.ext
  419. *
  420. * and trims 'base' to 8 characters, and 'ext' to 3.
  421. */
  422. char *
  423. fixname(s)
  424. char *s;
  425. {
  426. static char f[PSIZE];
  427. char base[32];
  428. char ext[32];
  429. char *p;
  430. int d = 0;
  431. int i;
  432. strcpy(f, s);
  433. if (f[1] == ':') {
  434. if (('a' <= f[0] && f[0] <= 'z') ||
  435. ('A' <= f[0] && f[0] <= 'Z')) {
  436. d = 2;
  437. }
  438. }
  439. for (i=0; i < PSIZE ;i++)
  440. if (f[d+i] == '/')
  441. f[d+i] = '\\';
  442. /*
  443. * Split the name into directory, base, extension.
  444. */
  445. if ((p = strrchr(f+d, '\\')) != NULL) {
  446. strcpy(base, p+1);
  447. p[1] = '\0';
  448. } else {
  449. strcpy(base, f+d);
  450. f[d] = '\0';
  451. }
  452. if ((p = strchr(base, '.')) != NULL) {
  453. strcpy(ext, p+1);
  454. *p = '\0';
  455. } else
  456. ext[0] = '\0';
  457. #if 0 /* [jrm 6/93] Allow longer filenames for HPFS/NTFS */
  458. /*
  459. * Trim the base name if necessary.
  460. */
  461. if (strlen(base) > 8)
  462. base[8] = '\0';
  463. if (strlen(ext) > 3)
  464. ext[3] = '\0';
  465. #endif
  466. /*
  467. * Paste it all back together
  468. */
  469. strcat(f, base);
  470. strcat(f, ".");
  471. strcat(f, ext);
  472. return f;
  473. }
  474. LONG
  475. mysystem(cmd, async)
  476. char *cmd;
  477. int async;
  478. {
  479. STARTUPINFO si;
  480. PROCESS_INFORMATION pi;
  481. BOOL ok;
  482. DWORD status;
  483. char *cmdline;
  484. char title[200];
  485. char *title2;
  486. char *shell = getenv("SHELL");
  487. if (!shell) {
  488. shell = getenv("COMSPEC");
  489. }
  490. if (!shell) {
  491. shell = "cmd.exe";
  492. }
  493. if (!cmd) {
  494. return !_access(shell,0);
  495. }
  496. if (!*cmd) {
  497. cmdline = _strdup(shell);
  498. } else {
  499. cmdline = malloc(strlen(shell) + strlen(cmd) + 5);
  500. strcpy(cmdline, shell);
  501. strcat(cmdline, " /c ");
  502. strcat(cmdline, cmd);
  503. }
  504. memset(&si, 0, sizeof(si));
  505. si.cb = sizeof(si);
  506. if (async) {
  507. si.dwFlags = STARTF_USESHOWWINDOW;
  508. si.wShowWindow = SW_SHOWNA;
  509. }
  510. if (!async) {
  511. GetConsoleTitle(title, sizeof(title));
  512. title2 = malloc(strlen(title) + 4 + strlen(cmdline));
  513. strcpy(title2, title);
  514. strcat(title2, " - ");
  515. strcat(title2, cmdline);
  516. SetConsoleTitle(title2);
  517. free(title2);
  518. }
  519. ok = CreateProcess(NULL,
  520. cmdline,
  521. NULL,
  522. NULL,
  523. FALSE,
  524. CREATE_NEW_PROCESS_GROUP |
  525. (async ? CREATE_NEW_CONSOLE : 0),
  526. NULL,
  527. NULL,
  528. &si,
  529. &pi
  530. );
  531. free(cmdline);
  532. if (!ok) {
  533. status = (DWORD)-1;
  534. } else {
  535. if (async) {
  536. status = 0;
  537. } else {
  538. SetConsoleCtrlHandler(NULL, TRUE);
  539. WaitForSingleObject(pi.hProcess, INFINITE);
  540. SetConsoleCtrlHandler(NULL, FALSE);
  541. GetExitCodeProcess(pi.hProcess, &status);
  542. }
  543. CloseHandle(pi.hProcess);
  544. CloseHandle(pi.hThread);
  545. }
  546. if (!async) {
  547. SetConsoleTitle(title);
  548. }
  549. return (LONG)status;
  550. }
  551. void
  552. doshell(cmd, async)
  553. char *cmd;
  554. int async;
  555. {
  556. int c;
  557. if (async) {
  558. mysystem(cmd? cmd : "", async);
  559. } else {
  560. usecmdconsole();
  561. if (!cmd) {
  562. mysystem("", async);
  563. } else {
  564. outchar('!');
  565. outstr(cmd);
  566. outchar('\n');
  567. flushbuf();
  568. mysystem(cmd, async);
  569. }
  570. c = wait_return0();
  571. outchar('\n');
  572. useviconsole();
  573. if (c == ':') {
  574. outchar(NL);
  575. docmdln(getcmdln(c));
  576. } else {
  577. screenclear();
  578. }
  579. updatescreen();
  580. }
  581. }
  582. void
  583. dochdir(arg)
  584. char *arg;
  585. {
  586. if (_chdir(arg)) {
  587. emsg("bad directory");
  588. }
  589. }
  590. /*
  591. NT console stuff
  592. */
  593. static DWORD RowSave,ColSave;
  594. void Scroll(int t,int l,int b,int r,int Row,int Col)
  595. {
  596. SMALL_RECT ScrollRect;
  597. COORD Coord;
  598. CHAR_INFO CharInfo;
  599. ScrollRect.Left = (SHORT)l;
  600. ScrollRect.Right = (SHORT)r;
  601. ScrollRect.Top = (SHORT)t;
  602. ScrollRect.Bottom = (SHORT)b;
  603. Coord.X = (SHORT)Col;
  604. Coord.Y = (SHORT)Row;
  605. CharInfo.Char.AsciiChar = ' ';
  606. CharInfo.Attributes = Attribute;
  607. ScrollConsoleScreenBuffer(ViConsole,&ScrollRect,NULL,Coord,&CharInfo);
  608. }
  609. void EraseLine(void)
  610. {
  611. CONSOLE_SCREEN_BUFFER_INFO Info;
  612. DWORD NumWritten;
  613. flushbuf();
  614. GetConsoleScreenBufferInfo(ViConsole,&Info);
  615. Info.dwCursorPosition.X = 0;
  616. SetConsoleCursorPosition(ViConsole,Info.dwCursorPosition);
  617. FillConsoleOutputCharacter(ViConsole,' ',Columns,Info.dwCursorPosition, &NumWritten);
  618. }
  619. void EraseNLinesAtRow(int n,int row)
  620. {
  621. COORD coord;
  622. DWORD NumWritten;
  623. flushbuf();
  624. coord.X = 0;
  625. coord.Y = (short)row;
  626. FillConsoleOutputCharacter(ViConsole,' ',n*Columns,coord, &NumWritten);
  627. }
  628. void ClearDisplay(void)
  629. {
  630. COORD c;
  631. DWORD NumWritten;
  632. flushbuf();
  633. c.X = c.Y = 0;
  634. SetConsoleCursorPosition(ViConsole,c);
  635. FillConsoleOutputCharacter(ViConsole,' ',Rows*Columns,c, &NumWritten);
  636. }
  637. void SaveCursor(void)
  638. {
  639. CONSOLE_SCREEN_BUFFER_INFO Info;
  640. flushbuf();
  641. GetConsoleScreenBufferInfo(ViConsole,&Info);
  642. ColSave = Info.dwCursorPosition.X;
  643. RowSave = Info.dwCursorPosition.Y;
  644. }
  645. void RestoreCursor(void)
  646. {
  647. COORD c;
  648. flushbuf();
  649. c.X = (SHORT)ColSave;
  650. c.Y = (SHORT)RowSave;
  651. SetConsoleCursorPosition(ViConsole,c);
  652. }
  653. void InvisibleCursor(void)
  654. {
  655. CONSOLE_CURSOR_INFO Info;
  656. flushbuf();
  657. Info.dwSize = CursorSize;
  658. Info.bVisible = FALSE;
  659. SetConsoleCursorInfo(CurrConsole,&Info);
  660. }
  661. void VisibleCursor(void)
  662. {
  663. CONSOLE_CURSOR_INFO Info;
  664. flushbuf();
  665. Info.dwSize = CursorSize;
  666. Info.bVisible = TRUE;
  667. SetConsoleCursorInfo(CurrConsole,&Info);
  668. }
  669. int CurHighlightLine = -1;
  670. int CurHighlightColumn = -1;
  671. int CurHighlightLength = -1;
  672. char CurHighlightString[512];
  673. int
  674. StrLength(char *cp)
  675. {
  676. int length = 0;
  677. int diff;
  678. while (*cp) {
  679. if (*cp == '\t') {
  680. diff = P(P_TS) - (length % P(P_TS));
  681. length += diff;
  682. } else {
  683. length++;
  684. }
  685. cp++;
  686. }
  687. return length;
  688. }
  689. void HighlightLine( int col, unsigned long line, char *string )
  690. {
  691. COORD dwWriteCoord;
  692. DWORD dwNumWritten;
  693. int length;
  694. if (P(P_HS) == FALSE)
  695. return;
  696. length = StrLength(string);
  697. if (length > Columns) {
  698. length = Columns;
  699. }
  700. if (col >= (Columns - 1)) {
  701. col--;
  702. }
  703. dwWriteCoord.X = CurHighlightColumn = col;
  704. dwWriteCoord.Y = CurHighlightLine = line;
  705. FillConsoleOutputAttribute(ViConsole,
  706. HighlightAttribute,
  707. length,
  708. dwWriteCoord,
  709. &dwNumWritten);
  710. updateline();
  711. #if 0
  712. WriteConsoleOutputCharacter(ViConsole,
  713. string,
  714. length,
  715. dwWriteCoord,
  716. &dwNumWritten);
  717. #endif
  718. strcpy(CurHighlightString, string);
  719. CurHighlightLength = length;
  720. }
  721. #define FOREGROUND_WHITE (FOREGROUND_BLUE | \
  722. FOREGROUND_GREEN | \
  723. FOREGROUND_RED | \
  724. FOREGROUND_INTENSITY)
  725. void RemoveHighlight( int col, unsigned long line, int length, char *string )
  726. {
  727. COORD dwWriteCoord;
  728. DWORD dwNumWritten;
  729. length = StrLength(string);
  730. if (length > Columns) {
  731. length = Columns;
  732. }
  733. dwWriteCoord.X = (short)col;
  734. dwWriteCoord.Y = (int)line;
  735. FillConsoleOutputAttribute(ViConsole,
  736. Attribute,
  737. length,
  738. dwWriteCoord,
  739. &dwNumWritten);
  740. updateline();
  741. #if 0
  742. WriteConsoleOutputCharacter(ViConsole,
  743. string,
  744. length,
  745. dwWriteCoord,
  746. &dwNumWritten);
  747. #endif
  748. }
  749. void HighlightCheck()
  750. {
  751. if (P(P_HS) == FALSE)
  752. return;
  753. if (CurHighlightLine != -1) {
  754. RemoveHighlight(CurHighlightColumn,
  755. CurHighlightLine,
  756. CurHighlightLength,
  757. CurHighlightString);
  758. CurHighlightLine = -1;
  759. CurHighlightColumn = -1;
  760. }
  761. }