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.

890 lines
23 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. /*
  413. * fixname(s) - fix up a dos name
  414. *
  415. * Takes a name like:
  416. *
  417. * d:\x\y\z\base.ext
  418. *
  419. * and trims 'base' to 8 characters, and 'ext' to 3.
  420. */
  421. char *
  422. fixname(char *s)
  423. {
  424. static char f[_MAX_PATH+1];
  425. char base[_MAX_FNAME+1];
  426. char ext[_MAX_EXT+1];
  427. char *p;
  428. int d = 0;
  429. int i, stringsize, fBackslashFound=FALSE;
  430. stringsize = strlen(s);
  431. if (stringsize > _MAX_PATH) {
  432. return NULL;
  433. }
  434. ZeroMemory(f, sizeof(f));
  435. memcpy(f, s, stringsize);
  436. if (f[1] == ':') {
  437. if (('a' <= f[0] && f[0] <= 'z') ||
  438. ('A' <= f[0] && f[0] <= 'Z')) {
  439. d = 2;
  440. }
  441. }
  442. for (i=0; d+i < stringsize ;i++) {
  443. if (f[d+i] == '/')
  444. f[d+i] = '\\';
  445. }
  446. /*
  447. * Split the name into directory, base, extension.
  448. */
  449. if ((p = strrchr(f+d, '\\')) != NULL) {
  450. if ((strlen(p+1) > sizeof(base)-1))
  451. return NULL;
  452. strcpy(base, p+1);
  453. p[1] = '\0';
  454. } else {
  455. if ((strlen(f+d) > sizeof(base)-1))
  456. return NULL;
  457. strcpy(base, f+d);
  458. f[d] = '\0';
  459. }
  460. if ((p = strchr(base, '.')) != NULL) {
  461. if ((strlen(p+1) > sizeof(ext)-1))
  462. return NULL;
  463. strcpy(ext, p+1);
  464. *p = '\0';
  465. } else
  466. ext[0] = '\0';
  467. /*
  468. * Paste it all back together
  469. */
  470. strcat(f, base);
  471. strcat(f, ".");
  472. strcat(f, ext);
  473. return f;
  474. }
  475. LONG
  476. mysystem(cmd, async)
  477. char *cmd;
  478. int async;
  479. {
  480. STARTUPINFO si;
  481. PROCESS_INFORMATION pi;
  482. BOOL ok;
  483. DWORD status;
  484. char *cmdline;
  485. char title[200];
  486. char *title2;
  487. char *shell = getenv("SHELL");
  488. if (!shell) {
  489. shell = getenv("COMSPEC");
  490. }
  491. if (!shell) {
  492. shell = "cmd.exe";
  493. }
  494. if (!cmd) {
  495. return !_access(shell,0);
  496. }
  497. if (!*cmd) {
  498. cmdline = _strdup(shell);
  499. } else {
  500. cmdline = malloc(strlen(shell) + strlen(cmd) + 5);
  501. strcpy(cmdline, shell);
  502. strcat(cmdline, " /c ");
  503. strcat(cmdline, cmd);
  504. }
  505. memset(&si, 0, sizeof(si));
  506. si.cb = sizeof(si);
  507. if (async) {
  508. si.dwFlags = STARTF_USESHOWWINDOW;
  509. si.wShowWindow = SW_SHOWNA;
  510. }
  511. if (!async) {
  512. GetConsoleTitle(title, sizeof(title));
  513. title2 = malloc(strlen(title) + 4 + strlen(cmdline));
  514. strcpy(title2, title);
  515. strcat(title2, " - ");
  516. strcat(title2, cmdline);
  517. SetConsoleTitle(title2);
  518. free(title2);
  519. }
  520. ok = CreateProcess(NULL,
  521. cmdline,
  522. NULL,
  523. NULL,
  524. FALSE,
  525. CREATE_NEW_PROCESS_GROUP |
  526. (async ? CREATE_NEW_CONSOLE : 0),
  527. NULL,
  528. NULL,
  529. &si,
  530. &pi
  531. );
  532. free(cmdline);
  533. if (!ok) {
  534. status = (DWORD)-1;
  535. } else {
  536. if (async) {
  537. status = 0;
  538. } else {
  539. SetConsoleCtrlHandler(NULL, TRUE);
  540. WaitForSingleObject(pi.hProcess, INFINITE);
  541. SetConsoleCtrlHandler(NULL, FALSE);
  542. GetExitCodeProcess(pi.hProcess, &status);
  543. }
  544. CloseHandle(pi.hProcess);
  545. CloseHandle(pi.hThread);
  546. }
  547. if (!async) {
  548. SetConsoleTitle(title);
  549. }
  550. return (LONG)status;
  551. }
  552. void
  553. doshell(cmd, async)
  554. char *cmd;
  555. int async;
  556. {
  557. int c;
  558. if (async) {
  559. mysystem(cmd? cmd : "", async);
  560. } else {
  561. usecmdconsole();
  562. if (!cmd) {
  563. mysystem("", async);
  564. } else {
  565. outchar('!');
  566. outstr(cmd);
  567. outchar('\n');
  568. flushbuf();
  569. mysystem(cmd, async);
  570. }
  571. c = wait_return0();
  572. outchar('\n');
  573. useviconsole();
  574. if (c == ':') {
  575. outchar(NL);
  576. docmdln(getcmdln(c));
  577. } else {
  578. screenclear();
  579. }
  580. updatescreen();
  581. }
  582. }
  583. void
  584. dochdir(arg)
  585. char *arg;
  586. {
  587. if (_chdir(arg)) {
  588. emsg("bad directory");
  589. }
  590. }
  591. /*
  592. NT console stuff
  593. */
  594. static DWORD RowSave,ColSave;
  595. void Scroll(int t,int l,int b,int r,int Row,int Col)
  596. {
  597. SMALL_RECT ScrollRect;
  598. COORD Coord;
  599. CHAR_INFO CharInfo;
  600. ScrollRect.Left = (SHORT)l;
  601. ScrollRect.Right = (SHORT)r;
  602. ScrollRect.Top = (SHORT)t;
  603. ScrollRect.Bottom = (SHORT)b;
  604. Coord.X = (SHORT)Col;
  605. Coord.Y = (SHORT)Row;
  606. CharInfo.Char.AsciiChar = ' ';
  607. CharInfo.Attributes = Attribute;
  608. ScrollConsoleScreenBuffer(ViConsole,&ScrollRect,NULL,Coord,&CharInfo);
  609. }
  610. void EraseLine(void)
  611. {
  612. CONSOLE_SCREEN_BUFFER_INFO Info;
  613. DWORD NumWritten;
  614. flushbuf();
  615. GetConsoleScreenBufferInfo(ViConsole,&Info);
  616. Info.dwCursorPosition.X = 0;
  617. SetConsoleCursorPosition(ViConsole,Info.dwCursorPosition);
  618. FillConsoleOutputCharacter(ViConsole,' ',Columns,Info.dwCursorPosition, &NumWritten);
  619. }
  620. void EraseNLinesAtRow(int n,int row)
  621. {
  622. COORD coord;
  623. DWORD NumWritten;
  624. flushbuf();
  625. coord.X = 0;
  626. coord.Y = (short)row;
  627. FillConsoleOutputCharacter(ViConsole,' ',n*Columns,coord, &NumWritten);
  628. }
  629. void ClearDisplay(void)
  630. {
  631. COORD c;
  632. DWORD NumWritten;
  633. flushbuf();
  634. c.X = c.Y = 0;
  635. SetConsoleCursorPosition(ViConsole,c);
  636. FillConsoleOutputCharacter(ViConsole,' ',Rows*Columns,c, &NumWritten);
  637. }
  638. void SaveCursor(void)
  639. {
  640. CONSOLE_SCREEN_BUFFER_INFO Info;
  641. flushbuf();
  642. GetConsoleScreenBufferInfo(ViConsole,&Info);
  643. ColSave = Info.dwCursorPosition.X;
  644. RowSave = Info.dwCursorPosition.Y;
  645. }
  646. void RestoreCursor(void)
  647. {
  648. COORD c;
  649. flushbuf();
  650. c.X = (SHORT)ColSave;
  651. c.Y = (SHORT)RowSave;
  652. SetConsoleCursorPosition(ViConsole,c);
  653. }
  654. void InvisibleCursor(void)
  655. {
  656. CONSOLE_CURSOR_INFO Info;
  657. flushbuf();
  658. Info.dwSize = CursorSize;
  659. Info.bVisible = FALSE;
  660. SetConsoleCursorInfo(CurrConsole,&Info);
  661. }
  662. void VisibleCursor(void)
  663. {
  664. CONSOLE_CURSOR_INFO Info;
  665. flushbuf();
  666. Info.dwSize = CursorSize;
  667. Info.bVisible = TRUE;
  668. SetConsoleCursorInfo(CurrConsole,&Info);
  669. }
  670. int CurHighlightLine = -1;
  671. int CurHighlightColumn = -1;
  672. int CurHighlightLength = -1;
  673. char CurHighlightString[512];
  674. int
  675. StrLength(char *cp)
  676. {
  677. int length = 0;
  678. int diff;
  679. while (*cp) {
  680. if (*cp == '\t') {
  681. diff = P(P_TS) - (length % P(P_TS));
  682. length += diff;
  683. } else {
  684. length++;
  685. }
  686. cp++;
  687. }
  688. return length;
  689. }
  690. void HighlightLine( int col, unsigned long line, char *string )
  691. {
  692. COORD dwWriteCoord;
  693. DWORD dwNumWritten;
  694. int length;
  695. if (P(P_HS) == FALSE)
  696. return;
  697. length = StrLength(string);
  698. if (length > Columns) {
  699. length = Columns;
  700. }
  701. if (col >= (Columns - 1)) {
  702. col--;
  703. }
  704. dwWriteCoord.X = CurHighlightColumn = col;
  705. dwWriteCoord.Y = CurHighlightLine = line;
  706. FillConsoleOutputAttribute(ViConsole,
  707. HighlightAttribute,
  708. length,
  709. dwWriteCoord,
  710. &dwNumWritten);
  711. updateline();
  712. #if 0
  713. WriteConsoleOutputCharacter(ViConsole,
  714. string,
  715. length,
  716. dwWriteCoord,
  717. &dwNumWritten);
  718. #endif
  719. strcpy(CurHighlightString, string);
  720. CurHighlightLength = length;
  721. }
  722. #define FOREGROUND_WHITE (FOREGROUND_BLUE | \
  723. FOREGROUND_GREEN | \
  724. FOREGROUND_RED | \
  725. FOREGROUND_INTENSITY)
  726. void RemoveHighlight( int col, unsigned long line, int length, char *string )
  727. {
  728. COORD dwWriteCoord;
  729. DWORD dwNumWritten;
  730. length = StrLength(string);
  731. if (length > Columns) {
  732. length = Columns;
  733. }
  734. dwWriteCoord.X = (short)col;
  735. dwWriteCoord.Y = (int)line;
  736. FillConsoleOutputAttribute(ViConsole,
  737. Attribute,
  738. length,
  739. dwWriteCoord,
  740. &dwNumWritten);
  741. updateline();
  742. #if 0
  743. WriteConsoleOutputCharacter(ViConsole,
  744. string,
  745. length,
  746. dwWriteCoord,
  747. &dwNumWritten);
  748. #endif
  749. }
  750. void HighlightCheck()
  751. {
  752. if (P(P_HS) == FALSE)
  753. return;
  754. if (CurHighlightLine != -1) {
  755. RemoveHighlight(CurHighlightColumn,
  756. CurHighlightLine,
  757. CurHighlightLength,
  758. CurHighlightString);
  759. CurHighlightLine = -1;
  760. CurHighlightColumn = -1;
  761. }
  762. }