NTSTATUS
CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN OUT PCONSOLE Console,
+ IN PCONSOLE_SCREEN_BUFFER_VTBL Vtbl,
IN SIZE_T Size);
VOID
CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer);
Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer,
Console,
+ &TextVtbl,
sizeof(TEXTMODE_SCREEN_BUFFER));
if (!NT_SUCCESS(Status)) return Status;
NewBuffer->Header.Type = TEXTMODE_BUFFER;
- NewBuffer->Vtbl = &TextVtbl;
NewBuffer->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
TextModeInfo->ScreenBufferSize.X *
}
}
-static __inline BOOLEAN
-ConioGetIntersection(OUT PSMALL_RECT Intersection,
- IN PSMALL_RECT Rect1,
- IN PSMALL_RECT Rect2)
-{
- if ( ConioIsRectEmpty(Rect1) ||
- ConioIsRectEmpty(Rect2) ||
- (Rect1->Top > Rect2->Bottom) ||
- (Rect1->Left > Rect2->Right) ||
- (Rect1->Bottom < Rect2->Top) ||
- (Rect1->Right < Rect2->Left) )
- {
- /* The rectangles do not intersect */
- ConioInitRect(Intersection, 0, -1, 0, -1);
- return FALSE;
- }
-
- ConioInitRect(Intersection,
- max(Rect1->Top , Rect2->Top ),
- max(Rect1->Left , Rect2->Left ),
- min(Rect1->Bottom, Rect2->Bottom),
- min(Rect1->Right , Rect2->Right ));
-
- return TRUE;
-}
-
-static __inline BOOLEAN
-ConioGetUnion(OUT PSMALL_RECT Union,
- IN PSMALL_RECT Rect1,
- IN PSMALL_RECT Rect2)
-{
- if (ConioIsRectEmpty(Rect1))
- {
- if (ConioIsRectEmpty(Rect2))
- {
- ConioInitRect(Union, 0, -1, 0, -1);
- return FALSE;
- }
- else
- {
- *Union = *Rect2;
- }
- }
- else if (ConioIsRectEmpty(Rect2))
- {
- *Union = *Rect1;
- }
- else
- {
- ConioInitRect(Union,
- min(Rect1->Top , Rect2->Top ),
- min(Rect1->Left , Rect2->Left ),
- max(Rect1->Bottom, Rect2->Bottom),
- max(Rect1->Right , Rect2->Right ));
- }
-
- return TRUE;
-}
-
static VOID
ConioComputeUpdateRect(IN PTEXTMODE_SCREEN_BUFFER Buff,
IN OUT PSMALL_RECT UpdateRect,
}
}
-DWORD
-ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale)
-{
- DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
- /* If line input in progress, perhaps adjust for insert toggle */
- if (Console->LineBuffer && !Console->LineComplete && (Console->InsertMode ? !Console->LineInsertToggle : Console->LineInsertToggle))
- return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
- return Size;
-}
-
NTSTATUS
ConioResizeBuffer(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
OUT PCHAR_INFO CharInfo/*Buffer*/,
- IN PCOORD BufferSize,
- IN PCOORD BufferCoord,
IN OUT PSMALL_RECT ReadRegion)
{
+ SHORT X, Y;
+ SMALL_RECT ScreenBuffer;
PCHAR_INFO CurCharInfo;
- SHORT SizeX, SizeY;
SMALL_RECT CapturedReadRegion;
- SMALL_RECT ScreenRect;
- DWORD i;
PCHAR_INFO Ptr;
- LONG X, Y;
- UINT CodePage;
- if (Console == NULL || Buffer == NULL || CharInfo == NULL ||
- BufferSize == NULL || BufferCoord == NULL || ReadRegion == NULL)
+ if (Console == NULL || Buffer == NULL || CharInfo == NULL || ReadRegion == NULL)
{
return STATUS_INVALID_PARAMETER;
}
CapturedReadRegion = *ReadRegion;
- /* FIXME: Is this correct? */
- CodePage = Console->OutputCodePage;
-
- SizeX = min(BufferSize->X - BufferCoord->X, ConioRectWidth(&CapturedReadRegion));
- SizeY = min(BufferSize->Y - BufferCoord->Y, ConioRectHeight(&CapturedReadRegion));
- CapturedReadRegion.Right = CapturedReadRegion.Left + SizeX;
- CapturedReadRegion.Bottom = CapturedReadRegion.Top + SizeY;
-
- ConioInitRect(&ScreenRect, 0, 0, Buffer->ScreenBufferSize.Y, Buffer->ScreenBufferSize.X);
- if (!ConioGetIntersection(&CapturedReadRegion, &ScreenRect, &CapturedReadRegion))
+ /* Make sure ReadRegion is inside the screen buffer */
+ ConioInitRect(&ScreenBuffer, 0, 0,
+ Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
+ if (!ConioGetIntersection(&CapturedReadRegion, &ScreenBuffer, &CapturedReadRegion))
{
+ /*
+ * It is okay to have a ReadRegion completely outside
+ * the screen buffer. No data is read then.
+ */
return STATUS_SUCCESS;
}
- for (i = 0, Y = CapturedReadRegion.Top; Y < CapturedReadRegion.Bottom; ++i, ++Y)
- {
- CurCharInfo = CharInfo + (i * BufferSize->X);
+ CurCharInfo = CharInfo;
+ for (Y = CapturedReadRegion.Top; Y <= CapturedReadRegion.Bottom; ++Y)
+ {
Ptr = ConioCoordToPointer(Buffer, CapturedReadRegion.Left, Y);
- for (X = CapturedReadRegion.Left; X < CapturedReadRegion.Right; ++X)
+ for (X = CapturedReadRegion.Left; X <= CapturedReadRegion.Right; ++X)
{
if (Unicode)
{
else
{
// ConsoleUnicodeCharToAnsiChar(Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar);
- WideCharToMultiByte(CodePage, 0, &Ptr->Char.UnicodeChar, 1,
+ WideCharToMultiByte(Console->OutputCodePage, 0, &Ptr->Char.UnicodeChar, 1,
&CurCharInfo->Char.AsciiChar, 1, NULL, NULL);
}
CurCharInfo->Attributes = Ptr->Attributes;
}
}
- ReadRegion->Left = CapturedReadRegion.Left;
- ReadRegion->Top = CapturedReadRegion.Top ;
- ReadRegion->Right = CapturedReadRegion.Left + SizeX - 1;
- ReadRegion->Bottom = CapturedReadRegion.Top + SizeY - 1;
+ *ReadRegion = CapturedReadRegion;
return STATUS_SUCCESS;
}
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
IN PCHAR_INFO CharInfo/*Buffer*/,
- IN PCOORD BufferSize,
- IN PCOORD BufferCoord,
IN OUT PSMALL_RECT WriteRegion)
{
- SHORT i, X, Y, SizeX, SizeY;
+ SHORT X, Y;
SMALL_RECT ScreenBuffer;
PCHAR_INFO CurCharInfo;
SMALL_RECT CapturedWriteRegion;
PCHAR_INFO Ptr;
- if (Console == NULL || Buffer == NULL || CharInfo == NULL ||
- BufferSize == NULL || BufferCoord == NULL || WriteRegion == NULL)
+ if (Console == NULL || Buffer == NULL || CharInfo == NULL || WriteRegion == NULL)
{
return STATUS_INVALID_PARAMETER;
}
CapturedWriteRegion = *WriteRegion;
- SizeX = min(BufferSize->X - BufferCoord->X, ConioRectWidth(&CapturedWriteRegion));
- SizeY = min(BufferSize->Y - BufferCoord->Y, ConioRectHeight(&CapturedWriteRegion));
- CapturedWriteRegion.Right = CapturedWriteRegion.Left + SizeX - 1;
- CapturedWriteRegion.Bottom = CapturedWriteRegion.Top + SizeY - 1;
-
/* Make sure WriteRegion is inside the screen buffer */
- ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
+ ConioInitRect(&ScreenBuffer, 0, 0,
+ Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer, &CapturedWriteRegion))
{
/*
return STATUS_SUCCESS;
}
- for (i = 0, Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; i++, Y++)
- {
- CurCharInfo = CharInfo + (i + BufferCoord->Y) * BufferSize->X + BufferCoord->X;
+ CurCharInfo = CharInfo;
+ for (Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; ++Y)
+ {
Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y);
- for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; X++)
+ for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; ++X)
{
if (Unicode)
{
TermDrawRegion(Console, &CapturedWriteRegion);
- WriteRegion->Left = CapturedWriteRegion.Left;
- WriteRegion->Top = CapturedWriteRegion.Top ;
- WriteRegion->Right = CapturedWriteRegion.Left + SizeX - 1;
- WriteRegion->Bottom = CapturedWriteRegion.Top + SizeY - 1;
+ *WriteRegion = CapturedWriteRegion;
return STATUS_SUCCESS;
}
/* Validity checks */
ASSERT(Console == ScreenBuffer->Header.Console);
- ASSERT( (StringBuffer != NULL && NumCharsToWrite > 0) ||
- (StringBuffer == NULL && NumCharsToWrite == 0) );
+ ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCharsToWrite == 0));
- // if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION))
- if (Console->PauseFlags && Console->UnpauseEvent != NULL)
- {
- return STATUS_PENDING;
- }
+ /* Stop here if the console is paused */
+ if (Console->UnpauseEvent != NULL) return STATUS_PENDING;
if (Unicode)
{
OUT PVOID StringBuffer,
IN ULONG NumCodesToRead,
IN PCOORD ReadCoord,
- OUT PCOORD EndCoord,
- OUT PULONG CodesRead)
+ // OUT PCOORD EndCoord,
+ OUT PULONG NumCodesRead OPTIONAL)
{
SHORT Xpos, Ypos;
PVOID ReadBuffer;
ULONG CodeSize;
PCHAR_INFO Ptr;
- if (Console == NULL || Buffer == NULL ||
- ReadCoord == NULL || EndCoord == NULL || CodesRead == NULL)
+ if (Console == NULL || Buffer == NULL || ReadCoord == NULL /* || EndCoord == NULL */)
{
return STATUS_INVALID_PARAMETER;
}
/* Validity checks */
ASSERT(Console == Buffer->Header.Console);
- ASSERT( (StringBuffer != NULL && NumCodesToRead > 0) ||
- (StringBuffer == NULL && NumCodesToRead == 0) );
+ ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToRead == 0));
+
+ if (NumCodesRead) *NumCodesRead = 0;
switch (CodeType)
{
case CODE_ASCII:
- CodeSize = sizeof(CHAR);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
break;
case CODE_UNICODE:
- CodeSize = sizeof(WCHAR);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
break;
case CODE_ATTRIBUTE:
- CodeSize = sizeof(WORD);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
break;
default:
}
}
- // switch (CodeType)
- // {
- // case CODE_UNICODE:
- // *(PWCHAR)ReadBuffer = 0;
- // break;
-
- // case CODE_ASCII:
- // *(PCHAR)ReadBuffer = 0;
- // break;
+ // EndCoord->X = Xpos;
+ // EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y;
- // case CODE_ATTRIBUTE:
- // *(PWORD)ReadBuffer = 0;
- // break;
- // }
-
- EndCoord->X = Xpos;
- EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y;
-
- *CodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize;
+ if (NumCodesRead)
+ *NumCodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize;
// <= NumCodesToRead
return STATUS_SUCCESS;
IN CODE_TYPE CodeType,
IN PVOID StringBuffer,
IN ULONG NumCodesToWrite,
- IN PCOORD WriteCoord /*,
- OUT PCOORD EndCoord,
- OUT PULONG CodesWritten */)
+ IN PCOORD WriteCoord,
+ // OUT PCOORD EndCoord,
+ OUT PULONG NumCodesWritten OPTIONAL)
{
NTSTATUS Status = STATUS_SUCCESS;
PVOID WriteBuffer = NULL;
ULONG CodeSize;
PCHAR_INFO Ptr;
- if (Console == NULL || Buffer == NULL ||
- WriteCoord == NULL /* || EndCoord == NULL || CodesWritten == NULL */)
+ if (Console == NULL || Buffer == NULL || WriteCoord == NULL /* || EndCoord == NULL */)
{
return STATUS_INVALID_PARAMETER;
}
/* Validity checks */
ASSERT(Console == Buffer->Header.Console);
- ASSERT( (StringBuffer != NULL && NumCodesToWrite > 0) ||
- (StringBuffer == NULL && NumCodesToWrite == 0) );
+ ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToWrite == 0));
+
+ if (NumCodesWritten) *NumCodesWritten = 0;
switch (CodeType)
{
case CODE_ASCII:
- CodeSize = sizeof(CHAR);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
break;
case CODE_UNICODE:
- CodeSize = sizeof(WCHAR);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
break;
case CODE_ATTRIBUTE:
- CodeSize = sizeof(WORD);
+ CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
break;
default:
Cleanup:
if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
- // CodesWritten = Written;
+ if (NumCodesWritten) *NumCodesWritten = NumCodesToWrite; // Written;
return Status;
}
ConDrvFillConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
- IN PVOID Code,
+ IN CODE_ELEMENT Code,
IN ULONG NumCodesToWrite,
- IN PCOORD WriteCoord /*,
- OUT PULONG CodesWritten */)
+ IN PCOORD WriteCoord,
+ OUT PULONG NumCodesWritten OPTIONAL)
{
DWORD X, Y, Length; // , Written = 0;
PCHAR_INFO Ptr;
- if (Console == NULL || Buffer == NULL || Code == NULL ||
- WriteCoord == NULL /* || CodesWritten == NULL */)
+ if (Console == NULL || Buffer == NULL || WriteCoord == NULL)
{
return STATUS_INVALID_PARAMETER;
}
/* Validity check */
ASSERT(Console == Buffer->Header.Console);
-#if 0
- switch (CodeType)
- {
- case CODE_ASCII:
- /* On-place conversion from the ASCII char to the UNICODE char */
- ConsoleAnsiCharToUnicodeChar(Console, &Code->UnicodeChar, &Code->AsciiChar);
- /* Fall through */
- case CODE_UNICODE:
- Code = &Code->UnicodeChar;
- break;
+ if (NumCodesWritten) *NumCodesWritten = 0;
- case CODE_ATTRIBUTE:
- Code = &Code->Attribute;
- break;
- }
-#else
if (CodeType == CODE_ASCII)
{
- /* On-place conversion from the ASCII char to the UNICODE char */
- // FIXME: What if Code points to an invalid memory zone ??
- ConsoleAnsiCharToUnicodeChar(Console, (PWCHAR)Code, (PCHAR)Code);
+ /* Conversion from the ASCII char to the UNICODE char */
+ CODE_ELEMENT tmp;
+ ConsoleAnsiCharToUnicodeChar(Console, &tmp.UnicodeChar, &Code.AsciiChar);
+ Code = tmp;
}
-#endif
X = WriteCoord->X;
Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
{
case CODE_ASCII:
case CODE_UNICODE:
- Ptr->Char.UnicodeChar = *(PWCHAR)Code;
+ Ptr->Char.UnicodeChar = Code.UnicodeChar;
break;
case CODE_ATTRIBUTE:
- Ptr->Attributes = *(PWORD)Code;
+ Ptr->Attributes = Code.Attribute;
break;
}
// ++Ptr;
TermDrawRegion(Console, &UpdateRect);
}
- // CodesWritten = Written; // NumCodesToWrite;
+ if (NumCodesWritten) *NumCodesWritten = NumCodesToWrite; // Written;
return STATUS_SUCCESS;
}
CapturedDestinationOrigin = *DestinationOrigin;
/* Make sure the source rectangle is inside the screen buffer */
- ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
+ ConioInitRect(&ScreenBuffer, 0, 0,
+ Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, ScrollRectangle))
{
return STATUS_SUCCESS;
CapturedDestinationOrigin.X + ConioRectWidth(&SrcRegion ) - 1);
if (!Unicode)
- ConsoleAnsiCharToUnicodeChar(Console, &FillChar.Char.UnicodeChar, &FillChar.Char.AsciiChar);
+ {
+ WCHAR tmp;
+ ConsoleAnsiCharToUnicodeChar(Console, &tmp, &FillChar.Char.AsciiChar);
+ FillChar.Char.UnicodeChar = tmp;
+ }
ConioMoveRegion(Buffer, &SrcRegion, &DstRegion, &CapturedClipRectangle, FillChar);