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.

1935 lines
66 KiB

  1. /*++
  2. Copyright (c) 1985 - 1999, Microsoft Corporation
  3. Module Name:
  4. convarea.c
  5. Abstract:
  6. Author:
  7. KazuM Mar.8,1993
  8. Revision History:
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #if defined(FE_IME)
  13. VOID
  14. LinkConversionArea(
  15. IN PCONSOLE_INFORMATION Console,
  16. IN PCONVERSIONAREA_INFORMATION ConvAreaInfo
  17. )
  18. {
  19. PCONVERSIONAREA_INFORMATION PrevConvAreaInfo;
  20. if (Console->ConsoleIme.ConvAreaRoot == NULL) {
  21. Console->ConsoleIme.ConvAreaRoot = ConvAreaInfo;
  22. }
  23. else {
  24. PrevConvAreaInfo = Console->ConsoleIme.ConvAreaRoot;
  25. while (PrevConvAreaInfo->ConvAreaNext)
  26. PrevConvAreaInfo = PrevConvAreaInfo->ConvAreaNext;
  27. PrevConvAreaInfo->ConvAreaNext = ConvAreaInfo;
  28. }
  29. }
  30. NTSTATUS
  31. FreeConvAreaScreenBuffer(
  32. IN PSCREEN_INFORMATION ScreenInfo
  33. )
  34. /*++
  35. Routine Description:
  36. This routine frees the memory associated with a screen buffer.
  37. Arguments:
  38. ScreenInfo - screen buffer data to free.
  39. Return Value:
  40. Note: console handle table lock must be held when calling this routine
  41. --*/
  42. {
  43. return FreeScreenBuffer(ScreenInfo);
  44. }
  45. NTSTATUS
  46. AllocateConversionArea(
  47. IN PCONSOLE_INFORMATION Console,
  48. IN COORD dwScreenBufferSize,
  49. OUT PCONVERSIONAREA_INFORMATION *ConvAreaInfo
  50. )
  51. {
  52. COORD dwWindowSize;
  53. CHAR_INFO Fill, PopupFill;
  54. PCONVERSIONAREA_INFORMATION ca;
  55. int FontIndex;
  56. NTSTATUS Status;
  57. //
  58. // allocate console data
  59. //
  60. if (Console->CurrentScreenBuffer == NULL) {
  61. return STATUS_UNSUCCESSFUL;
  62. }
  63. ca = ConsoleHeapAlloc(CONVAREA_TAG,
  64. sizeof(CONVERSIONAREA_INFORMATION));
  65. if (ca == NULL) {
  66. return STATUS_NO_MEMORY;
  67. }
  68. dwWindowSize.X = CONSOLE_WINDOW_SIZE_X(Console->CurrentScreenBuffer);
  69. dwWindowSize.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer);
  70. Fill.Attributes = Console->CurrentScreenBuffer->Attributes;
  71. PopupFill.Attributes = Console->CurrentScreenBuffer->PopupAttributes;
  72. FontIndex = FindCreateFont(CON_FAMILY(Console),
  73. CON_FACENAME(Console),
  74. CON_FONTSIZE(Console),
  75. CON_FONTWEIGHT(Console),
  76. CON_FONTCODEPAGE(Console)
  77. );
  78. Status = CreateScreenBuffer(&ca->ScreenBuffer,
  79. dwWindowSize,
  80. FontIndex,
  81. dwScreenBufferSize,
  82. Fill,
  83. PopupFill,
  84. Console,
  85. CONSOLE_TEXTMODE_BUFFER,
  86. NULL,
  87. NULL,
  88. NULL,
  89. CURSOR_SMALL_SIZE,
  90. NULL
  91. );
  92. if (!NT_SUCCESS(Status)) {
  93. ConsoleHeapFree(ca);
  94. return Status;
  95. }
  96. *ConvAreaInfo = ca;
  97. return STATUS_SUCCESS;
  98. }
  99. NTSTATUS
  100. SetUpConversionArea(
  101. IN PCONSOLE_INFORMATION Console,
  102. IN COORD coordCaBuffer,
  103. IN SMALL_RECT rcViewCaWindow,
  104. IN COORD coordConView,
  105. IN DWORD dwOption,
  106. OUT PCONVERSIONAREA_INFORMATION *ConvAreaInfo
  107. )
  108. {
  109. NTSTATUS Status;
  110. PCONVERSIONAREA_INFORMATION ca;
  111. Status = AllocateConversionArea(Console, coordCaBuffer, &ca);
  112. if (!NT_SUCCESS(Status)) {
  113. return Status;
  114. }
  115. ca->ConversionAreaMode = dwOption;
  116. ca->CaInfo.coordCaBuffer = coordCaBuffer;
  117. ca->CaInfo.rcViewCaWindow = rcViewCaWindow;
  118. ca->CaInfo.coordConView = coordConView;
  119. ca->ConvAreaNext = NULL;
  120. ca->ScreenBuffer->ConvScreenInfo = ca;
  121. LinkConversionArea(Console, ca);
  122. SetUndetermineAttribute(Console);
  123. *ConvAreaInfo = ca;
  124. return STATUS_SUCCESS;
  125. }
  126. VOID
  127. WriteConvRegionToScreen(
  128. IN PSCREEN_INFORMATION ScreenInfo,
  129. IN PCONVERSIONAREA_INFORMATION ConvAreaInfo,
  130. IN PSMALL_RECT ConvRegion
  131. )
  132. /*++
  133. Routine Description:
  134. Arguments:
  135. ClippedRegion - Rectangle of region by screen coordinate.
  136. Return Value:
  137. --*/
  138. {
  139. SMALL_RECT Region;
  140. SMALL_RECT ClippedRegion;
  141. if (ScreenInfo->Console->CurrentScreenBuffer->Flags & CONSOLE_GRAPHICS_BUFFER)
  142. return;
  143. while (ConvAreaInfo) {
  144. if ((ConvAreaInfo->ConversionAreaMode & (CA_HIDDEN+CA_HIDE_FOR_SCROLL))==0) {
  145. //
  146. // Do clipping region
  147. //
  148. Region.Left = ScreenInfo->Window.Left +
  149. ConvAreaInfo->CaInfo.rcViewCaWindow.Left +
  150. ConvAreaInfo->CaInfo.coordConView.X;
  151. Region.Right = Region.Left +
  152. (ConvAreaInfo->CaInfo.rcViewCaWindow.Right -
  153. ConvAreaInfo->CaInfo.rcViewCaWindow.Left);
  154. Region.Top = ScreenInfo->Window.Top +
  155. ConvAreaInfo->CaInfo.rcViewCaWindow.Top +
  156. ConvAreaInfo->CaInfo.coordConView.Y;
  157. Region.Bottom = Region.Top +
  158. (ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom -
  159. ConvAreaInfo->CaInfo.rcViewCaWindow.Top);
  160. ClippedRegion.Left = max(Region.Left, ScreenInfo->Window.Left);
  161. ClippedRegion.Top = max(Region.Top, ScreenInfo->Window.Top);
  162. ClippedRegion.Right = min(Region.Right, ScreenInfo->Window.Right);
  163. ClippedRegion.Bottom = min(Region.Bottom, ScreenInfo->Window.Bottom);
  164. if (ClippedRegion.Right < ClippedRegion.Left ||
  165. ClippedRegion.Bottom < ClippedRegion.Top) {
  166. /* TODO: Fix this. */;
  167. } else {
  168. Region = ClippedRegion;
  169. ClippedRegion.Left = max(Region.Left, ConvRegion->Left);
  170. ClippedRegion.Top = max(Region.Top, ConvRegion->Top);
  171. ClippedRegion.Right = min(Region.Right, ConvRegion->Right);
  172. ClippedRegion.Bottom = min(Region.Bottom, ConvRegion->Bottom);
  173. if (ClippedRegion.Right < ClippedRegion.Left ||
  174. ClippedRegion.Bottom < ClippedRegion.Top) {
  175. /* TODO: Fix this */;
  176. } else {
  177. ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
  178. ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
  179. WriteRegionToScreen(ConvAreaInfo->ScreenBuffer,
  180. &ClippedRegion
  181. );
  182. ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
  183. }
  184. }
  185. }
  186. ConvAreaInfo = ConvAreaInfo->ConvAreaNext;
  187. }
  188. }
  189. BOOL
  190. ConsoleImeBottomLineUse(
  191. IN PSCREEN_INFORMATION ScreenInfo,
  192. IN SHORT ScrollOffset
  193. )
  194. /*++
  195. Routine Description:
  196. Arguments:
  197. ScreenInfo -
  198. ScrollOffset -
  199. Return Value:
  200. --*/
  201. {
  202. SMALL_RECT ScrollRectangle;
  203. COORD DestinationOrigin;
  204. CHAR_INFO Fill;
  205. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  206. SMALL_RECT WriteRegion;
  207. BOOL fRedraw = FALSE;
  208. if (!(ScreenInfo->Console->ConsoleIme.ScrollFlag & HIDE_FOR_SCROLL)) {
  209. ScreenInfo->Console->ConsoleIme.ScrollFlag |= HIDE_FOR_SCROLL;
  210. if (ConvAreaInfo = ScreenInfo->Console->ConsoleIme.ConvAreaRoot) {
  211. do {
  212. if ((ConvAreaInfo->ConversionAreaMode & (CA_STATUS_LINE))==0) {
  213. ConvAreaInfo->ConversionAreaMode |= CA_HIDE_FOR_SCROLL;
  214. fRedraw = TRUE;
  215. }
  216. } while (ConvAreaInfo = ConvAreaInfo->ConvAreaNext);
  217. if (fRedraw) {
  218. // Check code for must CONSOLE_TEXTMODE_BUFFER !!
  219. if (ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER)
  220. {
  221. ASSERT(FALSE);
  222. }
  223. else {
  224. WriteRegion = ScreenInfo->Window;
  225. WriteRegion.Bottom--;
  226. ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
  227. ScreenInfo->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
  228. WriteToScreen(ScreenInfo,&WriteRegion);
  229. ScreenInfo->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
  230. }
  231. }
  232. }
  233. }
  234. if (ScrollOffset) {
  235. ScrollRectangle.Top = 1;
  236. ScrollRectangle.Left = 0;
  237. ScrollRectangle.Right = ScreenInfo->ScreenBufferSize.X-1;
  238. ScrollRectangle.Bottom = ScreenInfo->ScreenBufferSize.Y-1;
  239. ScrollRectangle.Bottom -= (ScrollOffset-1);
  240. DestinationOrigin.X = ScrollRectangle.Left;
  241. DestinationOrigin.Y = ScrollRectangle.Top-1;
  242. Fill.Char.UnicodeChar = '\0';
  243. Fill.Attributes = 0;
  244. ScrollRegion(ScreenInfo,
  245. &ScrollRectangle,
  246. NULL,
  247. DestinationOrigin,
  248. Fill
  249. );
  250. #if defined(FE_SB)
  251. #if defined(FE_IME)
  252. if ( ! (ScreenInfo->Console->InputBuffer.ImeMode.Disable) &&
  253. ! (ScreenInfo->Console->InputBuffer.ImeMode.Unavailable) &&
  254. (ScreenInfo->Console->InputBuffer.ImeMode.Open) &&
  255. (ScrollRectangle.Left == ScreenInfo->Window.Left) &&
  256. (ScrollRectangle.Right == ScreenInfo->Window.Right) ) {
  257. ScrollRectangle.Top = ScreenInfo->Window.Bottom;
  258. ScrollRectangle.Bottom = ScreenInfo->Window.Bottom;
  259. WriteToScreen(ScreenInfo,&ScrollRectangle);
  260. WriteConvRegionToScreen(ScreenInfo,
  261. ScreenInfo->Console->ConsoleIme.ConvAreaRoot,
  262. &ScrollRectangle);
  263. }
  264. #endif
  265. #endif
  266. }
  267. else {
  268. ScreenInfo->Console->ConsoleIme.ScrollWaitCountDown = ScreenInfo->Console->ConsoleIme.ScrollWaitTimeout;
  269. }
  270. return TRUE;
  271. }
  272. VOID
  273. ConsoleImeBottomLineInUse(
  274. IN PSCREEN_INFORMATION ScreenInfo
  275. )
  276. /*++
  277. Routine Description:
  278. Arguments:
  279. ScreenInfo -
  280. Return Value:
  281. --*/
  282. {
  283. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  284. SMALL_RECT WriteRegion;
  285. BOOL fRedraw = FALSE;
  286. COORD CursorPosition;
  287. ScreenInfo->Console->ConsoleIme.ScrollFlag &= ~HIDE_FOR_SCROLL;
  288. if (ConvAreaInfo = ScreenInfo->Console->ConsoleIme.ConvAreaRoot) {
  289. do {
  290. if (ConvAreaInfo->ConversionAreaMode & CA_HIDE_FOR_SCROLL) {
  291. ConvAreaInfo->ConversionAreaMode &= ~CA_HIDE_FOR_SCROLL;
  292. fRedraw = TRUE;
  293. }
  294. } while (ConvAreaInfo = ConvAreaInfo->ConvAreaNext);
  295. if (fRedraw) {
  296. // Check code for must CONSOLE_TEXTMODE_BUFFER !!
  297. if (ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER)
  298. {
  299. ASSERT(FALSE);
  300. }
  301. else {
  302. if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == (ScreenInfo->ScreenBufferSize.Y-1)) {
  303. ConsoleHideCursor(ScreenInfo);
  304. ConsoleImeBottomLineUse(ScreenInfo,1);
  305. CursorPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
  306. CursorPosition.Y--;
  307. SetCursorPosition(ScreenInfo,CursorPosition,TRUE);
  308. if (ScreenInfo->Console->lpCookedReadData) {
  309. ((PCOOKED_READ_DATA)(ScreenInfo->Console->lpCookedReadData))->OriginalCursorPosition.Y--;
  310. }
  311. ConsoleShowCursor(ScreenInfo);
  312. } else if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == ScreenInfo->Window.Bottom) {
  313. /* TODO: Fix this. */;
  314. }
  315. WriteRegion.Top = 0;
  316. WriteRegion.Bottom = (SHORT)(ScreenInfo->ScreenBufferSize.Y-1);
  317. WriteRegion.Left = 0;
  318. WriteRegion.Right = (SHORT)(ScreenInfo->ScreenBufferSize.X-1);
  319. ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
  320. ScreenInfo->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
  321. WriteToScreen(ScreenInfo,&WriteRegion);
  322. ScreenInfo->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
  323. }
  324. }
  325. }
  326. }
  327. NTSTATUS
  328. CreateConvAreaUndetermine(
  329. PCONSOLE_INFORMATION Console
  330. )
  331. {
  332. PCONSOLE_IME_INFORMATION ConsoleIme = &Console->ConsoleIme;
  333. NTSTATUS Status;
  334. COORD coordCaBuffer;
  335. SMALL_RECT rcViewCaWindow;
  336. COORD coordConView;
  337. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  338. if (ConsoleIme->ConvAreaCompStr) {
  339. ConsoleIme->ConvAreaCompStr =
  340. ConsoleHeapReAlloc(
  341. 0,
  342. ConsoleIme->ConvAreaCompStr,
  343. ConsoleHeapSize(
  344. ConsoleIme->ConvAreaCompStr)+sizeof(PCONVERSIONAREA_INFORMATION));
  345. if (ConsoleIme->ConvAreaCompStr == NULL)
  346. return STATUS_NO_MEMORY;
  347. }
  348. else {
  349. ConsoleIme->ConvAreaCompStr =
  350. ConsoleHeapAlloc(
  351. CONVAREA_TAG,
  352. sizeof(PCONVERSIONAREA_INFORMATION));
  353. if (ConsoleIme->ConvAreaCompStr == NULL)
  354. return STATUS_NO_MEMORY;
  355. }
  356. coordCaBuffer = Console->CurrentScreenBuffer->ScreenBufferSize;
  357. coordCaBuffer.Y = 1;
  358. rcViewCaWindow.Top = 0;
  359. rcViewCaWindow.Left = 0;
  360. rcViewCaWindow.Bottom = 0;
  361. rcViewCaWindow.Right = 0;
  362. coordConView.X = 0;
  363. coordConView.Y = 0;
  364. Status = SetUpConversionArea(Console,
  365. coordCaBuffer,
  366. rcViewCaWindow,
  367. coordConView,
  368. (Console->ConsoleIme.ScrollFlag & HIDE_FOR_SCROLL) ?
  369. CA_HIDE_FOR_SCROLL :
  370. CA_HIDDEN,
  371. &ConvAreaInfo
  372. );
  373. if (!NT_SUCCESS(Status)) {
  374. return Status;
  375. }
  376. ConsoleIme->ConvAreaCompStr[ConsoleIme->NumberOfConvAreaCompStr] = ConvAreaInfo;
  377. ConsoleIme->NumberOfConvAreaCompStr++;
  378. return Status;
  379. }
  380. NTSTATUS
  381. CreateConvAreaModeSystem(
  382. PCONSOLE_INFORMATION Console
  383. )
  384. {
  385. PCONSOLE_IME_INFORMATION ConsoleIme = &Console->ConsoleIme;
  386. NTSTATUS Status;
  387. COORD coordCaBuffer;
  388. SMALL_RECT rcViewCaWindow;
  389. COORD coordConView;
  390. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  391. if (Console->CurrentScreenBuffer == NULL) {
  392. return STATUS_UNSUCCESSFUL;
  393. }
  394. /*
  395. * Create mode text buffer
  396. */
  397. coordCaBuffer = Console->CurrentScreenBuffer->ScreenBufferSize;
  398. coordCaBuffer.Y = 1;
  399. rcViewCaWindow.Top = 0;
  400. rcViewCaWindow.Left = 0;
  401. rcViewCaWindow.Bottom = 0;
  402. rcViewCaWindow.Right = 0;
  403. coordConView.X = 0;
  404. coordConView.Y = 0;
  405. Status = SetUpConversionArea(Console,
  406. coordCaBuffer,
  407. rcViewCaWindow,
  408. coordConView,
  409. CA_HIDDEN+CA_STATUS_LINE,
  410. &ConvAreaInfo
  411. );
  412. if (!NT_SUCCESS(Status)) {
  413. return Status;
  414. }
  415. ConsoleIme->ConvAreaMode = ConvAreaInfo;
  416. /*
  417. * Create system text buffer
  418. */
  419. Status = SetUpConversionArea(Console,
  420. coordCaBuffer,
  421. rcViewCaWindow,
  422. coordConView,
  423. CA_HIDDEN+CA_STATUS_LINE,
  424. &ConvAreaInfo
  425. );
  426. if (!NT_SUCCESS(Status)) {
  427. return Status;
  428. }
  429. ConsoleIme->ConvAreaSystem = ConvAreaInfo;
  430. return Status;
  431. }
  432. #define LOCAL_BUFFER_SIZE 100
  433. NTSTATUS
  434. WriteUndetermineChars(
  435. PCONSOLE_INFORMATION Console,
  436. LPWSTR lpString,
  437. PBYTE lpAtr,
  438. PWORD lpAtrIdx,
  439. DWORD NumChars // character count
  440. )
  441. {
  442. PSCREEN_INFORMATION ScreenInfo;
  443. PSCREEN_INFORMATION ConvScreenInfo;
  444. WCHAR LocalBuffer[LOCAL_BUFFER_SIZE];
  445. BYTE LocalBufferA[LOCAL_BUFFER_SIZE];
  446. PWCHAR LocalBufPtr;
  447. PBYTE LocalBufPtrA;
  448. DWORD BufferSize;
  449. COORD Position;
  450. ULONG i;
  451. SMALL_RECT Region;
  452. COORD CursorPosition;
  453. WCHAR Char;
  454. WORD Attr;
  455. PCONSOLE_IME_INFORMATION ConsoleIme;
  456. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  457. DWORD ConvAreaIndex;
  458. NTSTATUS Status;
  459. ULONG NumStr;
  460. int WholeLen;
  461. int WholeRow;
  462. SHORT PosY;
  463. BOOL UndetAreaUp = FALSE;
  464. ConsoleIme = &Console->ConsoleIme;
  465. ScreenInfo = Console->CurrentScreenBuffer;
  466. // Check code for must CONSOLE_TEXTMODE_BUFFER !!
  467. ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
  468. Position = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
  469. if ((ScreenInfo->Window.Left <= Position.X && Position.X <= ScreenInfo->Window.Right) &&
  470. (ScreenInfo->Window.Top <= Position.Y && Position.Y <= ScreenInfo->Window.Bottom) ) {
  471. Position.X = ScreenInfo->BufferInfo.TextInfo.CursorPosition.X - ScreenInfo->Window.Left;
  472. Position.Y = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y - ScreenInfo->Window.Top;
  473. }
  474. else {
  475. Position.X = 0;
  476. Position.Y = CONSOLE_WINDOW_SIZE_Y(ScreenInfo) - 2;
  477. }
  478. PosY = Position.Y;
  479. RtlUnicodeToMultiByteSize(&NumStr, lpString, NumChars*sizeof(WCHAR));
  480. WholeLen = (int)Position.X + (int)NumStr;
  481. WholeRow = WholeLen / CONSOLE_WINDOW_SIZE_X(ScreenInfo);
  482. if ( ( PosY + WholeRow ) > ( CONSOLE_WINDOW_SIZE_Y(ScreenInfo) - 2) ) {
  483. PosY = CONSOLE_WINDOW_SIZE_Y(ScreenInfo) - 2 - WholeRow;
  484. if (PosY < 0) {
  485. PosY = ScreenInfo->Window.Top;
  486. }
  487. }
  488. if (PosY != Position.Y) {
  489. Position.Y = PosY;
  490. UndetAreaUp = TRUE;
  491. }
  492. ConvAreaIndex = 0;
  493. BufferSize = NumChars;
  494. NumChars = 0;
  495. for (ConvAreaIndex = 0; NumChars < BufferSize; ConvAreaIndex++) {
  496. if (ConvAreaIndex+1 > ConsoleIme->NumberOfConvAreaCompStr) {
  497. Status = CreateConvAreaUndetermine(Console);
  498. if (!NT_SUCCESS(Status)) {
  499. return Status;
  500. }
  501. }
  502. ConvAreaInfo = ConsoleIme->ConvAreaCompStr[ConvAreaIndex];
  503. ConvScreenInfo = ConvAreaInfo->ScreenBuffer;
  504. ConvScreenInfo->BufferInfo.TextInfo.CursorPosition.X = Position.X;
  505. if ((ConvAreaInfo->ConversionAreaMode & CA_HIDDEN) ||
  506. (UndetAreaUp)) {
  507. /*
  508. * This conversion area need positioning onto cursor position.
  509. */
  510. CursorPosition.X = 0;
  511. CursorPosition.Y = (SHORT)(Position.Y + ConvAreaIndex);
  512. ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
  513. }
  514. Region.Left = ConvScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
  515. Region.Top = 0;
  516. Region.Bottom = 0;
  517. while (NumChars < BufferSize) {
  518. i=0;
  519. LocalBufPtr = LocalBuffer;
  520. LocalBufPtrA = LocalBufferA;
  521. while (NumChars < BufferSize &&
  522. i < LOCAL_BUFFER_SIZE &&
  523. Position.X < CONSOLE_WINDOW_SIZE_X(ScreenInfo)) {
  524. Char = *lpString;
  525. Attr = *lpAtr;
  526. if (Char >= (WCHAR)' ') {
  527. if (IsConsoleFullWidth(Console->hDC,Console->OutputCP,Char)) {
  528. if (i < (LOCAL_BUFFER_SIZE-1) &&
  529. Position.X < CONSOLE_WINDOW_SIZE_X(ScreenInfo)-1) {
  530. *LocalBufPtr++ = Char;
  531. *LocalBufPtrA++ = ATTR_LEADING_BYTE;
  532. *LocalBufPtr++ = Char;
  533. *LocalBufPtrA++ = ATTR_TRAILING_BYTE;
  534. Position.X+=2;
  535. i+=2;
  536. }
  537. else {
  538. Position.X++;
  539. break;
  540. }
  541. }
  542. else {
  543. *LocalBufPtr++ = Char;
  544. *LocalBufPtrA++ = 0;
  545. Position.X++;
  546. i++;
  547. }
  548. }
  549. lpString++;
  550. lpAtr++;
  551. NumChars++;
  552. if (NumChars < BufferSize &&
  553. Attr != *lpAtr)
  554. break;
  555. }
  556. if (i != 0) {
  557. ConvScreenInfo->Attributes = lpAtrIdx[Attr & 0x07];
  558. if (Attr & 0x10) {
  559. ConvScreenInfo->Attributes |= (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_RVERTICAL);
  560. } else if (Attr & 0x20) {
  561. ConvScreenInfo->Attributes |= (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_LVERTICAL);
  562. }
  563. StreamWriteToScreenBufferIME(LocalBuffer,
  564. (SHORT)i,
  565. ConvScreenInfo,
  566. LocalBufferA);
  567. ConvScreenInfo->BufferInfo.TextInfo.CursorPosition.X += (SHORT)i;
  568. if (NumChars == BufferSize ||
  569. Position.X >= CONSOLE_WINDOW_SIZE_X(ScreenInfo) ||
  570. ( (Char >= (WCHAR)' ' &&
  571. IsConsoleFullWidth(Console->hDC,Console->OutputCP,Char) &&
  572. Position.X >= CONSOLE_WINDOW_SIZE_X(ScreenInfo)-1) )
  573. ) {
  574. Region.Right = (SHORT)(ConvScreenInfo->BufferInfo.TextInfo.CursorPosition.X - 1);
  575. ConsoleImeWindowInfo(Console,ConvAreaInfo,Region);
  576. ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
  577. ConsoleImePaint(Console,ConvAreaInfo);
  578. Position.X = 0;
  579. break;
  580. }
  581. if (NumChars == BufferSize) {
  582. return STATUS_SUCCESS;
  583. }
  584. continue;
  585. } else if (NumChars == BufferSize) {
  586. return STATUS_SUCCESS;
  587. }
  588. if (!NT_SUCCESS(Status)) {
  589. return Status;
  590. }
  591. if (Position.X >= CONSOLE_WINDOW_SIZE_X(ScreenInfo)) {
  592. Position.X = 0;
  593. break;
  594. }
  595. }
  596. }
  597. for (; ConvAreaIndex < ConsoleIme->NumberOfConvAreaCompStr; ConvAreaIndex++) {
  598. ConvAreaInfo = ConsoleIme->ConvAreaCompStr[ConvAreaIndex];
  599. if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
  600. ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
  601. ConsoleImePaint(Console,ConvAreaInfo);
  602. }
  603. }
  604. return STATUS_SUCCESS;
  605. }
  606. VOID
  607. WriteModeSystemChars(
  608. PCONSOLE_INFORMATION Console,
  609. PCONVERSIONAREA_INFORMATION ConvAreaInfo,
  610. PCHAR_INFO Buffer,
  611. DWORD NumberOfChars,
  612. DWORD ViewPosition
  613. )
  614. {
  615. SMALL_RECT CharRegion;
  616. COORD CursorPosition;
  617. if (Buffer) {
  618. CharRegion.Left = 0;
  619. CharRegion.Top = 0;
  620. CharRegion.Right = CalcWideCharToColumn(Console,Buffer,NumberOfChars);
  621. CharRegion.Right = (CharRegion.Right ? CharRegion.Right-1 : 0);
  622. CharRegion.Bottom = 0;
  623. }
  624. else {
  625. CharRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
  626. }
  627. if (ConvAreaInfo) {
  628. if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
  629. if (CharRegion.Left != ConvAreaInfo->CaInfo.rcViewCaWindow.Left ||
  630. CharRegion.Top != ConvAreaInfo->CaInfo.rcViewCaWindow.Top ||
  631. CharRegion.Right != ConvAreaInfo->CaInfo.rcViewCaWindow.Right ||
  632. CharRegion.Bottom != ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom) {
  633. switch (ViewPosition) {
  634. case VIEW_LEFT:
  635. CursorPosition.X = 0;
  636. break;
  637. case VIEW_RIGHT:
  638. CursorPosition.X = CONSOLE_WINDOW_SIZE_X(Console->CurrentScreenBuffer) - (CharRegion.Right + 1);
  639. break;
  640. }
  641. CursorPosition.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer) - 1;
  642. ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
  643. ConsoleImeWindowInfo(Console,ConvAreaInfo,CharRegion);
  644. }
  645. }
  646. else {
  647. /*
  648. * This conversion area need positioning onto cursor position.
  649. */
  650. switch (ViewPosition) {
  651. case VIEW_LEFT:
  652. CursorPosition.X = 0;
  653. break;
  654. case VIEW_RIGHT:
  655. CursorPosition.X = CONSOLE_WINDOW_SIZE_X(Console->CurrentScreenBuffer) - (CharRegion.Right + 1);
  656. break;
  657. }
  658. CursorPosition.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer) - 1;
  659. ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
  660. ConsoleImeWindowInfo(Console,ConvAreaInfo,CharRegion);
  661. }
  662. if (Buffer) {
  663. ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
  664. ConsoleImeWriteOutput(Console,ConvAreaInfo,Buffer,CharRegion,TRUE);
  665. }
  666. else {
  667. ConsoleImePaint(Console,ConvAreaInfo);
  668. }
  669. }
  670. }
  671. NTSTATUS
  672. FillUndetermineChars(
  673. PCONSOLE_INFORMATION Console,
  674. PCONVERSIONAREA_INFORMATION ConvAreaInfo
  675. )
  676. {
  677. COORD Coord;
  678. DWORD CharsToWrite;
  679. ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
  680. Coord.X = 0;
  681. Coord.Y = 0;
  682. CharsToWrite = ConvAreaInfo->ScreenBuffer->ScreenBufferSize.X;
  683. FillOutput(ConvAreaInfo->ScreenBuffer,
  684. (WCHAR)' ',
  685. Coord,
  686. CONSOLE_FALSE_UNICODE, // faster than real unicode
  687. &CharsToWrite
  688. );
  689. CharsToWrite = ConvAreaInfo->ScreenBuffer->ScreenBufferSize.X;
  690. FillOutput(ConvAreaInfo->ScreenBuffer,
  691. Console->CurrentScreenBuffer->Attributes,
  692. Coord,
  693. CONSOLE_ATTRIBUTE,
  694. &CharsToWrite
  695. );
  696. ConsoleImePaint(Console,ConvAreaInfo);
  697. return STATUS_SUCCESS;
  698. }
  699. NTSTATUS
  700. ConsoleImeCompStr(
  701. IN PCONSOLE_INFORMATION Console,
  702. IN LPCONIME_UICOMPMESSAGE CompStr
  703. )
  704. {
  705. UINT i;
  706. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  707. if (CompStr->dwCompStrLen == 0 ||
  708. CompStr->dwResultStrLen != 0
  709. ) {
  710. // Cursor turn ON.
  711. if ((Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) &&
  712. Console->ConsoleIme.SavedCursorVisible )
  713. {
  714. Console->ConsoleIme.SavedCursorVisible = FALSE;
  715. SetCursorInformation(Console->CurrentScreenBuffer,
  716. Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorSize,
  717. TRUE);
  718. }
  719. /*
  720. * Determine string.
  721. */
  722. for (i=0; i<Console->ConsoleIme.NumberOfConvAreaCompStr; i++) {
  723. ConvAreaInfo = Console->ConsoleIme.ConvAreaCompStr[i];
  724. if (ConvAreaInfo &&
  725. (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
  726. FillUndetermineChars(Console,ConvAreaInfo);
  727. }
  728. }
  729. if (CompStr->dwResultStrLen != 0)
  730. {
  731. if (!InsertConverTedString(Console, (LPWSTR)((PBYTE)CompStr + CompStr->dwResultStrOffset))) {
  732. return STATUS_INVALID_HANDLE;
  733. }
  734. }
  735. if (Console->ConsoleIme.CompStrData) {
  736. ConsoleHeapFree(Console->ConsoleIme.CompStrData);
  737. Console->ConsoleIme.CompStrData = NULL;
  738. }
  739. }
  740. else {
  741. LPWSTR lpStr;
  742. PBYTE lpAtr;
  743. PWORD lpAtrIdx;
  744. // Cursor turn OFF.
  745. if ((Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) &&
  746. Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorVisible )
  747. {
  748. Console->ConsoleIme.SavedCursorVisible = TRUE;
  749. SetCursorInformation(Console->CurrentScreenBuffer,
  750. Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorSize,
  751. FALSE);
  752. }
  753. /*
  754. * Composition string.
  755. */
  756. for (i=0; i<Console->ConsoleIme.NumberOfConvAreaCompStr; i++) {
  757. ConvAreaInfo = Console->ConsoleIme.ConvAreaCompStr[i];
  758. if (ConvAreaInfo &&
  759. (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
  760. FillUndetermineChars(Console,ConvAreaInfo);
  761. }
  762. }
  763. lpStr = (LPWSTR)((PBYTE)CompStr + CompStr->dwCompStrOffset);
  764. lpAtr = (PBYTE)CompStr + CompStr->dwCompAttrOffset;
  765. lpAtrIdx = (PWORD)CompStr->CompAttrColor;
  766. WriteUndetermineChars(Console, lpStr, lpAtr, lpAtrIdx, CompStr->dwCompStrLen / sizeof(WCHAR));
  767. }
  768. return STATUS_SUCCESS;
  769. }
  770. NTSTATUS
  771. ConsoleImeResizeModeSystemView(
  772. PCONSOLE_INFORMATION Console,
  773. SMALL_RECT WindowRect
  774. )
  775. {
  776. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  777. SMALL_RECT CharRegion;
  778. COORD CursorPosition;
  779. /*
  780. * Mode string
  781. */
  782. ConvAreaInfo = Console->ConsoleIme.ConvAreaMode;
  783. if (ConvAreaInfo &&
  784. (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
  785. ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
  786. ConsoleImePaint(Console,ConvAreaInfo);
  787. CharRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
  788. if (Console->ConsoleIme.ConvAreaModePosition == VIEW_LEFT){
  789. CursorPosition.X = 0;
  790. }
  791. else{
  792. CursorPosition.X = CONSOLE_WINDOW_SIZE_X(Console->CurrentScreenBuffer) - (CharRegion.Right + 1);
  793. }
  794. CursorPosition.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer) - 1;
  795. ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
  796. ConsoleImeWindowInfo(Console,ConvAreaInfo,CharRegion);
  797. ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
  798. WriteModeSystemChars(Console,
  799. Console->ConsoleIme.ConvAreaMode,
  800. NULL,
  801. 0,
  802. Console->ConsoleIme.ConvAreaModePosition);
  803. }
  804. /*
  805. * System string
  806. */
  807. ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
  808. if (ConvAreaInfo &&
  809. (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
  810. ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
  811. ConsoleImePaint(Console,ConvAreaInfo);
  812. CharRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
  813. CursorPosition.X = 0;
  814. CursorPosition.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer) - 1;
  815. ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
  816. ConsoleImeWindowInfo(Console,ConvAreaInfo,CharRegion);
  817. ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
  818. WriteModeSystemChars(Console,
  819. Console->ConsoleIme.ConvAreaSystem,
  820. NULL,
  821. 0,
  822. VIEW_LEFT);
  823. }
  824. return STATUS_SUCCESS;
  825. UNREFERENCED_PARAMETER(WindowRect);
  826. }
  827. NTSTATUS
  828. ConsoleImeResizeCompStrView(
  829. PCONSOLE_INFORMATION Console,
  830. SMALL_RECT WindowRect
  831. )
  832. {
  833. UINT i;
  834. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  835. LPCONIME_UICOMPMESSAGE CompStr;
  836. LPWSTR lpStr;
  837. PBYTE lpAtr;
  838. PWORD lpAtrIdx;
  839. /*
  840. * Compositon string
  841. */
  842. CompStr = Console->ConsoleIme.CompStrData;
  843. if (CompStr) {
  844. for (i=0; i<Console->ConsoleIme.NumberOfConvAreaCompStr; i++) {
  845. ConvAreaInfo = Console->ConsoleIme.ConvAreaCompStr[i];
  846. if (ConvAreaInfo &&
  847. (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
  848. FillUndetermineChars(Console,ConvAreaInfo);
  849. }
  850. }
  851. lpStr = (LPWSTR)((PBYTE)CompStr + CompStr->dwCompStrOffset);
  852. lpAtr = (PBYTE)CompStr + CompStr->dwCompAttrOffset;
  853. lpAtrIdx = (PWORD)CompStr->CompAttrColor;
  854. WriteUndetermineChars(Console, lpStr, lpAtr, lpAtrIdx, CompStr->dwCompStrLen / sizeof(WCHAR));
  855. }
  856. return STATUS_SUCCESS;
  857. UNREFERENCED_PARAMETER(WindowRect);
  858. }
  859. NTSTATUS
  860. ConsoleImeResizeModeSystemScreenBuffer(
  861. PCONSOLE_INFORMATION Console,
  862. COORD NewScreenSize
  863. )
  864. {
  865. NTSTATUS Status;
  866. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  867. /*
  868. * Mode string
  869. */
  870. ConvAreaInfo = Console->ConsoleIme.ConvAreaMode;
  871. if (ConvAreaInfo) {
  872. if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
  873. ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
  874. ConsoleImePaint(Console,ConvAreaInfo);
  875. ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
  876. }
  877. Status = ConsoleImeResizeScreenBuffer(ConvAreaInfo->ScreenBuffer,NewScreenSize,ConvAreaInfo);
  878. if (! NT_SUCCESS(Status))
  879. return Status;
  880. }
  881. /*
  882. * System string
  883. */
  884. ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
  885. if (ConvAreaInfo) {
  886. if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
  887. ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
  888. ConsoleImePaint(Console,ConvAreaInfo);
  889. ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
  890. }
  891. Status = ConsoleImeResizeScreenBuffer(ConvAreaInfo->ScreenBuffer,NewScreenSize,ConvAreaInfo);
  892. if (! NT_SUCCESS(Status))
  893. return Status;
  894. }
  895. return STATUS_SUCCESS;
  896. }
  897. NTSTATUS
  898. ConsoleImeResizeCompStrScreenBuffer(
  899. PCONSOLE_INFORMATION Console,
  900. COORD NewScreenSize
  901. )
  902. {
  903. NTSTATUS Status;
  904. UINT i;
  905. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  906. /*
  907. * Compositon string
  908. */
  909. for (i=0; i<Console->ConsoleIme.NumberOfConvAreaCompStr; i++) {
  910. ConvAreaInfo = Console->ConsoleIme.ConvAreaCompStr[i];
  911. if (ConvAreaInfo) {
  912. if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
  913. ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
  914. ConsoleImePaint(Console,ConvAreaInfo);
  915. }
  916. Status = ConsoleImeResizeScreenBuffer(ConvAreaInfo->ScreenBuffer,NewScreenSize,ConvAreaInfo);
  917. if (! NT_SUCCESS(Status))
  918. return Status;
  919. }
  920. }
  921. return STATUS_SUCCESS;
  922. }
  923. SHORT
  924. CalcWideCharToColumn(
  925. IN PCONSOLE_INFORMATION Console,
  926. IN PCHAR_INFO Buffer,
  927. IN DWORD NumberOfChars
  928. )
  929. {
  930. SHORT Column = 0;
  931. while (NumberOfChars--) {
  932. if (IsConsoleFullWidth(Console->hDC,Console->OutputCP,Buffer->Char.UnicodeChar))
  933. Column += 2;
  934. else
  935. Column++;
  936. Buffer++;
  937. }
  938. return Column;
  939. }
  940. LONG
  941. ConsoleImePaint(
  942. IN PCONSOLE_INFORMATION Console,
  943. IN PCONVERSIONAREA_INFORMATION ConvAreaInfo
  944. )
  945. /*++
  946. This routine
  947. --*/
  948. {
  949. PSCREEN_INFORMATION ScreenInfo;
  950. SMALL_RECT WriteRegion;
  951. COORD CursorPosition;
  952. if (!ConvAreaInfo)
  953. return FALSE;
  954. ScreenInfo = Console->CurrentScreenBuffer;
  955. if (!ScreenInfo)
  956. return FALSE;
  957. // Check code for must CONSOLE_TEXTMODE_BUFFER !!
  958. ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
  959. WriteRegion.Left = ScreenInfo->Window.Left
  960. + ConvAreaInfo->CaInfo.coordConView.X
  961. + ConvAreaInfo->CaInfo.rcViewCaWindow.Left;
  962. WriteRegion.Right = WriteRegion.Left
  963. + (ConvAreaInfo->CaInfo.rcViewCaWindow.Right - ConvAreaInfo->CaInfo.rcViewCaWindow.Left);
  964. WriteRegion.Top = ScreenInfo->Window.Top
  965. + ConvAreaInfo->CaInfo.coordConView.Y
  966. + ConvAreaInfo->CaInfo.rcViewCaWindow.Top;
  967. WriteRegion.Bottom = WriteRegion.Top
  968. + (ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom - ConvAreaInfo->CaInfo.rcViewCaWindow.Top);
  969. if ((ConvAreaInfo->ConversionAreaMode & (CA_HIDDEN+CA_STATUS_LINE))==(CA_STATUS_LINE)) {
  970. if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == (ScreenInfo->ScreenBufferSize.Y-1)) {
  971. ConsoleHideCursor(ScreenInfo);
  972. ConsoleImeBottomLineUse(ScreenInfo,1);
  973. CursorPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
  974. CursorPosition.Y--;
  975. SetCursorPosition(ScreenInfo,CursorPosition,TRUE);
  976. if (ScreenInfo->Console->lpCookedReadData) {
  977. ((PCOOKED_READ_DATA)(ScreenInfo->Console->lpCookedReadData))->OriginalCursorPosition.Y--;
  978. }
  979. ConsoleShowCursor(ScreenInfo);
  980. }
  981. else if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == ScreenInfo->Window.Bottom) {
  982. WriteRegion.Top = ScreenInfo->Window.Top
  983. + ConvAreaInfo->CaInfo.coordConView.Y
  984. + ConvAreaInfo->CaInfo.rcViewCaWindow.Top;
  985. WriteRegion.Bottom = WriteRegion.Top
  986. + (ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom - ConvAreaInfo->CaInfo.rcViewCaWindow.Top);
  987. }
  988. }
  989. ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
  990. ScreenInfo->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
  991. if (!(ConvAreaInfo->ConversionAreaMode & (CA_HIDDEN | CA_HIDE_FOR_SCROLL))) {
  992. WriteConvRegionToScreen(ScreenInfo,
  993. ConvAreaInfo,
  994. &WriteRegion
  995. );
  996. }
  997. else {
  998. WriteToScreen(ScreenInfo,&WriteRegion);
  999. }
  1000. ScreenInfo->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
  1001. return TRUE;
  1002. }
  1003. VOID
  1004. ConsoleImeViewInfo(
  1005. IN PCONSOLE_INFORMATION Console,
  1006. IN PCONVERSIONAREA_INFORMATION ConvAreaInfo,
  1007. IN COORD coordConView
  1008. )
  1009. {
  1010. SMALL_RECT OldRegion;
  1011. SMALL_RECT NewRegion;
  1012. if (ConvAreaInfo->ConversionAreaMode & CA_HIDDEN) {
  1013. ConvAreaInfo->CaInfo.coordConView = coordConView;
  1014. NewRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
  1015. NewRegion.Left += ConvAreaInfo->CaInfo.coordConView.X;
  1016. NewRegion.Right += ConvAreaInfo->CaInfo.coordConView.X;
  1017. NewRegion.Top += ConvAreaInfo->CaInfo.coordConView.Y;
  1018. NewRegion.Bottom += ConvAreaInfo->CaInfo.coordConView.Y;
  1019. }
  1020. else {
  1021. OldRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
  1022. OldRegion.Left += ConvAreaInfo->CaInfo.coordConView.X;
  1023. OldRegion.Right += ConvAreaInfo->CaInfo.coordConView.X;
  1024. OldRegion.Top += ConvAreaInfo->CaInfo.coordConView.Y;
  1025. OldRegion.Bottom += ConvAreaInfo->CaInfo.coordConView.Y;
  1026. ConvAreaInfo->CaInfo.coordConView = coordConView;
  1027. // Check code for must CONSOLE_TEXTMODE_BUFFER !!
  1028. ASSERT(!(Console->CurrentScreenBuffer->Flags & CONSOLE_GRAPHICS_BUFFER));
  1029. Console->CurrentScreenBuffer->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
  1030. Console->CurrentScreenBuffer->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
  1031. WriteToScreen(Console->CurrentScreenBuffer,&OldRegion);
  1032. NewRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
  1033. NewRegion.Left += ConvAreaInfo->CaInfo.coordConView.X;
  1034. NewRegion.Right += ConvAreaInfo->CaInfo.coordConView.X;
  1035. NewRegion.Top += ConvAreaInfo->CaInfo.coordConView.Y;
  1036. NewRegion.Bottom += ConvAreaInfo->CaInfo.coordConView.Y;
  1037. Console->CurrentScreenBuffer->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
  1038. WriteToScreen(Console->CurrentScreenBuffer,&NewRegion);
  1039. Console->CurrentScreenBuffer->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
  1040. }
  1041. }
  1042. VOID
  1043. ConsoleImeWindowInfo(
  1044. IN PCONSOLE_INFORMATION Console,
  1045. IN PCONVERSIONAREA_INFORMATION ConvAreaInfo,
  1046. IN SMALL_RECT rcViewCaWindow
  1047. )
  1048. {
  1049. if (rcViewCaWindow.Left != ConvAreaInfo->CaInfo.rcViewCaWindow.Left ||
  1050. rcViewCaWindow.Top != ConvAreaInfo->CaInfo.rcViewCaWindow.Top ||
  1051. rcViewCaWindow.Right != ConvAreaInfo->CaInfo.rcViewCaWindow.Right ||
  1052. rcViewCaWindow.Bottom != ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom) {
  1053. if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
  1054. ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
  1055. ConsoleImePaint(Console,ConvAreaInfo);
  1056. ConvAreaInfo->CaInfo.rcViewCaWindow = rcViewCaWindow;
  1057. ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
  1058. ConvAreaInfo->ScreenBuffer->BisectFlag &= ~(BISECT_LEFT | BISECT_RIGHT | BISECT_TOP | BISECT_BOTTOM);
  1059. ConsoleImePaint(Console,ConvAreaInfo);
  1060. }
  1061. else
  1062. ConvAreaInfo->CaInfo.rcViewCaWindow = rcViewCaWindow;
  1063. }
  1064. }
  1065. NTSTATUS
  1066. ConsoleImeResizeScreenBuffer(
  1067. IN PSCREEN_INFORMATION ScreenInfo,
  1068. IN COORD NewScreenSize,
  1069. PCONVERSIONAREA_INFORMATION ConvAreaInfo
  1070. )
  1071. {
  1072. NTSTATUS Status;
  1073. Status = ResizeScreenBuffer(ScreenInfo,
  1074. NewScreenSize,
  1075. FALSE);
  1076. if (NT_SUCCESS(Status)) {
  1077. ConvAreaInfo->CaInfo.coordCaBuffer = NewScreenSize;
  1078. if (ConvAreaInfo->CaInfo.rcViewCaWindow.Left > NewScreenSize.X-1)
  1079. ConvAreaInfo->CaInfo.rcViewCaWindow.Left = NewScreenSize.X-1;
  1080. if (ConvAreaInfo->CaInfo.rcViewCaWindow.Right > NewScreenSize.X-1)
  1081. ConvAreaInfo->CaInfo.rcViewCaWindow.Right = NewScreenSize.X-1;
  1082. if (ConvAreaInfo->CaInfo.rcViewCaWindow.Top > NewScreenSize.Y-1)
  1083. ConvAreaInfo->CaInfo.rcViewCaWindow.Top = NewScreenSize.Y-1;
  1084. if (ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom > NewScreenSize.Y-1)
  1085. ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom = NewScreenSize.Y-1;
  1086. }
  1087. return Status;
  1088. }
  1089. NTSTATUS
  1090. ConsoleImeWriteOutput(
  1091. IN PCONSOLE_INFORMATION Console,
  1092. IN PCONVERSIONAREA_INFORMATION ConvAreaInfo,
  1093. IN PCHAR_INFO Buffer,
  1094. IN SMALL_RECT CharRegion,
  1095. IN BOOL fUnicode
  1096. )
  1097. {
  1098. NTSTATUS Status;
  1099. PSCREEN_INFORMATION ScreenInfo;
  1100. COORD BufferSize;
  1101. SMALL_RECT ConvRegion;
  1102. COORD CursorPosition;
  1103. BufferSize.X = (SHORT)(CharRegion.Right - CharRegion.Left + 1);
  1104. BufferSize.Y = (SHORT)(CharRegion.Bottom - CharRegion.Top + 1);
  1105. ConvRegion = CharRegion;
  1106. ScreenInfo = ConvAreaInfo->ScreenBuffer;
  1107. if (!fUnicode) {
  1108. TranslateOutputToUnicode(Console,
  1109. Buffer,
  1110. BufferSize
  1111. );
  1112. Status = WriteScreenBuffer(ScreenInfo,
  1113. Buffer,
  1114. &ConvRegion
  1115. );
  1116. } else {
  1117. CHAR_INFO StackBuffer[STACK_BUFFER_SIZE * 2];
  1118. PCHAR_INFO TransBuffer;
  1119. BOOL StackBufferF = FALSE;
  1120. if (BufferSize.Y * BufferSize.X <= STACK_BUFFER_SIZE) {
  1121. TransBuffer = StackBuffer;
  1122. StackBufferF = TRUE;
  1123. } else {
  1124. TransBuffer = ConsoleHeapAlloc(TMP_DBCS_TAG, (BufferSize.Y * BufferSize.X) * 2 * sizeof(CHAR_INFO));
  1125. if (TransBuffer == NULL) {
  1126. return STATUS_NO_MEMORY;
  1127. }
  1128. }
  1129. if ((Console->CurrentScreenBuffer->Flags & CONSOLE_OEMFONT_DISPLAY) &&
  1130. ((Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
  1131. TranslateOutputToAnsiUnicode(Console,
  1132. Buffer,
  1133. BufferSize,
  1134. &TransBuffer[0]
  1135. );
  1136. }
  1137. else {
  1138. TranslateOutputToPaddingUnicode(Console,
  1139. Buffer,
  1140. BufferSize,
  1141. &TransBuffer[0]
  1142. );
  1143. }
  1144. Status = WriteScreenBuffer(ScreenInfo,
  1145. &TransBuffer[0],
  1146. &ConvRegion
  1147. );
  1148. if (!StackBufferF)
  1149. ConsoleHeapFree(TransBuffer);
  1150. }
  1151. if (NT_SUCCESS(Status)) {
  1152. ScreenInfo = Console->CurrentScreenBuffer;
  1153. // Check code for must CONSOLE_TEXTMODE_BUFFER !!
  1154. if (ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER) {
  1155. ASSERT(FALSE);
  1156. }
  1157. else if ((ConvAreaInfo->ConversionAreaMode & (CA_HIDDEN+CA_STATUS_LINE))==(CA_STATUS_LINE)) {
  1158. if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == (ScreenInfo->ScreenBufferSize.Y-1)
  1159. )
  1160. {
  1161. ConsoleHideCursor(ScreenInfo);
  1162. ConsoleImeBottomLineUse(ScreenInfo,1);
  1163. CursorPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
  1164. CursorPosition.Y--;
  1165. SetCursorPosition(ScreenInfo,CursorPosition,TRUE);
  1166. if (ScreenInfo->Console->lpCookedReadData) {
  1167. ((PCOOKED_READ_DATA)(ScreenInfo->Console->lpCookedReadData))->OriginalCursorPosition.Y--;
  1168. }
  1169. ConsoleShowCursor(ScreenInfo);
  1170. } else if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == ScreenInfo->Window.Bottom) {
  1171. COORD WindowOrigin;
  1172. WindowOrigin.X = ScreenInfo->Window.Left;
  1173. WindowOrigin.Y = ScreenInfo->Window.Top+1;
  1174. SetWindowOrigin(ScreenInfo, TRUE, WindowOrigin);
  1175. if ( ! (ScreenInfo->Console->InputBuffer.ImeMode.Disable) &&
  1176. ! (ScreenInfo->Console->InputBuffer.ImeMode.Unavailable) &&
  1177. (ScreenInfo->Console->InputBuffer.ImeMode.Open) ) {
  1178. SMALL_RECT Rectangle;
  1179. Rectangle.Left = ScreenInfo->Window.Left;
  1180. Rectangle.Right = ScreenInfo->Window.Right;
  1181. Rectangle.Top = ScreenInfo->Window.Bottom;
  1182. Rectangle.Bottom = ScreenInfo->Window.Bottom;
  1183. ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
  1184. WriteToScreen(ScreenInfo,&Rectangle);
  1185. ScreenInfo->BufferInfo.TextInfo.Flags |= TEXT_VALID_HINT;
  1186. WriteConvRegionToScreen(ScreenInfo,
  1187. ScreenInfo->Console->ConsoleIme.ConvAreaRoot,
  1188. &Rectangle);
  1189. }
  1190. }
  1191. }
  1192. //
  1193. // cause screen to be updated
  1194. //
  1195. ConvRegion.Left += (ScreenInfo->Window.Left + ConvAreaInfo->CaInfo.coordConView.X);
  1196. ConvRegion.Right += (ScreenInfo->Window.Left + ConvAreaInfo->CaInfo.coordConView.X);
  1197. ConvRegion.Top += (ScreenInfo->Window.Top + ConvAreaInfo->CaInfo.coordConView.Y);
  1198. ConvRegion.Bottom += (ScreenInfo->Window.Top + ConvAreaInfo->CaInfo.coordConView.Y);
  1199. // Check code for must CONSOLE_TEXTMODE_BUFFER !!
  1200. if (ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER) {
  1201. ASSERT(FALSE);
  1202. }
  1203. else
  1204. ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
  1205. WriteConvRegionToScreen(ScreenInfo,
  1206. ConvAreaInfo,
  1207. &ConvRegion
  1208. );
  1209. ConvAreaInfo->ScreenBuffer->BisectFlag &= ~(BISECT_LEFT | BISECT_RIGHT | BISECT_TOP | BISECT_BOTTOM);
  1210. }
  1211. return Status;
  1212. }
  1213. NTSTATUS
  1214. ImeControl(
  1215. IN PCONSOLE_INFORMATION Console,
  1216. IN HWND hWndConsoleIME,
  1217. IN PCOPYDATASTRUCT lParam
  1218. )
  1219. /*++
  1220. Routine Description:
  1221. This routine handle WM_COPYDATA message.
  1222. Arguments:
  1223. Console - Pointer to console information structure.
  1224. wParam -
  1225. lParam -
  1226. Return Value:
  1227. --*/
  1228. {
  1229. PSCREEN_INFORMATION ScreenInfo;
  1230. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  1231. PCHAR_INFO SystemString;
  1232. DWORD i, j;
  1233. if (lParam == NULL) {
  1234. // fail safe.
  1235. return STATUS_SUCCESS;
  1236. }
  1237. ScreenInfo = Console->CurrentScreenBuffer;
  1238. switch ((LONG)lParam->dwData) {
  1239. case CI_CONIMECOMPOSITION:
  1240. if (lParam->cbData >= sizeof(CONIME_UICOMPMESSAGE)) {
  1241. LPCONIME_UICOMPMESSAGE CompStr;
  1242. DBGPRINT(("CONSRV: Get IR_CONIMECOMPOSITION Message\n"));
  1243. CompStr = (LPCONIME_UICOMPMESSAGE)lParam->lpData;
  1244. if (CompStr && CompStr->dwSize == lParam->cbData) {
  1245. if (Console->ConsoleIme.CompStrData)
  1246. ConsoleHeapFree(Console->ConsoleIme.CompStrData);
  1247. Console->ConsoleIme.CompStrData = ConsoleHeapAlloc(
  1248. IME_TAG,
  1249. CompStr->dwSize);
  1250. if (Console->ConsoleIme.CompStrData == NULL)
  1251. break;
  1252. memmove(Console->ConsoleIme.CompStrData,CompStr,CompStr->dwSize);
  1253. ConsoleImeCompStr(Console, Console->ConsoleIme.CompStrData);
  1254. }
  1255. }
  1256. break;
  1257. case CI_CONIMEMODEINFO:
  1258. if (lParam->cbData == sizeof(CONIME_UIMODEINFO)) {
  1259. LPCONIME_UIMODEINFO lpModeInfo;
  1260. DBGPRINT(("CONSRV: Get IR_CONIMEMODEINFO Message\n"));
  1261. lpModeInfo = (LPCONIME_UIMODEINFO)lParam->lpData;
  1262. if (lpModeInfo != NULL) {
  1263. if (! Console->InputBuffer.ImeMode.Disable) {
  1264. if (lpModeInfo->ModeStringLen != 0){
  1265. for (j = 0; j < lpModeInfo->ModeStringLen; j++ )
  1266. lpModeInfo->ModeString[j].Attributes = Console->CurrentScreenBuffer->Attributes;
  1267. Console->ConsoleIme.ConvAreaModePosition = lpModeInfo->Position;
  1268. WriteModeSystemChars(Console,
  1269. Console->ConsoleIme.ConvAreaMode,
  1270. (PCHAR_INFO)&lpModeInfo->ModeString,
  1271. lpModeInfo->ModeStringLen,
  1272. Console->ConsoleIme.ConvAreaModePosition);
  1273. } else{
  1274. ConvAreaInfo = Console->ConsoleIme.ConvAreaMode;
  1275. if (ConvAreaInfo &&
  1276. (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
  1277. FillUndetermineChars(Console,ConvAreaInfo);
  1278. }
  1279. ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
  1280. if (ConvAreaInfo &&
  1281. (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
  1282. FillUndetermineChars(Console,ConvAreaInfo);
  1283. }
  1284. }
  1285. }
  1286. }
  1287. }
  1288. break;
  1289. case CI_CONIMESYSINFO: {
  1290. PWCHAR SourceString;
  1291. DBGPRINT(("CONSRV: Get IR_CONIMESYSINFO Message\n"));
  1292. if ((lParam->cbData != 0) &&
  1293. (lParam->lpData != NULL) &&
  1294. (! Console->InputBuffer.ImeMode.Disable)) {
  1295. i = (lParam->cbData / sizeof(WCHAR))-1;
  1296. SourceString = ((LPCONIME_UIMESSAGE)(lParam->lpData))->String;
  1297. SystemString = ConsoleHeapAlloc(IME_TAG,
  1298. sizeof(CHAR_INFO) * i);
  1299. if (SystemString == NULL) {
  1300. break;
  1301. }
  1302. for (j = 0; j < i; j++ ) {
  1303. SystemString[j].Char.UnicodeChar = *SourceString;
  1304. SystemString[j].Attributes = Console->CurrentScreenBuffer->Attributes;
  1305. SourceString++;
  1306. }
  1307. WriteModeSystemChars(Console,
  1308. Console->ConsoleIme.ConvAreaSystem,
  1309. (PCHAR_INFO)SystemString,
  1310. i,
  1311. VIEW_LEFT);
  1312. ConsoleHeapFree(SystemString);
  1313. } else {
  1314. ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
  1315. if (ConvAreaInfo &&
  1316. (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
  1317. FillUndetermineChars(Console,ConvAreaInfo);
  1318. }
  1319. }
  1320. break;
  1321. }
  1322. case CI_CONIMECANDINFO:{
  1323. PWCHAR SourceString;
  1324. PUCHAR SourceAttr;
  1325. DWORD LengthToWrite;
  1326. LPCONIME_CANDMESSAGE CandInfo = (LPCONIME_CANDMESSAGE)(lParam->lpData);
  1327. DBGPRINT(("CONSRV: Get IR_CONIMESYSINFO Message\n"));
  1328. if ((lParam->cbData != 0) &&
  1329. (CandInfo != NULL) ){
  1330. SourceString = CandInfo->String;
  1331. SourceAttr = (PUCHAR)((PBYTE)CandInfo + CandInfo->AttrOff);
  1332. LengthToWrite = lstrlenW(SourceString);
  1333. SystemString = ConsoleHeapAlloc(IME_TAG,
  1334. sizeof(CHAR_INFO) * LengthToWrite);
  1335. if (SystemString == NULL) {
  1336. break;
  1337. }
  1338. for (j = 0; j < LengthToWrite; j++ ) {
  1339. SystemString[j].Char.UnicodeChar = *SourceString;
  1340. if (*SourceAttr == 1 &&
  1341. Console->ConsoleIme.CompStrData != NULL) {
  1342. SystemString[j].Attributes = Console->ConsoleIme.CompStrData->CompAttrColor[1];
  1343. } else {
  1344. SystemString[j].Attributes = Console->CurrentScreenBuffer->Attributes;
  1345. }
  1346. SourceString++;
  1347. SourceAttr++;
  1348. }
  1349. WriteModeSystemChars(Console,
  1350. Console->ConsoleIme.ConvAreaSystem,
  1351. (PCHAR_INFO)SystemString,
  1352. LengthToWrite,
  1353. VIEW_LEFT);
  1354. ConsoleHeapFree(SystemString);
  1355. }
  1356. else {
  1357. ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
  1358. if (ConvAreaInfo) {
  1359. SMALL_RECT rcViewCaWindow = {0, 0, 0, 0};
  1360. FillUndetermineChars(Console,ConvAreaInfo);
  1361. ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
  1362. ConsoleImeWindowInfo(Console,ConvAreaInfo,rcViewCaWindow);
  1363. }
  1364. }
  1365. break;
  1366. }
  1367. case CI_CONIMEPROPERTYINFO:{
  1368. WPARAM* wParam = (WPARAM*)(lParam->lpData);
  1369. if ((lParam->cbData != 0) &&
  1370. (wParam != NULL) ){
  1371. switch (*wParam) {
  1372. case IMS_OPENPROPERTYWINDOW:
  1373. Console->InputBuffer.hWndConsoleIME = hWndConsoleIME;
  1374. break;
  1375. case IMS_CLOSEPROPERTYWINDOW:
  1376. Console->InputBuffer.hWndConsoleIME = NULL;
  1377. SetFocus(Console->hWnd);
  1378. break;
  1379. }
  1380. }
  1381. break;
  1382. }
  1383. }
  1384. return STATUS_SUCCESS;
  1385. }
  1386. BOOL
  1387. InsertConverTedString(
  1388. IN PCONSOLE_INFORMATION Console,
  1389. LPWSTR lpStr
  1390. )
  1391. {
  1392. ULONG EventsWritten;
  1393. PINPUT_RECORD InputEvent,TmpInputEvent;
  1394. DWORD dwControlKeyState;
  1395. DWORD dwLen;
  1396. DWORD dwConversion;
  1397. BOOL fResult = FALSE;
  1398. // Check code for must CONSOLE_TEXTMODE_BUFFER !!
  1399. if (Console->CurrentScreenBuffer->Flags & CONSOLE_GRAPHICS_BUFFER) {
  1400. ASSERT(FALSE);
  1401. } else if(Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorOn){
  1402. CursorTimerRoutine(Console->CurrentScreenBuffer);
  1403. }
  1404. dwLen = wcslen(lpStr)+1;
  1405. InputEvent = ConsoleHeapAlloc(IME_TAG, sizeof(INPUT_RECORD)*dwLen);
  1406. if (InputEvent == NULL) {
  1407. return FALSE;
  1408. }
  1409. TmpInputEvent = InputEvent;
  1410. dwControlKeyState = GetControlKeyState(0);
  1411. if (!NT_SUCCESS(GetImeKeyState(Console, &dwConversion))) {
  1412. goto skip_and_return;
  1413. }
  1414. dwControlKeyState |= ImmConversionToConsole(dwConversion);
  1415. while (*lpStr) {
  1416. TmpInputEvent->EventType = KEY_EVENT;
  1417. TmpInputEvent->Event.KeyEvent.bKeyDown = TRUE;
  1418. TmpInputEvent->Event.KeyEvent.wVirtualKeyCode = 0;
  1419. TmpInputEvent->Event.KeyEvent.wVirtualScanCode = 0;
  1420. TmpInputEvent->Event.KeyEvent.dwControlKeyState = dwControlKeyState;
  1421. TmpInputEvent->Event.KeyEvent.uChar.UnicodeChar = *lpStr++;
  1422. TmpInputEvent->Event.KeyEvent.wRepeatCount = 1;
  1423. TmpInputEvent++;
  1424. }
  1425. EventsWritten = WriteInputBuffer( Console,
  1426. &Console->InputBuffer,
  1427. InputEvent,
  1428. dwLen-1
  1429. );
  1430. fResult = TRUE;
  1431. skip_and_return:
  1432. ConsoleHeapFree(InputEvent);
  1433. return fResult;
  1434. }
  1435. VOID
  1436. SetUndetermineAttribute(
  1437. IN PCONSOLE_INFORMATION Console
  1438. )
  1439. {
  1440. PSCREEN_INFORMATION ScreenInfo;
  1441. PCONVERSIONAREA_INFORMATION ConvAreaInfo;
  1442. ScreenInfo = Console->CurrentScreenBuffer;
  1443. ConvAreaInfo = Console->ConsoleIme.ConvAreaRoot;
  1444. if (ConvAreaInfo != NULL) {
  1445. do {
  1446. ConvAreaInfo->ScreenBuffer->Attributes = ScreenInfo->Attributes;
  1447. ConvAreaInfo = ConvAreaInfo->ConvAreaNext;
  1448. } while (ConvAreaInfo != NULL);
  1449. }
  1450. if (Console->ConsoleIme.ConvAreaMode != NULL) {
  1451. Console->ConsoleIme.ConvAreaMode->ScreenBuffer->Attributes = ScreenInfo->Attributes;
  1452. }
  1453. if (Console->ConsoleIme.ConvAreaSystem != NULL) {
  1454. Console->ConsoleIme.ConvAreaSystem->ScreenBuffer->Attributes = ScreenInfo->Attributes;
  1455. }
  1456. }
  1457. VOID
  1458. StreamWriteToScreenBufferIME(
  1459. IN PWCHAR String,
  1460. IN SHORT StringLength,
  1461. IN PSCREEN_INFORMATION ScreenInfo,
  1462. IN PCHAR StringA
  1463. )
  1464. {
  1465. SHORT RowIndex;
  1466. PROW Row;
  1467. PWCHAR Char;
  1468. COORD TargetPoint;
  1469. DBGOUTPUT(("StreamWriteToScreenBuffer\n"));
  1470. // Check code for must CONSOLE_TEXTMODE_BUFFER !!
  1471. ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
  1472. ScreenInfo->BufferInfo.TextInfo.Flags |= TEXT_VALID_HINT;
  1473. TargetPoint = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
  1474. RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y;
  1475. Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
  1476. DBGOUTPUT(("RowIndex = %lx, Row = %lx, TargetPoint = (%d,%d)\n",
  1477. RowIndex, Row, TargetPoint.X, TargetPoint.Y));
  1478. //
  1479. // copy chars
  1480. //
  1481. //#if defined(FE_SB)
  1482. BisectWrite(StringLength,TargetPoint,ScreenInfo);
  1483. if (TargetPoint.Y == ScreenInfo->ScreenBufferSize.Y-1 &&
  1484. TargetPoint.X+StringLength >= ScreenInfo->ScreenBufferSize.X &&
  1485. *(StringA+ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) & ATTR_LEADING_BYTE
  1486. ) {
  1487. *(String+ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) = UNICODE_SPACE;
  1488. *(StringA+ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) = 0;
  1489. if (StringLength > ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) {
  1490. *(String+ScreenInfo->ScreenBufferSize.X-TargetPoint.X) = UNICODE_SPACE;
  1491. *(StringA+ScreenInfo->ScreenBufferSize.X-TargetPoint.X) = 0;
  1492. }
  1493. }
  1494. //#endif
  1495. RtlCopyMemory(&Row->CharRow.Chars[TargetPoint.X],String,StringLength*sizeof(WCHAR));
  1496. //#if defined(FE_SB)
  1497. RtlCopyMemory(&Row->CharRow.KAttrs[TargetPoint.X],StringA,StringLength*sizeof(CHAR));
  1498. //#endif
  1499. // recalculate first and last non-space char
  1500. Row->CharRow.OldLeft = Row->CharRow.Left;
  1501. if (TargetPoint.X < Row->CharRow.Left) {
  1502. //#if defined(FE_SB)
  1503. /*
  1504. * CharRow.Left is leftmost bound of chars in Chars array (array will be full width)
  1505. * i.e. type is COORD
  1506. */
  1507. PWCHAR LastChar = &Row->CharRow.Chars[ScreenInfo->ScreenBufferSize.X-1];
  1508. //#else
  1509. // PWCHAR LastChar = &Row->CharRow.Chars[ScreenInfo->ScreenBufferSize.X];
  1510. //#endif
  1511. for (Char=&Row->CharRow.Chars[TargetPoint.X];Char < LastChar && *Char==(WCHAR)' ';Char++) {
  1512. /* do nothing*/;
  1513. }
  1514. Row->CharRow.Left = (SHORT)(Char-Row->CharRow.Chars);
  1515. }
  1516. Row->CharRow.OldRight = Row->CharRow.Right;
  1517. if ((TargetPoint.X+StringLength) >= Row->CharRow.Right) {
  1518. PWCHAR FirstChar = Row->CharRow.Chars;
  1519. for (Char=&Row->CharRow.Chars[TargetPoint.X+StringLength-1];*Char==(WCHAR)' ' && Char >= FirstChar;Char--) {
  1520. /* do nothing */;
  1521. }
  1522. Row->CharRow.Right = (SHORT)(Char+1-FirstChar);
  1523. }
  1524. //
  1525. // see if attr string is different. if so, allocate a new
  1526. // attr buffer and merge the two strings.
  1527. //
  1528. if (Row->AttrRow.Length != 1 ||
  1529. Row->AttrRow.Attrs->Attr != ScreenInfo->Attributes) {
  1530. PATTR_PAIR NewAttrs;
  1531. WORD NewAttrsLength;
  1532. ATTR_PAIR Attrs;
  1533. //#if defined(FE_SB) && defined(FE_IME)
  1534. if ((ScreenInfo->Attributes & (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_RVERTICAL)) ==
  1535. (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_RVERTICAL)){
  1536. SHORT i;
  1537. for (i = 0; i < StringLength; i++ ) {
  1538. Attrs.Length = 1;
  1539. if (*(StringA + i) & ATTR_LEADING_BYTE) {
  1540. Attrs.Attr = ScreenInfo->Attributes & ~(COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_RVERTICAL);
  1541. } else {
  1542. Attrs.Attr = ScreenInfo->Attributes & ~COMMON_LVB_GRID_SINGLEFLAG;
  1543. }
  1544. if (!NT_SUCCESS(MergeAttrStrings(Row->AttrRow.Attrs,
  1545. Row->AttrRow.Length,
  1546. &Attrs,
  1547. 1,
  1548. &NewAttrs,
  1549. &NewAttrsLength,
  1550. (SHORT)(TargetPoint.X+i),
  1551. (SHORT)(TargetPoint.X+i),
  1552. Row,
  1553. ScreenInfo
  1554. ))) {
  1555. return;
  1556. }
  1557. if (Row->AttrRow.Length > 1) {
  1558. ConsoleHeapFree(Row->AttrRow.Attrs);
  1559. }
  1560. else {
  1561. ASSERT(Row->AttrRow.Attrs == &Row->AttrRow.AttrPair);
  1562. }
  1563. Row->AttrRow.Attrs = NewAttrs;
  1564. Row->AttrRow.Length = NewAttrsLength;
  1565. }
  1566. Row->CharRow.OldLeft = INVALID_OLD_LENGTH;
  1567. Row->CharRow.OldRight = INVALID_OLD_LENGTH;
  1568. }
  1569. else if ((ScreenInfo->Attributes & (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_LVERTICAL)) ==
  1570. (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_LVERTICAL)){
  1571. SHORT i;
  1572. for (i = 0; i < StringLength; i++ ) {
  1573. Attrs.Length = 1;
  1574. if (*(StringA + i) & ATTR_TRAILING_BYTE) {
  1575. Attrs.Attr = ScreenInfo->Attributes & ~(COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_LVERTICAL);
  1576. } else {
  1577. Attrs.Attr = ScreenInfo->Attributes & ~COMMON_LVB_GRID_SINGLEFLAG;
  1578. }
  1579. if (!NT_SUCCESS(MergeAttrStrings(Row->AttrRow.Attrs,
  1580. Row->AttrRow.Length,
  1581. &Attrs,
  1582. 1,
  1583. &NewAttrs,
  1584. &NewAttrsLength,
  1585. (SHORT)(TargetPoint.X+i),
  1586. (SHORT)(TargetPoint.X+i),
  1587. Row,
  1588. ScreenInfo
  1589. ))) {
  1590. return;
  1591. }
  1592. if (Row->AttrRow.Length > 1) {
  1593. ConsoleHeapFree(Row->AttrRow.Attrs);
  1594. }
  1595. else {
  1596. ASSERT(Row->AttrRow.Attrs == &Row->AttrRow.AttrPair);
  1597. }
  1598. Row->AttrRow.Attrs = NewAttrs;
  1599. Row->AttrRow.Length = NewAttrsLength;
  1600. }
  1601. Row->CharRow.OldLeft = INVALID_OLD_LENGTH;
  1602. Row->CharRow.OldRight = INVALID_OLD_LENGTH;
  1603. }
  1604. else{
  1605. //#endif
  1606. Attrs.Length = StringLength;
  1607. Attrs.Attr = ScreenInfo->Attributes;
  1608. if (!NT_SUCCESS(MergeAttrStrings(Row->AttrRow.Attrs,
  1609. Row->AttrRow.Length,
  1610. &Attrs,
  1611. 1,
  1612. &NewAttrs,
  1613. &NewAttrsLength,
  1614. TargetPoint.X,
  1615. (SHORT)(TargetPoint.X+StringLength-1),
  1616. Row,
  1617. ScreenInfo
  1618. ))) {
  1619. return;
  1620. }
  1621. if (Row->AttrRow.Length > 1) {
  1622. ConsoleHeapFree(Row->AttrRow.Attrs);
  1623. }
  1624. else {
  1625. ASSERT(Row->AttrRow.Attrs == &Row->AttrRow.AttrPair);
  1626. }
  1627. Row->AttrRow.Attrs = NewAttrs;
  1628. Row->AttrRow.Length = NewAttrsLength;
  1629. Row->CharRow.OldLeft = INVALID_OLD_LENGTH;
  1630. Row->CharRow.OldRight = INVALID_OLD_LENGTH;
  1631. //#if defined(FE_SB) && defined(FE_IME)
  1632. }
  1633. //#endif
  1634. }
  1635. ResetTextFlags(ScreenInfo,
  1636. TargetPoint.X,
  1637. TargetPoint.Y,
  1638. TargetPoint.X + StringLength - 1,
  1639. TargetPoint.Y);
  1640. }
  1641. #endif // FE_IME