[CONSRV] Additions for the GUI frontend.

- Fix the text-copy code to handle fullwidth characters.
- Move the caret painting code to its own function.
This commit is contained in:
Hermès Bélusca-Maïto 2020-02-09 00:28:20 +01:00
parent 0d500b642b
commit 53061a4b69
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -120,8 +120,13 @@ CopyBlock(PTEXTMODE_SCREEN_BUFFER Buffer,
/* /*
* Sometimes, applications can put NULL chars into the screen-buffer * Sometimes, applications can put NULL chars into the screen-buffer
* (this behaviour is allowed). Detect this and replace by a space. * (this behaviour is allowed). Detect this and replace by a space.
* For full-width characters: copy only the character specified
* in the leading-byte cell, skipping the trailing-byte cell.
*/ */
*dstPos++ = (ptr[xPos].Char.UnicodeChar ? ptr[xPos].Char.UnicodeChar : L' '); if (!(ptr[xPos].Attributes & COMMON_LVB_TRAILING_BYTE))
{
*dstPos++ = (ptr[xPos].Char.UnicodeChar ? ptr[xPos].Char.UnicodeChar : L' ');
}
} }
/* Add newline characters if we are not in inline-text copy mode */ /* Add newline characters if we are not in inline-text copy mode */
@ -212,8 +217,13 @@ CopyLines(PTEXTMODE_SCREEN_BUFFER Buffer,
/* /*
* Sometimes, applications can put NULL chars into the screen-buffer * Sometimes, applications can put NULL chars into the screen-buffer
* (this behaviour is allowed). Detect this and replace by a space. * (this behaviour is allowed). Detect this and replace by a space.
* For full-width characters: copy only the character specified
* in the leading-byte cell, skipping the trailing-byte cell.
*/ */
*dstPos++ = (ptr[xPos].Char.UnicodeChar ? ptr[xPos].Char.UnicodeChar : L' '); if (!(ptr[xPos].Attributes & COMMON_LVB_TRAILING_BYTE))
{
*dstPos++ = (ptr[xPos].Char.UnicodeChar ? ptr[xPos].Char.UnicodeChar : L' ');
}
} }
} }
@ -351,6 +361,75 @@ GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
GlobalUnlock(hData); GlobalUnlock(hData);
} }
static VOID
GuiPaintCaret(
PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData,
ULONG TopLine,
ULONG BottomLine,
ULONG LeftColumn,
ULONG RightColumn)
{
PCONSRV_CONSOLE Console = Buffer->Header.Console;
ULONG CursorX, CursorY, CursorHeight;
HBRUSH CursorBrush, OldBrush;
WORD Attribute;
if (Buffer->CursorInfo.bVisible &&
Buffer->CursorBlinkOn &&
!Buffer->ForceCursorOff)
{
CursorX = Buffer->CursorPosition.X;
CursorY = Buffer->CursorPosition.Y;
if (LeftColumn <= CursorX && CursorX <= RightColumn &&
TopLine <= CursorY && CursorY <= BottomLine)
{
CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight);
Attribute = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y)->Attributes;
if (Attribute == DEFAULT_SCREEN_ATTRIB)
Attribute = Buffer->ScreenDefaultAttrib;
CursorBrush = CreateSolidBrush(PaletteRGBFromAttrib(Console, TextAttribFromAttrib(Attribute)));
OldBrush = SelectObject(GuiData->hMemDC, CursorBrush);
if (Attribute & COMMON_LVB_LEADING_BYTE)
{
/* The caret is on the leading byte */
PatBlt(GuiData->hMemDC,
CursorX * GuiData->CharWidth,
CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
GuiData->CharWidth * 2,
CursorHeight,
PATCOPY);
}
else if (Attribute & COMMON_LVB_TRAILING_BYTE)
{
/* The caret is on the trailing byte */
PatBlt(GuiData->hMemDC,
(CursorX - 1) * GuiData->CharWidth,
CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
GuiData->CharWidth * 2,
CursorHeight,
PATCOPY);
}
else
{
PatBlt(GuiData->hMemDC,
CursorX * GuiData->CharWidth,
CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
GuiData->CharWidth,
CursorHeight,
PATCOPY);
}
SelectObject(GuiData->hMemDC, OldBrush);
DeleteObject(CursorBrush);
}
}
}
VOID VOID
GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData, PGUI_CONSOLE_DATA GuiData,
@ -363,8 +442,6 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PCHAR_INFO From; PCHAR_INFO From;
PWCHAR To; PWCHAR To;
WORD LastAttribute, Attribute; WORD LastAttribute, Attribute;
ULONG CursorX, CursorY, CursorHeight;
HBRUSH CursorBrush, OldBrush;
HFONT OldFont, NewFont; HFONT OldFont, NewFont;
BOOLEAN IsUnderline; BOOLEAN IsUnderline;
@ -492,61 +569,8 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
/* Restore the old font */ /* Restore the old font */
SelectObject(GuiData->hMemDC, OldFont); SelectObject(GuiData->hMemDC, OldFont);
/* /* Draw the caret */
* Draw the caret GuiPaintCaret(Buffer, GuiData, TopLine, BottomLine, LeftColumn, RightColumn);
*/
if (Buffer->CursorInfo.bVisible &&
Buffer->CursorBlinkOn &&
!Buffer->ForceCursorOff)
{
CursorX = Buffer->CursorPosition.X;
CursorY = Buffer->CursorPosition.Y;
if (LeftColumn <= CursorX && CursorX <= RightColumn &&
TopLine <= CursorY && CursorY <= BottomLine)
{
CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight);
Attribute = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y)->Attributes;
if (Attribute == DEFAULT_SCREEN_ATTRIB)
Attribute = Buffer->ScreenDefaultAttrib;
CursorBrush = CreateSolidBrush(PaletteRGBFromAttrib(Console, TextAttribFromAttrib(Attribute)));
OldBrush = SelectObject(GuiData->hMemDC, CursorBrush);
if (Attribute & COMMON_LVB_LEADING_BYTE)
{
/* The caret is on the leading byte */
PatBlt(GuiData->hMemDC,
CursorX * GuiData->CharWidth,
CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
GuiData->CharWidth * 2,
CursorHeight,
PATCOPY);
}
else if (Attribute & COMMON_LVB_TRAILING_BYTE)
{
/* The caret is on the trailing byte */
PatBlt(GuiData->hMemDC,
(CursorX - 1) * GuiData->CharWidth,
CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
GuiData->CharWidth * 2,
CursorHeight,
PATCOPY);
}
else
{
PatBlt(GuiData->hMemDC,
CursorX * GuiData->CharWidth,
CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
GuiData->CharWidth,
CursorHeight,
PATCOPY);
}
SelectObject(GuiData->hMemDC, OldBrush);
DeleteObject(CursorBrush);
}
}
LeaveCriticalSection(&Console->Lock); LeaveCriticalSection(&Console->Lock);
} }