From 53061a4b695b377ac7ae10367121f55a158bb348 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 9 Feb 2020 00:28:20 +0100 Subject: [PATCH] [CONSRV] Additions for the GUI frontend. - Fix the text-copy code to handle fullwidth characters. - Move the caret painting code to its own function. --- .../user/winsrv/consrv/frontends/gui/text.c | 142 ++++++++++-------- 1 file changed, 83 insertions(+), 59 deletions(-) diff --git a/win32ss/user/winsrv/consrv/frontends/gui/text.c b/win32ss/user/winsrv/consrv/frontends/gui/text.c index 1751dfeb865..0397be7d82e 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/text.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/text.c @@ -120,8 +120,13 @@ CopyBlock(PTEXTMODE_SCREEN_BUFFER Buffer, /* * Sometimes, applications can put NULL chars into the screen-buffer * (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 */ @@ -212,8 +217,13 @@ CopyLines(PTEXTMODE_SCREEN_BUFFER Buffer, /* * Sometimes, applications can put NULL chars into the screen-buffer * (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); } +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 GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, @@ -363,8 +442,6 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, PCHAR_INFO From; PWCHAR To; WORD LastAttribute, Attribute; - ULONG CursorX, CursorY, CursorHeight; - HBRUSH CursorBrush, OldBrush; HFONT OldFont, NewFont; BOOLEAN IsUnderline; @@ -492,61 +569,8 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, /* Restore the old font */ SelectObject(GuiData->hMemDC, OldFont); - /* - * Draw the caret - */ - 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); - } - } + /* Draw the caret */ + GuiPaintCaret(Buffer, GuiData, TopLine, BottomLine, LeftColumn, RightColumn); LeaveCriticalSection(&Console->Lock); } -- 2.17.1