static BOOL WINAPI TuiSetCursorInfo(IN OUT PFRONTEND This, PCONSOLE_SCREEN_BUFFER Buff) { CONSOLE_CURSOR_INFO Info; DWORD BytesReturned; if (ActiveConsole->Console->ActiveBuffer != Buff) return TRUE; Info.dwSize = ConioEffectiveCursorSize(Console, 100); Info.bVisible = Buff->CursorInfo.bVisible; if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO, &Info, sizeof(Info), NULL, 0, &BytesReturned, NULL)) { DPRINT1( "Failed to set cursor info\n" ); return FALSE; } return TRUE; }
VOID GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, PRECT rcView, PRECT rcFramebuffer) { PCONSRV_CONSOLE Console = Buffer->Header.Console; // ASSERT(Console == GuiData->Console); ULONG TopLine, BottomLine, LeftChar, RightChar; ULONG Line, Char, Start; PCHAR_INFO From; PWCHAR To; WORD LastAttribute, Attribute; ULONG CursorX, CursorY, CursorHeight; HBRUSH CursorBrush, OldBrush; HFONT OldFont, NewFont; BOOLEAN IsUnderline; if (Buffer->Buffer == NULL) return; if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return; rcFramebuffer->left = Buffer->ViewOrigin.X * GuiData->CharWidth + rcView->left; rcFramebuffer->top = Buffer->ViewOrigin.Y * GuiData->CharHeight + rcView->top; rcFramebuffer->right = Buffer->ViewOrigin.X * GuiData->CharWidth + rcView->right; rcFramebuffer->bottom = Buffer->ViewOrigin.Y * GuiData->CharHeight + rcView->bottom; LeftChar = rcFramebuffer->left / GuiData->CharWidth; TopLine = rcFramebuffer->top / GuiData->CharHeight; RightChar = rcFramebuffer->right / GuiData->CharWidth; BottomLine = rcFramebuffer->bottom / GuiData->CharHeight; if (RightChar >= (ULONG)Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1; if (BottomLine >= (ULONG)Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1; LastAttribute = ConioCoordToPointer(Buffer, LeftChar, TopLine)->Attributes; SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); /* We use the underscore flag as a underline flag */ IsUnderline = !!(LastAttribute & COMMON_LVB_UNDERSCORE); /* Select the new font */ NewFont = GuiData->Font[IsUnderline ? FONT_BOLD : FONT_NORMAL]; OldFont = SelectObject(GuiData->hMemDC, NewFont); for (Line = TopLine; Line <= BottomLine; Line++) { WCHAR LineBuffer[80]; // Buffer containing a part or all the line to be displayed From = ConioCoordToPointer(Buffer, LeftChar, Line); // Get the first code of the line Start = LeftChar; To = LineBuffer; for (Char = LeftChar; Char <= RightChar; Char++) { /* * We flush the buffer if the new attribute is different * from the current one, or if the buffer is full. */ if (From->Attributes != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR))) { TextOutW(GuiData->hMemDC, Start * GuiData->CharWidth, Line * GuiData->CharHeight, LineBuffer, Char - Start); Start = Char; To = LineBuffer; Attribute = From->Attributes; if (Attribute != LastAttribute) { LastAttribute = Attribute; SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); /* Change underline state if needed */ if (!!(LastAttribute & COMMON_LVB_UNDERSCORE) != IsUnderline) { IsUnderline = !!(LastAttribute & COMMON_LVB_UNDERSCORE); /* Select the new font */ NewFont = GuiData->Font[IsUnderline ? FONT_BOLD : FONT_NORMAL]; /* OldFont = */ SelectObject(GuiData->hMemDC, NewFont); } } } *(To++) = (From++)->Char.UnicodeChar; } TextOutW(GuiData->hMemDC, Start * GuiData->CharWidth, Line * GuiData->CharHeight, LineBuffer, RightChar - Start + 1); } /* 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 (LeftChar <= CursorX && CursorX <= RightChar && 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); 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); }
VOID GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, HDC hDC, PRECT rc) { PCONSOLE Console = Buffer->Header.Console; // ASSERT(Console == GuiData->Console); ULONG TopLine, BottomLine, LeftChar, RightChar; ULONG Line, Char, Start; PCHAR_INFO From; PWCHAR To; WORD LastAttribute, Attribute; ULONG CursorX, CursorY, CursorHeight; HBRUSH CursorBrush, OldBrush; HFONT OldFont; if (Buffer->Buffer == NULL) return; TopLine = rc->top / GuiData->CharHeight + Buffer->ViewOrigin.Y; BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buffer->ViewOrigin.Y; LeftChar = rc->left / GuiData->CharWidth + Buffer->ViewOrigin.X; RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1 + Buffer->ViewOrigin.X; LastAttribute = ConioCoordToPointer(Buffer, LeftChar, TopLine)->Attributes; SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); if (BottomLine >= Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1; if (RightChar >= Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1; OldFont = SelectObject(hDC, GuiData->Font); for (Line = TopLine; Line <= BottomLine; Line++) { WCHAR LineBuffer[80]; // Buffer containing a part or all the line to be displayed From = ConioCoordToPointer(Buffer, LeftChar, Line); // Get the first code of the line Start = LeftChar; To = LineBuffer; for (Char = LeftChar; Char <= RightChar; Char++) { /* * We flush the buffer if the new attribute is different * from the current one, or if the buffer is full. */ if (From->Attributes != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR))) { TextOutW(hDC, (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth , (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, LineBuffer, Char - Start); Start = Char; To = LineBuffer; Attribute = From->Attributes; if (Attribute != LastAttribute) { SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute))); SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute))); LastAttribute = Attribute; } } *(To++) = (From++)->Char.UnicodeChar; } TextOutW(hDC, (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth , (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, LineBuffer, RightChar - Start + 1); } /* * Draw the caret */ if (Buffer->CursorInfo.bVisible && Buffer->CursorBlinkOn && !Buffer->ForceCursorOff) { CursorX = Buffer->CursorPosition.X; CursorY = Buffer->CursorPosition.Y; if (LeftChar <= CursorX && CursorX <= RightChar && TopLine <= CursorY && CursorY <= BottomLine) { CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight); Attribute = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y)->Attributes; if (Attribute != DEFAULT_SCREEN_ATTRIB) { CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Attribute)); } else { CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Buffer->ScreenDefaultAttrib)); } OldBrush = SelectObject(hDC, CursorBrush); PatBlt(hDC, (CursorX - Buffer->ViewOrigin.X) * GuiData->CharWidth, (CursorY - Buffer->ViewOrigin.Y) * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight), GuiData->CharWidth, CursorHeight, PATCOPY); SelectObject(hDC, OldBrush); DeleteObject(CursorBrush); } } SelectObject(hDC, OldFont); }