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
1935 lines
66 KiB
/*++
|
|
|
|
Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
convarea.c
|
|
|
|
Abstract:
|
|
|
|
Author:
|
|
|
|
KazuM Mar.8,1993
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#if defined(FE_IME)
|
|
|
|
|
|
|
|
|
|
VOID
|
|
LinkConversionArea(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN PCONVERSIONAREA_INFORMATION ConvAreaInfo
|
|
)
|
|
{
|
|
PCONVERSIONAREA_INFORMATION PrevConvAreaInfo;
|
|
|
|
if (Console->ConsoleIme.ConvAreaRoot == NULL) {
|
|
Console->ConsoleIme.ConvAreaRoot = ConvAreaInfo;
|
|
}
|
|
else {
|
|
PrevConvAreaInfo = Console->ConsoleIme.ConvAreaRoot;
|
|
while (PrevConvAreaInfo->ConvAreaNext)
|
|
PrevConvAreaInfo = PrevConvAreaInfo->ConvAreaNext;
|
|
PrevConvAreaInfo->ConvAreaNext = ConvAreaInfo;
|
|
}
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
FreeConvAreaScreenBuffer(
|
|
IN PSCREEN_INFORMATION ScreenInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine frees the memory associated with a screen buffer.
|
|
|
|
Arguments:
|
|
|
|
ScreenInfo - screen buffer data to free.
|
|
|
|
Return Value:
|
|
|
|
Note: console handle table lock must be held when calling this routine
|
|
|
|
--*/
|
|
|
|
{
|
|
return FreeScreenBuffer(ScreenInfo);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
AllocateConversionArea(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN COORD dwScreenBufferSize,
|
|
OUT PCONVERSIONAREA_INFORMATION *ConvAreaInfo
|
|
)
|
|
{
|
|
COORD dwWindowSize;
|
|
CHAR_INFO Fill, PopupFill;
|
|
PCONVERSIONAREA_INFORMATION ca;
|
|
int FontIndex;
|
|
NTSTATUS Status;
|
|
|
|
//
|
|
// allocate console data
|
|
//
|
|
|
|
if (Console->CurrentScreenBuffer == NULL) {
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
ca = ConsoleHeapAlloc(CONVAREA_TAG,
|
|
sizeof(CONVERSIONAREA_INFORMATION));
|
|
if (ca == NULL) {
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
dwWindowSize.X = CONSOLE_WINDOW_SIZE_X(Console->CurrentScreenBuffer);
|
|
dwWindowSize.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer);
|
|
Fill.Attributes = Console->CurrentScreenBuffer->Attributes;
|
|
PopupFill.Attributes = Console->CurrentScreenBuffer->PopupAttributes;
|
|
FontIndex = FindCreateFont(CON_FAMILY(Console),
|
|
CON_FACENAME(Console),
|
|
CON_FONTSIZE(Console),
|
|
CON_FONTWEIGHT(Console),
|
|
CON_FONTCODEPAGE(Console)
|
|
);
|
|
Status = CreateScreenBuffer(&ca->ScreenBuffer,
|
|
dwWindowSize,
|
|
FontIndex,
|
|
dwScreenBufferSize,
|
|
Fill,
|
|
PopupFill,
|
|
Console,
|
|
CONSOLE_TEXTMODE_BUFFER,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
CURSOR_SMALL_SIZE,
|
|
NULL
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
ConsoleHeapFree(ca);
|
|
return Status;
|
|
}
|
|
|
|
*ConvAreaInfo = ca;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SetUpConversionArea(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN COORD coordCaBuffer,
|
|
IN SMALL_RECT rcViewCaWindow,
|
|
IN COORD coordConView,
|
|
IN DWORD dwOption,
|
|
OUT PCONVERSIONAREA_INFORMATION *ConvAreaInfo
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PCONVERSIONAREA_INFORMATION ca;
|
|
|
|
Status = AllocateConversionArea(Console, coordCaBuffer, &ca);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
ca->ConversionAreaMode = dwOption;
|
|
ca->CaInfo.coordCaBuffer = coordCaBuffer;
|
|
ca->CaInfo.rcViewCaWindow = rcViewCaWindow;
|
|
ca->CaInfo.coordConView = coordConView;
|
|
|
|
ca->ConvAreaNext = NULL;
|
|
|
|
ca->ScreenBuffer->ConvScreenInfo = ca;
|
|
|
|
LinkConversionArea(Console, ca);
|
|
|
|
SetUndetermineAttribute(Console);
|
|
|
|
*ConvAreaInfo = ca;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
VOID
|
|
WriteConvRegionToScreen(
|
|
IN PSCREEN_INFORMATION ScreenInfo,
|
|
IN PCONVERSIONAREA_INFORMATION ConvAreaInfo,
|
|
IN PSMALL_RECT ConvRegion
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
ClippedRegion - Rectangle of region by screen coordinate.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
SMALL_RECT Region;
|
|
SMALL_RECT ClippedRegion;
|
|
|
|
if (ScreenInfo->Console->CurrentScreenBuffer->Flags & CONSOLE_GRAPHICS_BUFFER)
|
|
return;
|
|
|
|
while (ConvAreaInfo) {
|
|
|
|
if ((ConvAreaInfo->ConversionAreaMode & (CA_HIDDEN+CA_HIDE_FOR_SCROLL))==0) {
|
|
//
|
|
// Do clipping region
|
|
//
|
|
Region.Left = ScreenInfo->Window.Left +
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow.Left +
|
|
ConvAreaInfo->CaInfo.coordConView.X;
|
|
Region.Right = Region.Left +
|
|
(ConvAreaInfo->CaInfo.rcViewCaWindow.Right -
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow.Left);
|
|
Region.Top = ScreenInfo->Window.Top +
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow.Top +
|
|
ConvAreaInfo->CaInfo.coordConView.Y;
|
|
Region.Bottom = Region.Top +
|
|
(ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom -
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow.Top);
|
|
ClippedRegion.Left = max(Region.Left, ScreenInfo->Window.Left);
|
|
ClippedRegion.Top = max(Region.Top, ScreenInfo->Window.Top);
|
|
ClippedRegion.Right = min(Region.Right, ScreenInfo->Window.Right);
|
|
ClippedRegion.Bottom = min(Region.Bottom, ScreenInfo->Window.Bottom);
|
|
if (ClippedRegion.Right < ClippedRegion.Left ||
|
|
ClippedRegion.Bottom < ClippedRegion.Top) {
|
|
/* TODO: Fix this. */;
|
|
} else {
|
|
Region = ClippedRegion;
|
|
ClippedRegion.Left = max(Region.Left, ConvRegion->Left);
|
|
ClippedRegion.Top = max(Region.Top, ConvRegion->Top);
|
|
ClippedRegion.Right = min(Region.Right, ConvRegion->Right);
|
|
ClippedRegion.Bottom = min(Region.Bottom, ConvRegion->Bottom);
|
|
if (ClippedRegion.Right < ClippedRegion.Left ||
|
|
ClippedRegion.Bottom < ClippedRegion.Top) {
|
|
/* TODO: Fix this */;
|
|
} else {
|
|
ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
|
|
ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
|
|
WriteRegionToScreen(ConvAreaInfo->ScreenBuffer,
|
|
&ClippedRegion
|
|
);
|
|
ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
|
|
}
|
|
}
|
|
}
|
|
ConvAreaInfo = ConvAreaInfo->ConvAreaNext;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
ConsoleImeBottomLineUse(
|
|
IN PSCREEN_INFORMATION ScreenInfo,
|
|
IN SHORT ScrollOffset
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
ScreenInfo -
|
|
|
|
ScrollOffset -
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
SMALL_RECT ScrollRectangle;
|
|
COORD DestinationOrigin;
|
|
CHAR_INFO Fill;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
SMALL_RECT WriteRegion;
|
|
BOOL fRedraw = FALSE;
|
|
|
|
if (!(ScreenInfo->Console->ConsoleIme.ScrollFlag & HIDE_FOR_SCROLL)) {
|
|
ScreenInfo->Console->ConsoleIme.ScrollFlag |= HIDE_FOR_SCROLL;
|
|
if (ConvAreaInfo = ScreenInfo->Console->ConsoleIme.ConvAreaRoot) {
|
|
do {
|
|
if ((ConvAreaInfo->ConversionAreaMode & (CA_STATUS_LINE))==0) {
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDE_FOR_SCROLL;
|
|
fRedraw = TRUE;
|
|
}
|
|
} while (ConvAreaInfo = ConvAreaInfo->ConvAreaNext);
|
|
|
|
if (fRedraw) {
|
|
// Check code for must CONSOLE_TEXTMODE_BUFFER !!
|
|
if (ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER)
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
else {
|
|
WriteRegion = ScreenInfo->Window;
|
|
WriteRegion.Bottom--;
|
|
ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
|
|
ScreenInfo->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
|
|
WriteToScreen(ScreenInfo,&WriteRegion);
|
|
ScreenInfo->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ScrollOffset) {
|
|
ScrollRectangle.Top = 1;
|
|
ScrollRectangle.Left = 0;
|
|
ScrollRectangle.Right = ScreenInfo->ScreenBufferSize.X-1;
|
|
ScrollRectangle.Bottom = ScreenInfo->ScreenBufferSize.Y-1;
|
|
ScrollRectangle.Bottom -= (ScrollOffset-1);
|
|
DestinationOrigin.X = ScrollRectangle.Left;
|
|
DestinationOrigin.Y = ScrollRectangle.Top-1;
|
|
Fill.Char.UnicodeChar = '\0';
|
|
Fill.Attributes = 0;
|
|
ScrollRegion(ScreenInfo,
|
|
&ScrollRectangle,
|
|
NULL,
|
|
DestinationOrigin,
|
|
Fill
|
|
);
|
|
#if defined(FE_SB)
|
|
#if defined(FE_IME)
|
|
if ( ! (ScreenInfo->Console->InputBuffer.ImeMode.Disable) &&
|
|
! (ScreenInfo->Console->InputBuffer.ImeMode.Unavailable) &&
|
|
(ScreenInfo->Console->InputBuffer.ImeMode.Open) &&
|
|
(ScrollRectangle.Left == ScreenInfo->Window.Left) &&
|
|
(ScrollRectangle.Right == ScreenInfo->Window.Right) ) {
|
|
ScrollRectangle.Top = ScreenInfo->Window.Bottom;
|
|
ScrollRectangle.Bottom = ScreenInfo->Window.Bottom;
|
|
WriteToScreen(ScreenInfo,&ScrollRectangle);
|
|
WriteConvRegionToScreen(ScreenInfo,
|
|
ScreenInfo->Console->ConsoleIme.ConvAreaRoot,
|
|
&ScrollRectangle);
|
|
}
|
|
#endif
|
|
#endif
|
|
}
|
|
else {
|
|
ScreenInfo->Console->ConsoleIme.ScrollWaitCountDown = ScreenInfo->Console->ConsoleIme.ScrollWaitTimeout;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
ConsoleImeBottomLineInUse(
|
|
IN PSCREEN_INFORMATION ScreenInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
ScreenInfo -
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
SMALL_RECT WriteRegion;
|
|
BOOL fRedraw = FALSE;
|
|
COORD CursorPosition;
|
|
|
|
ScreenInfo->Console->ConsoleIme.ScrollFlag &= ~HIDE_FOR_SCROLL;
|
|
if (ConvAreaInfo = ScreenInfo->Console->ConsoleIme.ConvAreaRoot) {
|
|
do {
|
|
if (ConvAreaInfo->ConversionAreaMode & CA_HIDE_FOR_SCROLL) {
|
|
ConvAreaInfo->ConversionAreaMode &= ~CA_HIDE_FOR_SCROLL;
|
|
fRedraw = TRUE;
|
|
}
|
|
} while (ConvAreaInfo = ConvAreaInfo->ConvAreaNext);
|
|
|
|
if (fRedraw) {
|
|
// Check code for must CONSOLE_TEXTMODE_BUFFER !!
|
|
if (ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER)
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
else {
|
|
if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == (ScreenInfo->ScreenBufferSize.Y-1)) {
|
|
ConsoleHideCursor(ScreenInfo);
|
|
ConsoleImeBottomLineUse(ScreenInfo,1);
|
|
CursorPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
|
|
CursorPosition.Y--;
|
|
SetCursorPosition(ScreenInfo,CursorPosition,TRUE);
|
|
if (ScreenInfo->Console->lpCookedReadData) {
|
|
((PCOOKED_READ_DATA)(ScreenInfo->Console->lpCookedReadData))->OriginalCursorPosition.Y--;
|
|
}
|
|
ConsoleShowCursor(ScreenInfo);
|
|
} else if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == ScreenInfo->Window.Bottom) {
|
|
/* TODO: Fix this. */;
|
|
}
|
|
|
|
WriteRegion.Top = 0;
|
|
WriteRegion.Bottom = (SHORT)(ScreenInfo->ScreenBufferSize.Y-1);
|
|
WriteRegion.Left = 0;
|
|
WriteRegion.Right = (SHORT)(ScreenInfo->ScreenBufferSize.X-1);
|
|
ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
|
|
ScreenInfo->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
|
|
WriteToScreen(ScreenInfo,&WriteRegion);
|
|
ScreenInfo->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
CreateConvAreaUndetermine(
|
|
PCONSOLE_INFORMATION Console
|
|
)
|
|
{
|
|
PCONSOLE_IME_INFORMATION ConsoleIme = &Console->ConsoleIme;
|
|
NTSTATUS Status;
|
|
COORD coordCaBuffer;
|
|
SMALL_RECT rcViewCaWindow;
|
|
COORD coordConView;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
|
|
if (ConsoleIme->ConvAreaCompStr) {
|
|
ConsoleIme->ConvAreaCompStr =
|
|
ConsoleHeapReAlloc(
|
|
0,
|
|
ConsoleIme->ConvAreaCompStr,
|
|
ConsoleHeapSize(
|
|
ConsoleIme->ConvAreaCompStr)+sizeof(PCONVERSIONAREA_INFORMATION));
|
|
if (ConsoleIme->ConvAreaCompStr == NULL)
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
else {
|
|
ConsoleIme->ConvAreaCompStr =
|
|
ConsoleHeapAlloc(
|
|
CONVAREA_TAG,
|
|
sizeof(PCONVERSIONAREA_INFORMATION));
|
|
if (ConsoleIme->ConvAreaCompStr == NULL)
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
coordCaBuffer = Console->CurrentScreenBuffer->ScreenBufferSize;
|
|
coordCaBuffer.Y = 1;
|
|
rcViewCaWindow.Top = 0;
|
|
rcViewCaWindow.Left = 0;
|
|
rcViewCaWindow.Bottom = 0;
|
|
rcViewCaWindow.Right = 0;
|
|
coordConView.X = 0;
|
|
coordConView.Y = 0;
|
|
Status = SetUpConversionArea(Console,
|
|
coordCaBuffer,
|
|
rcViewCaWindow,
|
|
coordConView,
|
|
(Console->ConsoleIme.ScrollFlag & HIDE_FOR_SCROLL) ?
|
|
CA_HIDE_FOR_SCROLL :
|
|
CA_HIDDEN,
|
|
&ConvAreaInfo
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
ConsoleIme->ConvAreaCompStr[ConsoleIme->NumberOfConvAreaCompStr] = ConvAreaInfo;
|
|
ConsoleIme->NumberOfConvAreaCompStr++;
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
CreateConvAreaModeSystem(
|
|
PCONSOLE_INFORMATION Console
|
|
)
|
|
{
|
|
PCONSOLE_IME_INFORMATION ConsoleIme = &Console->ConsoleIme;
|
|
NTSTATUS Status;
|
|
COORD coordCaBuffer;
|
|
SMALL_RECT rcViewCaWindow;
|
|
COORD coordConView;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
|
|
if (Console->CurrentScreenBuffer == NULL) {
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
/*
|
|
* Create mode text buffer
|
|
*/
|
|
coordCaBuffer = Console->CurrentScreenBuffer->ScreenBufferSize;
|
|
coordCaBuffer.Y = 1;
|
|
rcViewCaWindow.Top = 0;
|
|
rcViewCaWindow.Left = 0;
|
|
rcViewCaWindow.Bottom = 0;
|
|
rcViewCaWindow.Right = 0;
|
|
coordConView.X = 0;
|
|
coordConView.Y = 0;
|
|
Status = SetUpConversionArea(Console,
|
|
coordCaBuffer,
|
|
rcViewCaWindow,
|
|
coordConView,
|
|
CA_HIDDEN+CA_STATUS_LINE,
|
|
&ConvAreaInfo
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
ConsoleIme->ConvAreaMode = ConvAreaInfo;
|
|
|
|
/*
|
|
* Create system text buffer
|
|
*/
|
|
Status = SetUpConversionArea(Console,
|
|
coordCaBuffer,
|
|
rcViewCaWindow,
|
|
coordConView,
|
|
CA_HIDDEN+CA_STATUS_LINE,
|
|
&ConvAreaInfo
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
ConsoleIme->ConvAreaSystem = ConvAreaInfo;
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
#define LOCAL_BUFFER_SIZE 100
|
|
NTSTATUS
|
|
WriteUndetermineChars(
|
|
PCONSOLE_INFORMATION Console,
|
|
LPWSTR lpString,
|
|
PBYTE lpAtr,
|
|
PWORD lpAtrIdx,
|
|
DWORD NumChars // character count
|
|
)
|
|
{
|
|
PSCREEN_INFORMATION ScreenInfo;
|
|
PSCREEN_INFORMATION ConvScreenInfo;
|
|
WCHAR LocalBuffer[LOCAL_BUFFER_SIZE];
|
|
BYTE LocalBufferA[LOCAL_BUFFER_SIZE];
|
|
PWCHAR LocalBufPtr;
|
|
PBYTE LocalBufPtrA;
|
|
DWORD BufferSize;
|
|
COORD Position;
|
|
ULONG i;
|
|
SMALL_RECT Region;
|
|
COORD CursorPosition;
|
|
WCHAR Char;
|
|
WORD Attr;
|
|
PCONSOLE_IME_INFORMATION ConsoleIme;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
DWORD ConvAreaIndex;
|
|
NTSTATUS Status;
|
|
ULONG NumStr;
|
|
int WholeLen;
|
|
int WholeRow;
|
|
SHORT PosY;
|
|
BOOL UndetAreaUp = FALSE;
|
|
|
|
ConsoleIme = &Console->ConsoleIme;
|
|
ScreenInfo = Console->CurrentScreenBuffer;
|
|
|
|
// Check code for must CONSOLE_TEXTMODE_BUFFER !!
|
|
ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
|
|
|
|
Position = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
|
|
|
|
if ((ScreenInfo->Window.Left <= Position.X && Position.X <= ScreenInfo->Window.Right) &&
|
|
(ScreenInfo->Window.Top <= Position.Y && Position.Y <= ScreenInfo->Window.Bottom) ) {
|
|
Position.X = ScreenInfo->BufferInfo.TextInfo.CursorPosition.X - ScreenInfo->Window.Left;
|
|
Position.Y = ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y - ScreenInfo->Window.Top;
|
|
}
|
|
else {
|
|
Position.X = 0;
|
|
Position.Y = CONSOLE_WINDOW_SIZE_Y(ScreenInfo) - 2;
|
|
}
|
|
|
|
PosY = Position.Y;
|
|
RtlUnicodeToMultiByteSize(&NumStr, lpString, NumChars*sizeof(WCHAR));
|
|
|
|
WholeLen = (int)Position.X + (int)NumStr;
|
|
WholeRow = WholeLen / CONSOLE_WINDOW_SIZE_X(ScreenInfo);
|
|
if ( ( PosY + WholeRow ) > ( CONSOLE_WINDOW_SIZE_Y(ScreenInfo) - 2) ) {
|
|
PosY = CONSOLE_WINDOW_SIZE_Y(ScreenInfo) - 2 - WholeRow;
|
|
if (PosY < 0) {
|
|
PosY = ScreenInfo->Window.Top;
|
|
}
|
|
}
|
|
if (PosY != Position.Y) {
|
|
Position.Y = PosY;
|
|
UndetAreaUp = TRUE;
|
|
}
|
|
|
|
ConvAreaIndex = 0;
|
|
|
|
BufferSize = NumChars;
|
|
NumChars = 0;
|
|
|
|
for (ConvAreaIndex = 0; NumChars < BufferSize; ConvAreaIndex++) {
|
|
|
|
if (ConvAreaIndex+1 > ConsoleIme->NumberOfConvAreaCompStr) {
|
|
Status = CreateConvAreaUndetermine(Console);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
ConvAreaInfo = ConsoleIme->ConvAreaCompStr[ConvAreaIndex];
|
|
ConvScreenInfo = ConvAreaInfo->ScreenBuffer;
|
|
ConvScreenInfo->BufferInfo.TextInfo.CursorPosition.X = Position.X;
|
|
|
|
if ((ConvAreaInfo->ConversionAreaMode & CA_HIDDEN) ||
|
|
(UndetAreaUp)) {
|
|
/*
|
|
* This conversion area need positioning onto cursor position.
|
|
*/
|
|
CursorPosition.X = 0;
|
|
CursorPosition.Y = (SHORT)(Position.Y + ConvAreaIndex);
|
|
ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
|
|
}
|
|
|
|
Region.Left = ConvScreenInfo->BufferInfo.TextInfo.CursorPosition.X;
|
|
Region.Top = 0;
|
|
Region.Bottom = 0;
|
|
|
|
while (NumChars < BufferSize) {
|
|
i=0;
|
|
LocalBufPtr = LocalBuffer;
|
|
LocalBufPtrA = LocalBufferA;
|
|
|
|
while (NumChars < BufferSize &&
|
|
i < LOCAL_BUFFER_SIZE &&
|
|
Position.X < CONSOLE_WINDOW_SIZE_X(ScreenInfo)) {
|
|
Char = *lpString;
|
|
Attr = *lpAtr;
|
|
if (Char >= (WCHAR)' ') {
|
|
if (IsConsoleFullWidth(Console->hDC,Console->OutputCP,Char)) {
|
|
if (i < (LOCAL_BUFFER_SIZE-1) &&
|
|
Position.X < CONSOLE_WINDOW_SIZE_X(ScreenInfo)-1) {
|
|
*LocalBufPtr++ = Char;
|
|
*LocalBufPtrA++ = ATTR_LEADING_BYTE;
|
|
*LocalBufPtr++ = Char;
|
|
*LocalBufPtrA++ = ATTR_TRAILING_BYTE;
|
|
Position.X+=2;
|
|
i+=2;
|
|
}
|
|
else {
|
|
Position.X++;
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
*LocalBufPtr++ = Char;
|
|
*LocalBufPtrA++ = 0;
|
|
Position.X++;
|
|
i++;
|
|
}
|
|
}
|
|
lpString++;
|
|
lpAtr++;
|
|
NumChars++;
|
|
|
|
if (NumChars < BufferSize &&
|
|
Attr != *lpAtr)
|
|
break;
|
|
}
|
|
if (i != 0) {
|
|
ConvScreenInfo->Attributes = lpAtrIdx[Attr & 0x07];
|
|
if (Attr & 0x10) {
|
|
ConvScreenInfo->Attributes |= (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_RVERTICAL);
|
|
} else if (Attr & 0x20) {
|
|
ConvScreenInfo->Attributes |= (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_LVERTICAL);
|
|
}
|
|
StreamWriteToScreenBufferIME(LocalBuffer,
|
|
(SHORT)i,
|
|
ConvScreenInfo,
|
|
LocalBufferA);
|
|
|
|
ConvScreenInfo->BufferInfo.TextInfo.CursorPosition.X += (SHORT)i;
|
|
|
|
if (NumChars == BufferSize ||
|
|
Position.X >= CONSOLE_WINDOW_SIZE_X(ScreenInfo) ||
|
|
( (Char >= (WCHAR)' ' &&
|
|
IsConsoleFullWidth(Console->hDC,Console->OutputCP,Char) &&
|
|
Position.X >= CONSOLE_WINDOW_SIZE_X(ScreenInfo)-1) )
|
|
) {
|
|
|
|
Region.Right = (SHORT)(ConvScreenInfo->BufferInfo.TextInfo.CursorPosition.X - 1);
|
|
ConsoleImeWindowInfo(Console,ConvAreaInfo,Region);
|
|
|
|
ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
|
|
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
|
|
Position.X = 0;
|
|
break;
|
|
}
|
|
|
|
if (NumChars == BufferSize) {
|
|
return STATUS_SUCCESS;
|
|
}
|
|
continue;
|
|
|
|
} else if (NumChars == BufferSize) {
|
|
return STATUS_SUCCESS;
|
|
}
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
if (Position.X >= CONSOLE_WINDOW_SIZE_X(ScreenInfo)) {
|
|
Position.X = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
for (; ConvAreaIndex < ConsoleIme->NumberOfConvAreaCompStr; ConvAreaIndex++) {
|
|
ConvAreaInfo = ConsoleIme->ConvAreaCompStr[ConvAreaIndex];
|
|
if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
}
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
VOID
|
|
WriteModeSystemChars(
|
|
PCONSOLE_INFORMATION Console,
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo,
|
|
PCHAR_INFO Buffer,
|
|
DWORD NumberOfChars,
|
|
DWORD ViewPosition
|
|
)
|
|
{
|
|
SMALL_RECT CharRegion;
|
|
COORD CursorPosition;
|
|
|
|
if (Buffer) {
|
|
CharRegion.Left = 0;
|
|
CharRegion.Top = 0;
|
|
CharRegion.Right = CalcWideCharToColumn(Console,Buffer,NumberOfChars);
|
|
CharRegion.Right = (CharRegion.Right ? CharRegion.Right-1 : 0);
|
|
CharRegion.Bottom = 0;
|
|
}
|
|
else {
|
|
CharRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
|
|
}
|
|
if (ConvAreaInfo) {
|
|
if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
|
|
if (CharRegion.Left != ConvAreaInfo->CaInfo.rcViewCaWindow.Left ||
|
|
CharRegion.Top != ConvAreaInfo->CaInfo.rcViewCaWindow.Top ||
|
|
CharRegion.Right != ConvAreaInfo->CaInfo.rcViewCaWindow.Right ||
|
|
CharRegion.Bottom != ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom) {
|
|
switch (ViewPosition) {
|
|
case VIEW_LEFT:
|
|
CursorPosition.X = 0;
|
|
break;
|
|
case VIEW_RIGHT:
|
|
CursorPosition.X = CONSOLE_WINDOW_SIZE_X(Console->CurrentScreenBuffer) - (CharRegion.Right + 1);
|
|
break;
|
|
}
|
|
CursorPosition.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer) - 1;
|
|
ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
|
|
|
|
ConsoleImeWindowInfo(Console,ConvAreaInfo,CharRegion);
|
|
}
|
|
}
|
|
else {
|
|
/*
|
|
* This conversion area need positioning onto cursor position.
|
|
*/
|
|
switch (ViewPosition) {
|
|
case VIEW_LEFT:
|
|
CursorPosition.X = 0;
|
|
break;
|
|
case VIEW_RIGHT:
|
|
CursorPosition.X = CONSOLE_WINDOW_SIZE_X(Console->CurrentScreenBuffer) - (CharRegion.Right + 1);
|
|
break;
|
|
}
|
|
CursorPosition.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer) - 1;
|
|
ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
|
|
|
|
ConsoleImeWindowInfo(Console,ConvAreaInfo,CharRegion);
|
|
}
|
|
|
|
if (Buffer) {
|
|
ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
|
|
ConsoleImeWriteOutput(Console,ConvAreaInfo,Buffer,CharRegion,TRUE);
|
|
}
|
|
else {
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
FillUndetermineChars(
|
|
PCONSOLE_INFORMATION Console,
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo
|
|
)
|
|
{
|
|
COORD Coord;
|
|
DWORD CharsToWrite;
|
|
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
|
|
Coord.X = 0;
|
|
Coord.Y = 0;
|
|
CharsToWrite = ConvAreaInfo->ScreenBuffer->ScreenBufferSize.X;
|
|
FillOutput(ConvAreaInfo->ScreenBuffer,
|
|
(WCHAR)' ',
|
|
Coord,
|
|
CONSOLE_FALSE_UNICODE, // faster than real unicode
|
|
&CharsToWrite
|
|
);
|
|
CharsToWrite = ConvAreaInfo->ScreenBuffer->ScreenBufferSize.X;
|
|
FillOutput(ConvAreaInfo->ScreenBuffer,
|
|
Console->CurrentScreenBuffer->Attributes,
|
|
Coord,
|
|
CONSOLE_ATTRIBUTE,
|
|
&CharsToWrite
|
|
);
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
ConsoleImeCompStr(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN LPCONIME_UICOMPMESSAGE CompStr
|
|
)
|
|
{
|
|
UINT i;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
|
|
if (CompStr->dwCompStrLen == 0 ||
|
|
CompStr->dwResultStrLen != 0
|
|
) {
|
|
|
|
// Cursor turn ON.
|
|
if ((Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) &&
|
|
Console->ConsoleIme.SavedCursorVisible )
|
|
{
|
|
Console->ConsoleIme.SavedCursorVisible = FALSE;
|
|
SetCursorInformation(Console->CurrentScreenBuffer,
|
|
Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorSize,
|
|
TRUE);
|
|
}
|
|
|
|
/*
|
|
* Determine string.
|
|
*/
|
|
for (i=0; i<Console->ConsoleIme.NumberOfConvAreaCompStr; i++) {
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaCompStr[i];
|
|
if (ConvAreaInfo &&
|
|
(!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
|
|
FillUndetermineChars(Console,ConvAreaInfo);
|
|
}
|
|
}
|
|
|
|
if (CompStr->dwResultStrLen != 0)
|
|
{
|
|
if (!InsertConverTedString(Console, (LPWSTR)((PBYTE)CompStr + CompStr->dwResultStrOffset))) {
|
|
return STATUS_INVALID_HANDLE;
|
|
}
|
|
}
|
|
if (Console->ConsoleIme.CompStrData) {
|
|
ConsoleHeapFree(Console->ConsoleIme.CompStrData);
|
|
Console->ConsoleIme.CompStrData = NULL;
|
|
}
|
|
}
|
|
else {
|
|
LPWSTR lpStr;
|
|
PBYTE lpAtr;
|
|
PWORD lpAtrIdx;
|
|
|
|
// Cursor turn OFF.
|
|
if ((Console->CurrentScreenBuffer->Flags & CONSOLE_TEXTMODE_BUFFER) &&
|
|
Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorVisible )
|
|
{
|
|
Console->ConsoleIme.SavedCursorVisible = TRUE;
|
|
SetCursorInformation(Console->CurrentScreenBuffer,
|
|
Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorSize,
|
|
FALSE);
|
|
}
|
|
|
|
/*
|
|
* Composition string.
|
|
*/
|
|
for (i=0; i<Console->ConsoleIme.NumberOfConvAreaCompStr; i++) {
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaCompStr[i];
|
|
if (ConvAreaInfo &&
|
|
(!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
|
|
FillUndetermineChars(Console,ConvAreaInfo);
|
|
}
|
|
}
|
|
|
|
lpStr = (LPWSTR)((PBYTE)CompStr + CompStr->dwCompStrOffset);
|
|
lpAtr = (PBYTE)CompStr + CompStr->dwCompAttrOffset;
|
|
lpAtrIdx = (PWORD)CompStr->CompAttrColor;
|
|
WriteUndetermineChars(Console, lpStr, lpAtr, lpAtrIdx, CompStr->dwCompStrLen / sizeof(WCHAR));
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
ConsoleImeResizeModeSystemView(
|
|
PCONSOLE_INFORMATION Console,
|
|
SMALL_RECT WindowRect
|
|
)
|
|
{
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
SMALL_RECT CharRegion;
|
|
COORD CursorPosition;
|
|
|
|
/*
|
|
* Mode string
|
|
*/
|
|
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaMode;
|
|
|
|
if (ConvAreaInfo &&
|
|
(!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
CharRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
|
|
|
|
if (Console->ConsoleIme.ConvAreaModePosition == VIEW_LEFT){
|
|
CursorPosition.X = 0;
|
|
}
|
|
else{
|
|
CursorPosition.X = CONSOLE_WINDOW_SIZE_X(Console->CurrentScreenBuffer) - (CharRegion.Right + 1);
|
|
}
|
|
|
|
CursorPosition.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer) - 1;
|
|
ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
|
|
ConsoleImeWindowInfo(Console,ConvAreaInfo,CharRegion);
|
|
ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
|
|
|
|
WriteModeSystemChars(Console,
|
|
Console->ConsoleIme.ConvAreaMode,
|
|
NULL,
|
|
0,
|
|
Console->ConsoleIme.ConvAreaModePosition);
|
|
}
|
|
|
|
/*
|
|
* System string
|
|
*/
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
|
|
if (ConvAreaInfo &&
|
|
(!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
|
|
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
|
|
CharRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
|
|
CursorPosition.X = 0;
|
|
CursorPosition.Y = CONSOLE_WINDOW_SIZE_Y(Console->CurrentScreenBuffer) - 1;
|
|
ConsoleImeViewInfo(Console,ConvAreaInfo,CursorPosition);
|
|
ConsoleImeWindowInfo(Console,ConvAreaInfo,CharRegion);
|
|
ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
|
|
|
|
WriteModeSystemChars(Console,
|
|
Console->ConsoleIme.ConvAreaSystem,
|
|
NULL,
|
|
0,
|
|
VIEW_LEFT);
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
UNREFERENCED_PARAMETER(WindowRect);
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
ConsoleImeResizeCompStrView(
|
|
PCONSOLE_INFORMATION Console,
|
|
SMALL_RECT WindowRect
|
|
)
|
|
{
|
|
UINT i;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
LPCONIME_UICOMPMESSAGE CompStr;
|
|
LPWSTR lpStr;
|
|
PBYTE lpAtr;
|
|
PWORD lpAtrIdx;
|
|
|
|
/*
|
|
* Compositon string
|
|
*/
|
|
CompStr = Console->ConsoleIme.CompStrData;
|
|
if (CompStr) {
|
|
for (i=0; i<Console->ConsoleIme.NumberOfConvAreaCompStr; i++) {
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaCompStr[i];
|
|
if (ConvAreaInfo &&
|
|
(!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
|
|
FillUndetermineChars(Console,ConvAreaInfo);
|
|
}
|
|
}
|
|
|
|
lpStr = (LPWSTR)((PBYTE)CompStr + CompStr->dwCompStrOffset);
|
|
lpAtr = (PBYTE)CompStr + CompStr->dwCompAttrOffset;
|
|
lpAtrIdx = (PWORD)CompStr->CompAttrColor;
|
|
|
|
WriteUndetermineChars(Console, lpStr, lpAtr, lpAtrIdx, CompStr->dwCompStrLen / sizeof(WCHAR));
|
|
}
|
|
return STATUS_SUCCESS;
|
|
UNREFERENCED_PARAMETER(WindowRect);
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
ConsoleImeResizeModeSystemScreenBuffer(
|
|
PCONSOLE_INFORMATION Console,
|
|
COORD NewScreenSize
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
|
|
/*
|
|
* Mode string
|
|
*/
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaMode;
|
|
if (ConvAreaInfo) {
|
|
if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
|
|
}
|
|
|
|
Status = ConsoleImeResizeScreenBuffer(ConvAreaInfo->ScreenBuffer,NewScreenSize,ConvAreaInfo);
|
|
if (! NT_SUCCESS(Status))
|
|
return Status;
|
|
}
|
|
|
|
/*
|
|
* System string
|
|
*/
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
|
|
if (ConvAreaInfo) {
|
|
if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
|
|
}
|
|
|
|
Status = ConsoleImeResizeScreenBuffer(ConvAreaInfo->ScreenBuffer,NewScreenSize,ConvAreaInfo);
|
|
if (! NT_SUCCESS(Status))
|
|
return Status;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
ConsoleImeResizeCompStrScreenBuffer(
|
|
PCONSOLE_INFORMATION Console,
|
|
COORD NewScreenSize
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
UINT i;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
|
|
/*
|
|
* Compositon string
|
|
*/
|
|
for (i=0; i<Console->ConsoleIme.NumberOfConvAreaCompStr; i++) {
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaCompStr[i];
|
|
|
|
if (ConvAreaInfo) {
|
|
if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
}
|
|
|
|
Status = ConsoleImeResizeScreenBuffer(ConvAreaInfo->ScreenBuffer,NewScreenSize,ConvAreaInfo);
|
|
if (! NT_SUCCESS(Status))
|
|
return Status;
|
|
}
|
|
|
|
}
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
SHORT
|
|
CalcWideCharToColumn(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN PCHAR_INFO Buffer,
|
|
IN DWORD NumberOfChars
|
|
)
|
|
{
|
|
SHORT Column = 0;
|
|
|
|
while (NumberOfChars--) {
|
|
if (IsConsoleFullWidth(Console->hDC,Console->OutputCP,Buffer->Char.UnicodeChar))
|
|
Column += 2;
|
|
else
|
|
Column++;
|
|
Buffer++;
|
|
}
|
|
return Column;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LONG
|
|
ConsoleImePaint(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN PCONVERSIONAREA_INFORMATION ConvAreaInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
This routine
|
|
|
|
--*/
|
|
|
|
{
|
|
PSCREEN_INFORMATION ScreenInfo;
|
|
SMALL_RECT WriteRegion;
|
|
COORD CursorPosition;
|
|
|
|
if (!ConvAreaInfo)
|
|
return FALSE;
|
|
|
|
ScreenInfo = Console->CurrentScreenBuffer;
|
|
if (!ScreenInfo)
|
|
return FALSE;
|
|
|
|
// Check code for must CONSOLE_TEXTMODE_BUFFER !!
|
|
ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
|
|
|
|
WriteRegion.Left = ScreenInfo->Window.Left
|
|
+ ConvAreaInfo->CaInfo.coordConView.X
|
|
+ ConvAreaInfo->CaInfo.rcViewCaWindow.Left;
|
|
WriteRegion.Right = WriteRegion.Left
|
|
+ (ConvAreaInfo->CaInfo.rcViewCaWindow.Right - ConvAreaInfo->CaInfo.rcViewCaWindow.Left);
|
|
WriteRegion.Top = ScreenInfo->Window.Top
|
|
+ ConvAreaInfo->CaInfo.coordConView.Y
|
|
+ ConvAreaInfo->CaInfo.rcViewCaWindow.Top;
|
|
WriteRegion.Bottom = WriteRegion.Top
|
|
+ (ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom - ConvAreaInfo->CaInfo.rcViewCaWindow.Top);
|
|
|
|
if ((ConvAreaInfo->ConversionAreaMode & (CA_HIDDEN+CA_STATUS_LINE))==(CA_STATUS_LINE)) {
|
|
if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == (ScreenInfo->ScreenBufferSize.Y-1)) {
|
|
ConsoleHideCursor(ScreenInfo);
|
|
ConsoleImeBottomLineUse(ScreenInfo,1);
|
|
CursorPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
|
|
CursorPosition.Y--;
|
|
SetCursorPosition(ScreenInfo,CursorPosition,TRUE);
|
|
if (ScreenInfo->Console->lpCookedReadData) {
|
|
((PCOOKED_READ_DATA)(ScreenInfo->Console->lpCookedReadData))->OriginalCursorPosition.Y--;
|
|
}
|
|
ConsoleShowCursor(ScreenInfo);
|
|
}
|
|
else if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == ScreenInfo->Window.Bottom) {
|
|
WriteRegion.Top = ScreenInfo->Window.Top
|
|
+ ConvAreaInfo->CaInfo.coordConView.Y
|
|
+ ConvAreaInfo->CaInfo.rcViewCaWindow.Top;
|
|
WriteRegion.Bottom = WriteRegion.Top
|
|
+ (ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom - ConvAreaInfo->CaInfo.rcViewCaWindow.Top);
|
|
}
|
|
}
|
|
|
|
ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
|
|
ScreenInfo->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
|
|
if (!(ConvAreaInfo->ConversionAreaMode & (CA_HIDDEN | CA_HIDE_FOR_SCROLL))) {
|
|
WriteConvRegionToScreen(ScreenInfo,
|
|
ConvAreaInfo,
|
|
&WriteRegion
|
|
);
|
|
}
|
|
else {
|
|
WriteToScreen(ScreenInfo,&WriteRegion);
|
|
}
|
|
ScreenInfo->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
ConsoleImeViewInfo(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN PCONVERSIONAREA_INFORMATION ConvAreaInfo,
|
|
IN COORD coordConView
|
|
)
|
|
{
|
|
SMALL_RECT OldRegion;
|
|
SMALL_RECT NewRegion;
|
|
|
|
if (ConvAreaInfo->ConversionAreaMode & CA_HIDDEN) {
|
|
ConvAreaInfo->CaInfo.coordConView = coordConView;
|
|
NewRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
|
|
NewRegion.Left += ConvAreaInfo->CaInfo.coordConView.X;
|
|
NewRegion.Right += ConvAreaInfo->CaInfo.coordConView.X;
|
|
NewRegion.Top += ConvAreaInfo->CaInfo.coordConView.Y;
|
|
NewRegion.Bottom += ConvAreaInfo->CaInfo.coordConView.Y;
|
|
}
|
|
else {
|
|
OldRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
|
|
OldRegion.Left += ConvAreaInfo->CaInfo.coordConView.X;
|
|
OldRegion.Right += ConvAreaInfo->CaInfo.coordConView.X;
|
|
OldRegion.Top += ConvAreaInfo->CaInfo.coordConView.Y;
|
|
OldRegion.Bottom += ConvAreaInfo->CaInfo.coordConView.Y;
|
|
ConvAreaInfo->CaInfo.coordConView = coordConView;
|
|
|
|
// Check code for must CONSOLE_TEXTMODE_BUFFER !!
|
|
ASSERT(!(Console->CurrentScreenBuffer->Flags & CONSOLE_GRAPHICS_BUFFER));
|
|
|
|
Console->CurrentScreenBuffer->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
|
|
Console->CurrentScreenBuffer->BufferInfo.TextInfo.Flags |= CONSOLE_CONVERSION_AREA_REDRAW;
|
|
WriteToScreen(Console->CurrentScreenBuffer,&OldRegion);
|
|
|
|
NewRegion = ConvAreaInfo->CaInfo.rcViewCaWindow;
|
|
NewRegion.Left += ConvAreaInfo->CaInfo.coordConView.X;
|
|
NewRegion.Right += ConvAreaInfo->CaInfo.coordConView.X;
|
|
NewRegion.Top += ConvAreaInfo->CaInfo.coordConView.Y;
|
|
NewRegion.Bottom += ConvAreaInfo->CaInfo.coordConView.Y;
|
|
Console->CurrentScreenBuffer->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
|
|
WriteToScreen(Console->CurrentScreenBuffer,&NewRegion);
|
|
Console->CurrentScreenBuffer->BufferInfo.TextInfo.Flags &= ~CONSOLE_CONVERSION_AREA_REDRAW;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ConsoleImeWindowInfo(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN PCONVERSIONAREA_INFORMATION ConvAreaInfo,
|
|
IN SMALL_RECT rcViewCaWindow
|
|
)
|
|
{
|
|
if (rcViewCaWindow.Left != ConvAreaInfo->CaInfo.rcViewCaWindow.Left ||
|
|
rcViewCaWindow.Top != ConvAreaInfo->CaInfo.rcViewCaWindow.Top ||
|
|
rcViewCaWindow.Right != ConvAreaInfo->CaInfo.rcViewCaWindow.Right ||
|
|
rcViewCaWindow.Bottom != ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom) {
|
|
if (!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN)) {
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow = rcViewCaWindow;
|
|
ConvAreaInfo->ConversionAreaMode &= ~CA_HIDDEN;
|
|
ConvAreaInfo->ScreenBuffer->BisectFlag &= ~(BISECT_LEFT | BISECT_RIGHT | BISECT_TOP | BISECT_BOTTOM);
|
|
ConsoleImePaint(Console,ConvAreaInfo);
|
|
}
|
|
else
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow = rcViewCaWindow;
|
|
}
|
|
}
|
|
|
|
NTSTATUS
|
|
ConsoleImeResizeScreenBuffer(
|
|
IN PSCREEN_INFORMATION ScreenInfo,
|
|
IN COORD NewScreenSize,
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = ResizeScreenBuffer(ScreenInfo,
|
|
NewScreenSize,
|
|
FALSE);
|
|
if (NT_SUCCESS(Status)) {
|
|
ConvAreaInfo->CaInfo.coordCaBuffer = NewScreenSize;
|
|
if (ConvAreaInfo->CaInfo.rcViewCaWindow.Left > NewScreenSize.X-1)
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow.Left = NewScreenSize.X-1;
|
|
if (ConvAreaInfo->CaInfo.rcViewCaWindow.Right > NewScreenSize.X-1)
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow.Right = NewScreenSize.X-1;
|
|
if (ConvAreaInfo->CaInfo.rcViewCaWindow.Top > NewScreenSize.Y-1)
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow.Top = NewScreenSize.Y-1;
|
|
if (ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom > NewScreenSize.Y-1)
|
|
ConvAreaInfo->CaInfo.rcViewCaWindow.Bottom = NewScreenSize.Y-1;
|
|
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
ConsoleImeWriteOutput(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN PCONVERSIONAREA_INFORMATION ConvAreaInfo,
|
|
IN PCHAR_INFO Buffer,
|
|
IN SMALL_RECT CharRegion,
|
|
IN BOOL fUnicode
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PSCREEN_INFORMATION ScreenInfo;
|
|
COORD BufferSize;
|
|
SMALL_RECT ConvRegion;
|
|
COORD CursorPosition;
|
|
|
|
BufferSize.X = (SHORT)(CharRegion.Right - CharRegion.Left + 1);
|
|
BufferSize.Y = (SHORT)(CharRegion.Bottom - CharRegion.Top + 1);
|
|
|
|
ConvRegion = CharRegion;
|
|
|
|
ScreenInfo = ConvAreaInfo->ScreenBuffer;
|
|
|
|
if (!fUnicode) {
|
|
TranslateOutputToUnicode(Console,
|
|
Buffer,
|
|
BufferSize
|
|
);
|
|
Status = WriteScreenBuffer(ScreenInfo,
|
|
Buffer,
|
|
&ConvRegion
|
|
);
|
|
} else {
|
|
CHAR_INFO StackBuffer[STACK_BUFFER_SIZE * 2];
|
|
PCHAR_INFO TransBuffer;
|
|
BOOL StackBufferF = FALSE;
|
|
|
|
if (BufferSize.Y * BufferSize.X <= STACK_BUFFER_SIZE) {
|
|
TransBuffer = StackBuffer;
|
|
StackBufferF = TRUE;
|
|
} else {
|
|
TransBuffer = ConsoleHeapAlloc(TMP_DBCS_TAG, (BufferSize.Y * BufferSize.X) * 2 * sizeof(CHAR_INFO));
|
|
if (TransBuffer == NULL) {
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
}
|
|
if ((Console->CurrentScreenBuffer->Flags & CONSOLE_OEMFONT_DISPLAY) &&
|
|
((Console->FullScreenFlags & CONSOLE_FULLSCREEN) == 0)) {
|
|
TranslateOutputToAnsiUnicode(Console,
|
|
Buffer,
|
|
BufferSize,
|
|
&TransBuffer[0]
|
|
);
|
|
}
|
|
else {
|
|
TranslateOutputToPaddingUnicode(Console,
|
|
Buffer,
|
|
BufferSize,
|
|
&TransBuffer[0]
|
|
);
|
|
}
|
|
|
|
Status = WriteScreenBuffer(ScreenInfo,
|
|
&TransBuffer[0],
|
|
&ConvRegion
|
|
);
|
|
if (!StackBufferF)
|
|
ConsoleHeapFree(TransBuffer);
|
|
}
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
ScreenInfo = Console->CurrentScreenBuffer;
|
|
|
|
|
|
// Check code for must CONSOLE_TEXTMODE_BUFFER !!
|
|
if (ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER) {
|
|
ASSERT(FALSE);
|
|
}
|
|
else if ((ConvAreaInfo->ConversionAreaMode & (CA_HIDDEN+CA_STATUS_LINE))==(CA_STATUS_LINE)) {
|
|
if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == (ScreenInfo->ScreenBufferSize.Y-1)
|
|
)
|
|
{
|
|
ConsoleHideCursor(ScreenInfo);
|
|
ConsoleImeBottomLineUse(ScreenInfo,1);
|
|
CursorPosition = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
|
|
CursorPosition.Y--;
|
|
SetCursorPosition(ScreenInfo,CursorPosition,TRUE);
|
|
if (ScreenInfo->Console->lpCookedReadData) {
|
|
((PCOOKED_READ_DATA)(ScreenInfo->Console->lpCookedReadData))->OriginalCursorPosition.Y--;
|
|
}
|
|
ConsoleShowCursor(ScreenInfo);
|
|
} else if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y == ScreenInfo->Window.Bottom) {
|
|
COORD WindowOrigin;
|
|
WindowOrigin.X = ScreenInfo->Window.Left;
|
|
WindowOrigin.Y = ScreenInfo->Window.Top+1;
|
|
SetWindowOrigin(ScreenInfo, TRUE, WindowOrigin);
|
|
if ( ! (ScreenInfo->Console->InputBuffer.ImeMode.Disable) &&
|
|
! (ScreenInfo->Console->InputBuffer.ImeMode.Unavailable) &&
|
|
(ScreenInfo->Console->InputBuffer.ImeMode.Open) ) {
|
|
SMALL_RECT Rectangle;
|
|
Rectangle.Left = ScreenInfo->Window.Left;
|
|
Rectangle.Right = ScreenInfo->Window.Right;
|
|
Rectangle.Top = ScreenInfo->Window.Bottom;
|
|
Rectangle.Bottom = ScreenInfo->Window.Bottom;
|
|
ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
|
|
WriteToScreen(ScreenInfo,&Rectangle);
|
|
ScreenInfo->BufferInfo.TextInfo.Flags |= TEXT_VALID_HINT;
|
|
WriteConvRegionToScreen(ScreenInfo,
|
|
ScreenInfo->Console->ConsoleIme.ConvAreaRoot,
|
|
&Rectangle);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// cause screen to be updated
|
|
//
|
|
ConvRegion.Left += (ScreenInfo->Window.Left + ConvAreaInfo->CaInfo.coordConView.X);
|
|
ConvRegion.Right += (ScreenInfo->Window.Left + ConvAreaInfo->CaInfo.coordConView.X);
|
|
ConvRegion.Top += (ScreenInfo->Window.Top + ConvAreaInfo->CaInfo.coordConView.Y);
|
|
ConvRegion.Bottom += (ScreenInfo->Window.Top + ConvAreaInfo->CaInfo.coordConView.Y);
|
|
|
|
|
|
// Check code for must CONSOLE_TEXTMODE_BUFFER !!
|
|
if (ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER) {
|
|
ASSERT(FALSE);
|
|
}
|
|
else
|
|
ScreenInfo->BufferInfo.TextInfo.Flags &= ~TEXT_VALID_HINT;
|
|
WriteConvRegionToScreen(ScreenInfo,
|
|
ConvAreaInfo,
|
|
&ConvRegion
|
|
);
|
|
ConvAreaInfo->ScreenBuffer->BisectFlag &= ~(BISECT_LEFT | BISECT_RIGHT | BISECT_TOP | BISECT_BOTTOM);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
ImeControl(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
IN HWND hWndConsoleIME,
|
|
IN PCOPYDATASTRUCT lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine handle WM_COPYDATA message.
|
|
|
|
Arguments:
|
|
|
|
Console - Pointer to console information structure.
|
|
|
|
wParam -
|
|
|
|
lParam -
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
PSCREEN_INFORMATION ScreenInfo;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
PCHAR_INFO SystemString;
|
|
DWORD i, j;
|
|
|
|
if (lParam == NULL) {
|
|
// fail safe.
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
ScreenInfo = Console->CurrentScreenBuffer;
|
|
switch ((LONG)lParam->dwData) {
|
|
case CI_CONIMECOMPOSITION:
|
|
if (lParam->cbData >= sizeof(CONIME_UICOMPMESSAGE)) {
|
|
LPCONIME_UICOMPMESSAGE CompStr;
|
|
|
|
DBGPRINT(("CONSRV: Get IR_CONIMECOMPOSITION Message\n"));
|
|
CompStr = (LPCONIME_UICOMPMESSAGE)lParam->lpData;
|
|
if (CompStr && CompStr->dwSize == lParam->cbData) {
|
|
if (Console->ConsoleIme.CompStrData)
|
|
ConsoleHeapFree(Console->ConsoleIme.CompStrData);
|
|
Console->ConsoleIme.CompStrData = ConsoleHeapAlloc(
|
|
IME_TAG,
|
|
CompStr->dwSize);
|
|
if (Console->ConsoleIme.CompStrData == NULL)
|
|
break;
|
|
memmove(Console->ConsoleIme.CompStrData,CompStr,CompStr->dwSize);
|
|
ConsoleImeCompStr(Console, Console->ConsoleIme.CompStrData);
|
|
}
|
|
}
|
|
break;
|
|
case CI_CONIMEMODEINFO:
|
|
if (lParam->cbData == sizeof(CONIME_UIMODEINFO)) {
|
|
LPCONIME_UIMODEINFO lpModeInfo;
|
|
|
|
DBGPRINT(("CONSRV: Get IR_CONIMEMODEINFO Message\n"));
|
|
|
|
lpModeInfo = (LPCONIME_UIMODEINFO)lParam->lpData;
|
|
if (lpModeInfo != NULL) {
|
|
if (! Console->InputBuffer.ImeMode.Disable) {
|
|
if (lpModeInfo->ModeStringLen != 0){
|
|
for (j = 0; j < lpModeInfo->ModeStringLen; j++ )
|
|
lpModeInfo->ModeString[j].Attributes = Console->CurrentScreenBuffer->Attributes;
|
|
Console->ConsoleIme.ConvAreaModePosition = lpModeInfo->Position;
|
|
WriteModeSystemChars(Console,
|
|
Console->ConsoleIme.ConvAreaMode,
|
|
(PCHAR_INFO)&lpModeInfo->ModeString,
|
|
lpModeInfo->ModeStringLen,
|
|
Console->ConsoleIme.ConvAreaModePosition);
|
|
} else{
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaMode;
|
|
if (ConvAreaInfo &&
|
|
(!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
|
|
FillUndetermineChars(Console,ConvAreaInfo);
|
|
}
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
|
|
if (ConvAreaInfo &&
|
|
(!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
|
|
FillUndetermineChars(Console,ConvAreaInfo);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CI_CONIMESYSINFO: {
|
|
PWCHAR SourceString;
|
|
|
|
DBGPRINT(("CONSRV: Get IR_CONIMESYSINFO Message\n"));
|
|
|
|
if ((lParam->cbData != 0) &&
|
|
(lParam->lpData != NULL) &&
|
|
(! Console->InputBuffer.ImeMode.Disable)) {
|
|
i = (lParam->cbData / sizeof(WCHAR))-1;
|
|
SourceString = ((LPCONIME_UIMESSAGE)(lParam->lpData))->String;
|
|
SystemString = ConsoleHeapAlloc(IME_TAG,
|
|
sizeof(CHAR_INFO) * i);
|
|
if (SystemString == NULL) {
|
|
break;
|
|
}
|
|
for (j = 0; j < i; j++ ) {
|
|
SystemString[j].Char.UnicodeChar = *SourceString;
|
|
SystemString[j].Attributes = Console->CurrentScreenBuffer->Attributes;
|
|
SourceString++;
|
|
}
|
|
WriteModeSystemChars(Console,
|
|
Console->ConsoleIme.ConvAreaSystem,
|
|
(PCHAR_INFO)SystemString,
|
|
i,
|
|
VIEW_LEFT);
|
|
ConsoleHeapFree(SystemString);
|
|
} else {
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
|
|
if (ConvAreaInfo &&
|
|
(!(ConvAreaInfo->ConversionAreaMode & CA_HIDDEN))) {
|
|
FillUndetermineChars(Console,ConvAreaInfo);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case CI_CONIMECANDINFO:{
|
|
PWCHAR SourceString;
|
|
PUCHAR SourceAttr;
|
|
DWORD LengthToWrite;
|
|
LPCONIME_CANDMESSAGE CandInfo = (LPCONIME_CANDMESSAGE)(lParam->lpData);
|
|
|
|
DBGPRINT(("CONSRV: Get IR_CONIMESYSINFO Message\n"));
|
|
|
|
if ((lParam->cbData != 0) &&
|
|
(CandInfo != NULL) ){
|
|
SourceString = CandInfo->String;
|
|
SourceAttr = (PUCHAR)((PBYTE)CandInfo + CandInfo->AttrOff);
|
|
LengthToWrite = lstrlenW(SourceString);
|
|
SystemString = ConsoleHeapAlloc(IME_TAG,
|
|
sizeof(CHAR_INFO) * LengthToWrite);
|
|
if (SystemString == NULL) {
|
|
break;
|
|
}
|
|
for (j = 0; j < LengthToWrite; j++ ) {
|
|
SystemString[j].Char.UnicodeChar = *SourceString;
|
|
if (*SourceAttr == 1 &&
|
|
Console->ConsoleIme.CompStrData != NULL) {
|
|
SystemString[j].Attributes = Console->ConsoleIme.CompStrData->CompAttrColor[1];
|
|
} else {
|
|
SystemString[j].Attributes = Console->CurrentScreenBuffer->Attributes;
|
|
}
|
|
SourceString++;
|
|
SourceAttr++;
|
|
}
|
|
WriteModeSystemChars(Console,
|
|
Console->ConsoleIme.ConvAreaSystem,
|
|
(PCHAR_INFO)SystemString,
|
|
LengthToWrite,
|
|
VIEW_LEFT);
|
|
ConsoleHeapFree(SystemString);
|
|
}
|
|
else {
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaSystem;
|
|
if (ConvAreaInfo) {
|
|
SMALL_RECT rcViewCaWindow = {0, 0, 0, 0};
|
|
FillUndetermineChars(Console,ConvAreaInfo);
|
|
ConvAreaInfo->ConversionAreaMode |= CA_HIDDEN;
|
|
ConsoleImeWindowInfo(Console,ConvAreaInfo,rcViewCaWindow);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case CI_CONIMEPROPERTYINFO:{
|
|
WPARAM* wParam = (WPARAM*)(lParam->lpData);
|
|
|
|
if ((lParam->cbData != 0) &&
|
|
(wParam != NULL) ){
|
|
switch (*wParam) {
|
|
case IMS_OPENPROPERTYWINDOW:
|
|
Console->InputBuffer.hWndConsoleIME = hWndConsoleIME;
|
|
break;
|
|
case IMS_CLOSEPROPERTYWINDOW:
|
|
Console->InputBuffer.hWndConsoleIME = NULL;
|
|
SetFocus(Console->hWnd);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
BOOL
|
|
InsertConverTedString(
|
|
IN PCONSOLE_INFORMATION Console,
|
|
LPWSTR lpStr
|
|
)
|
|
{
|
|
ULONG EventsWritten;
|
|
PINPUT_RECORD InputEvent,TmpInputEvent;
|
|
DWORD dwControlKeyState;
|
|
DWORD dwLen;
|
|
DWORD dwConversion;
|
|
BOOL fResult = FALSE;
|
|
|
|
// Check code for must CONSOLE_TEXTMODE_BUFFER !!
|
|
if (Console->CurrentScreenBuffer->Flags & CONSOLE_GRAPHICS_BUFFER) {
|
|
ASSERT(FALSE);
|
|
} else if(Console->CurrentScreenBuffer->BufferInfo.TextInfo.CursorOn){
|
|
CursorTimerRoutine(Console->CurrentScreenBuffer);
|
|
}
|
|
|
|
dwLen = wcslen(lpStr)+1;
|
|
InputEvent = ConsoleHeapAlloc(IME_TAG, sizeof(INPUT_RECORD)*dwLen);
|
|
if (InputEvent == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
TmpInputEvent = InputEvent;
|
|
dwControlKeyState = GetControlKeyState(0);
|
|
|
|
if (!NT_SUCCESS(GetImeKeyState(Console, &dwConversion))) {
|
|
goto skip_and_return;
|
|
}
|
|
|
|
dwControlKeyState |= ImmConversionToConsole(dwConversion);
|
|
|
|
while (*lpStr) {
|
|
TmpInputEvent->EventType = KEY_EVENT;
|
|
TmpInputEvent->Event.KeyEvent.bKeyDown = TRUE;
|
|
TmpInputEvent->Event.KeyEvent.wVirtualKeyCode = 0;
|
|
TmpInputEvent->Event.KeyEvent.wVirtualScanCode = 0;
|
|
TmpInputEvent->Event.KeyEvent.dwControlKeyState = dwControlKeyState;
|
|
TmpInputEvent->Event.KeyEvent.uChar.UnicodeChar = *lpStr++;
|
|
TmpInputEvent->Event.KeyEvent.wRepeatCount = 1;
|
|
TmpInputEvent++;
|
|
}
|
|
|
|
EventsWritten = WriteInputBuffer( Console,
|
|
&Console->InputBuffer,
|
|
InputEvent,
|
|
dwLen-1
|
|
);
|
|
|
|
fResult = TRUE;
|
|
|
|
skip_and_return:
|
|
ConsoleHeapFree(InputEvent);
|
|
return fResult;
|
|
}
|
|
|
|
|
|
VOID
|
|
SetUndetermineAttribute(
|
|
IN PCONSOLE_INFORMATION Console
|
|
)
|
|
{
|
|
PSCREEN_INFORMATION ScreenInfo;
|
|
PCONVERSIONAREA_INFORMATION ConvAreaInfo;
|
|
|
|
ScreenInfo = Console->CurrentScreenBuffer;
|
|
|
|
ConvAreaInfo = Console->ConsoleIme.ConvAreaRoot;
|
|
if (ConvAreaInfo != NULL) {
|
|
do {
|
|
ConvAreaInfo->ScreenBuffer->Attributes = ScreenInfo->Attributes;
|
|
ConvAreaInfo = ConvAreaInfo->ConvAreaNext;
|
|
} while (ConvAreaInfo != NULL);
|
|
}
|
|
|
|
if (Console->ConsoleIme.ConvAreaMode != NULL) {
|
|
Console->ConsoleIme.ConvAreaMode->ScreenBuffer->Attributes = ScreenInfo->Attributes;
|
|
}
|
|
|
|
if (Console->ConsoleIme.ConvAreaSystem != NULL) {
|
|
Console->ConsoleIme.ConvAreaSystem->ScreenBuffer->Attributes = ScreenInfo->Attributes;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
StreamWriteToScreenBufferIME(
|
|
IN PWCHAR String,
|
|
IN SHORT StringLength,
|
|
IN PSCREEN_INFORMATION ScreenInfo,
|
|
IN PCHAR StringA
|
|
)
|
|
{
|
|
SHORT RowIndex;
|
|
PROW Row;
|
|
PWCHAR Char;
|
|
COORD TargetPoint;
|
|
|
|
DBGOUTPUT(("StreamWriteToScreenBuffer\n"));
|
|
|
|
// Check code for must CONSOLE_TEXTMODE_BUFFER !!
|
|
ASSERT(!(ScreenInfo->Flags & CONSOLE_GRAPHICS_BUFFER));
|
|
|
|
ScreenInfo->BufferInfo.TextInfo.Flags |= TEXT_VALID_HINT;
|
|
TargetPoint = ScreenInfo->BufferInfo.TextInfo.CursorPosition;
|
|
RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow+TargetPoint.Y) % ScreenInfo->ScreenBufferSize.Y;
|
|
Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
|
|
DBGOUTPUT(("RowIndex = %lx, Row = %lx, TargetPoint = (%d,%d)\n",
|
|
RowIndex, Row, TargetPoint.X, TargetPoint.Y));
|
|
|
|
//
|
|
// copy chars
|
|
//
|
|
|
|
//#if defined(FE_SB)
|
|
BisectWrite(StringLength,TargetPoint,ScreenInfo);
|
|
if (TargetPoint.Y == ScreenInfo->ScreenBufferSize.Y-1 &&
|
|
TargetPoint.X+StringLength >= ScreenInfo->ScreenBufferSize.X &&
|
|
*(StringA+ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) & ATTR_LEADING_BYTE
|
|
) {
|
|
*(String+ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) = UNICODE_SPACE;
|
|
*(StringA+ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) = 0;
|
|
if (StringLength > ScreenInfo->ScreenBufferSize.X-TargetPoint.X-1) {
|
|
*(String+ScreenInfo->ScreenBufferSize.X-TargetPoint.X) = UNICODE_SPACE;
|
|
*(StringA+ScreenInfo->ScreenBufferSize.X-TargetPoint.X) = 0;
|
|
}
|
|
}
|
|
//#endif
|
|
RtlCopyMemory(&Row->CharRow.Chars[TargetPoint.X],String,StringLength*sizeof(WCHAR));
|
|
//#if defined(FE_SB)
|
|
RtlCopyMemory(&Row->CharRow.KAttrs[TargetPoint.X],StringA,StringLength*sizeof(CHAR));
|
|
//#endif
|
|
|
|
// recalculate first and last non-space char
|
|
|
|
Row->CharRow.OldLeft = Row->CharRow.Left;
|
|
if (TargetPoint.X < Row->CharRow.Left) {
|
|
//#if defined(FE_SB)
|
|
/*
|
|
* CharRow.Left is leftmost bound of chars in Chars array (array will be full width)
|
|
* i.e. type is COORD
|
|
*/
|
|
PWCHAR LastChar = &Row->CharRow.Chars[ScreenInfo->ScreenBufferSize.X-1];
|
|
//#else
|
|
// PWCHAR LastChar = &Row->CharRow.Chars[ScreenInfo->ScreenBufferSize.X];
|
|
//#endif
|
|
|
|
for (Char=&Row->CharRow.Chars[TargetPoint.X];Char < LastChar && *Char==(WCHAR)' ';Char++) {
|
|
/* do nothing*/;
|
|
}
|
|
Row->CharRow.Left = (SHORT)(Char-Row->CharRow.Chars);
|
|
}
|
|
|
|
Row->CharRow.OldRight = Row->CharRow.Right;
|
|
if ((TargetPoint.X+StringLength) >= Row->CharRow.Right) {
|
|
PWCHAR FirstChar = Row->CharRow.Chars;
|
|
|
|
for (Char=&Row->CharRow.Chars[TargetPoint.X+StringLength-1];*Char==(WCHAR)' ' && Char >= FirstChar;Char--) {
|
|
/* do nothing */;
|
|
}
|
|
Row->CharRow.Right = (SHORT)(Char+1-FirstChar);
|
|
}
|
|
|
|
//
|
|
// see if attr string is different. if so, allocate a new
|
|
// attr buffer and merge the two strings.
|
|
//
|
|
|
|
if (Row->AttrRow.Length != 1 ||
|
|
Row->AttrRow.Attrs->Attr != ScreenInfo->Attributes) {
|
|
PATTR_PAIR NewAttrs;
|
|
WORD NewAttrsLength;
|
|
ATTR_PAIR Attrs;
|
|
|
|
//#if defined(FE_SB) && defined(FE_IME)
|
|
if ((ScreenInfo->Attributes & (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_RVERTICAL)) ==
|
|
(COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_RVERTICAL)){
|
|
SHORT i;
|
|
for (i = 0; i < StringLength; i++ ) {
|
|
Attrs.Length = 1;
|
|
if (*(StringA + i) & ATTR_LEADING_BYTE) {
|
|
Attrs.Attr = ScreenInfo->Attributes & ~(COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_RVERTICAL);
|
|
} else {
|
|
Attrs.Attr = ScreenInfo->Attributes & ~COMMON_LVB_GRID_SINGLEFLAG;
|
|
}
|
|
|
|
if (!NT_SUCCESS(MergeAttrStrings(Row->AttrRow.Attrs,
|
|
Row->AttrRow.Length,
|
|
&Attrs,
|
|
1,
|
|
&NewAttrs,
|
|
&NewAttrsLength,
|
|
(SHORT)(TargetPoint.X+i),
|
|
(SHORT)(TargetPoint.X+i),
|
|
Row,
|
|
ScreenInfo
|
|
))) {
|
|
return;
|
|
}
|
|
if (Row->AttrRow.Length > 1) {
|
|
ConsoleHeapFree(Row->AttrRow.Attrs);
|
|
}
|
|
else {
|
|
ASSERT(Row->AttrRow.Attrs == &Row->AttrRow.AttrPair);
|
|
}
|
|
Row->AttrRow.Attrs = NewAttrs;
|
|
Row->AttrRow.Length = NewAttrsLength;
|
|
}
|
|
Row->CharRow.OldLeft = INVALID_OLD_LENGTH;
|
|
Row->CharRow.OldRight = INVALID_OLD_LENGTH;
|
|
}
|
|
else if ((ScreenInfo->Attributes & (COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_LVERTICAL)) ==
|
|
(COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_LVERTICAL)){
|
|
SHORT i;
|
|
for (i = 0; i < StringLength; i++ ) {
|
|
Attrs.Length = 1;
|
|
if (*(StringA + i) & ATTR_TRAILING_BYTE) {
|
|
Attrs.Attr = ScreenInfo->Attributes & ~(COMMON_LVB_GRID_SINGLEFLAG + COMMON_LVB_GRID_LVERTICAL);
|
|
} else {
|
|
Attrs.Attr = ScreenInfo->Attributes & ~COMMON_LVB_GRID_SINGLEFLAG;
|
|
}
|
|
|
|
if (!NT_SUCCESS(MergeAttrStrings(Row->AttrRow.Attrs,
|
|
Row->AttrRow.Length,
|
|
&Attrs,
|
|
1,
|
|
&NewAttrs,
|
|
&NewAttrsLength,
|
|
(SHORT)(TargetPoint.X+i),
|
|
(SHORT)(TargetPoint.X+i),
|
|
Row,
|
|
ScreenInfo
|
|
))) {
|
|
return;
|
|
}
|
|
if (Row->AttrRow.Length > 1) {
|
|
ConsoleHeapFree(Row->AttrRow.Attrs);
|
|
}
|
|
else {
|
|
ASSERT(Row->AttrRow.Attrs == &Row->AttrRow.AttrPair);
|
|
}
|
|
Row->AttrRow.Attrs = NewAttrs;
|
|
Row->AttrRow.Length = NewAttrsLength;
|
|
}
|
|
Row->CharRow.OldLeft = INVALID_OLD_LENGTH;
|
|
Row->CharRow.OldRight = INVALID_OLD_LENGTH;
|
|
}
|
|
else{
|
|
//#endif
|
|
Attrs.Length = StringLength;
|
|
Attrs.Attr = ScreenInfo->Attributes;
|
|
if (!NT_SUCCESS(MergeAttrStrings(Row->AttrRow.Attrs,
|
|
Row->AttrRow.Length,
|
|
&Attrs,
|
|
1,
|
|
&NewAttrs,
|
|
&NewAttrsLength,
|
|
TargetPoint.X,
|
|
(SHORT)(TargetPoint.X+StringLength-1),
|
|
Row,
|
|
ScreenInfo
|
|
))) {
|
|
return;
|
|
}
|
|
if (Row->AttrRow.Length > 1) {
|
|
ConsoleHeapFree(Row->AttrRow.Attrs);
|
|
}
|
|
else {
|
|
ASSERT(Row->AttrRow.Attrs == &Row->AttrRow.AttrPair);
|
|
}
|
|
Row->AttrRow.Attrs = NewAttrs;
|
|
Row->AttrRow.Length = NewAttrsLength;
|
|
Row->CharRow.OldLeft = INVALID_OLD_LENGTH;
|
|
Row->CharRow.OldRight = INVALID_OLD_LENGTH;
|
|
//#if defined(FE_SB) && defined(FE_IME)
|
|
}
|
|
//#endif
|
|
}
|
|
ResetTextFlags(ScreenInfo,
|
|
TargetPoint.X,
|
|
TargetPoint.Y,
|
|
TargetPoint.X + StringLength - 1,
|
|
TargetPoint.Y);
|
|
}
|
|
|
|
#endif // FE_IME
|