- Use a Unicode screen-buffer for the console.
- Fix some pointers miscalculations in Read/Write console output routines, which lead to character display problems sometimes.
CORE-7277 #resolve #comment Should be fixed in revision r59212. Thanks for your report :)

svn path=/trunk/; revision=59212
This commit is contained in:
Hermès Bélusca-Maïto 2013-06-14 01:10:43 +00:00
parent 3ada1fe593
commit d224604eef
7 changed files with 323 additions and 266 deletions

View file

@ -99,7 +99,7 @@ ConioProcessInputEvent(PCONSOLE Console,
}
}
/* add event to the queue */
/* Add event to the queue */
ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES;

View file

@ -744,8 +744,6 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l
{
PCONSOLE Console = GuiData->Console;
PCONSOLE_SCREEN_BUFFER ActiveBuffer;
MSG Message;
WORD VirtualKeyCode = LOWORD(wParam);
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
@ -753,6 +751,8 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l
if (Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS)
{
WORD VirtualKeyCode = LOWORD(wParam);
if (msg != WM_KEYDOWN) goto Quit;
if (VirtualKeyCode == VK_RETURN)
@ -767,12 +767,13 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l
/* Cancel selection if ESC or Ctrl-C are pressed */
GuiConsoleUpdateSelection(Console, NULL);
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
goto Quit;
}
if ((Console->Selection.dwFlags & CONSOLE_MOUSE_SELECTION) == 0)
{
/* Selection mode with keyboard */
/* Keyboard selection mode */
BOOL Interpreted = FALSE;
BOOL MajPressed = (GetKeyState(VK_SHIFT) & 0x8000);
@ -865,20 +866,30 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l
/* Emit an error beep sound */
SendNotifyMessage(GuiData->hWindow, PM_CONSOLE_BEEP, 0, 0);
}
goto Quit;
}
else
{
/* Selection mode with mouse, clear the selection if needed */
/* Mouse selection mode */
if (!IsSystemKey(VirtualKeyCode))
{
/* Clear the selection and send the key into the input buffer */
GuiConsoleUpdateSelection(Console, NULL);
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
}
else
{
goto Quit;
}
}
}
if ((Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) == 0)
{
MSG Message;
Message.hwnd = GuiData->hWindow;
Message.message = msg;
Message.wParam = wParam;
@ -2247,7 +2258,7 @@ GuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
static VOID WINAPI
GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length)
UINT ScrolledLines, PWCHAR Buffer, UINT Length)
{
PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data;
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;

View file

@ -20,13 +20,6 @@
#include <debug.h>
/* GLOBALS ********************************************************************/
/* Copied from consrv/text.c */
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
/* FUNCTIONS ******************************************************************/
VOID
@ -45,7 +38,7 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
BOOL InlineCopyMode = (GetKeyState(VK_SHIFT) & 0x8000);
HANDLE hData;
PBYTE ptr;
PCHAR_INFO ptr;
LPWSTR data, dstPos;
ULONG selWidth, selHeight;
ULONG xPos, yPos, size;
@ -90,7 +83,7 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
/* Copy only the characters, leave attributes alone */
for (xPos = 0; xPos < selWidth; xPos++)
{
ConsoleAnsiCharToUnicodeChar(Console, &dstPos[xPos], (LPCSTR)&ptr[xPos * 2]);
dstPos[xPos] = ptr[xPos].Char.UnicodeChar;
}
dstPos += selWidth;
@ -192,9 +185,9 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
ULONG TopLine, BottomLine, LeftChar, RightChar;
ULONG Line, Char, Start;
PBYTE From;
PCHAR_INFO From;
PWCHAR To;
BYTE LastAttribute, Attribute;
WORD LastAttribute, Attribute;
ULONG CursorX, CursorY, CursorHeight;
HBRUSH CursorBrush, OldBrush;
HFONT OldFont;
@ -205,35 +198,40 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
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)[1];
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;
if (RightChar >= Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1;
OldFont = SelectObject(hDC, GuiData->Font);
for (Line = TopLine; Line <= BottomLine; Line++)
{
WCHAR LineBuffer[80];
From = ConioCoordToPointer(Buffer, LeftChar, 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;
To = LineBuffer;
for (Char = LeftChar; Char <= RightChar; Char++)
{
if (*(From + 1) != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR)))
/*
* 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,
(Start - Buffer->ViewOrigin.X) * GuiData->CharWidth ,
(Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight,
LineBuffer,
Char - Start);
Start = Char;
To = LineBuffer;
Attribute = *(From + 1);
To = LineBuffer;
Attribute = From->Attributes;
if (Attribute != LastAttribute)
{
SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute)));
@ -242,15 +240,12 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
}
}
MultiByteToWideChar(Console->OutputCodePage,
0, (PCHAR)From, 1, To, 1);
To++;
From += 2;
*(To++) = (From++)->Char.UnicodeChar;
}
TextOutW(hDC,
(Start - Buffer->ViewOrigin.X) * GuiData->CharWidth,
(Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight,
(Start - Buffer->ViewOrigin.X) * GuiData->CharWidth ,
(Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight,
LineBuffer,
RightChar - Start + 1);
}
@ -268,11 +263,11 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
TopLine <= CursorY && CursorY <= BottomLine)
{
CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight);
From = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y) + 1;
Attribute = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y)->Attributes;
if (*From != DEFAULT_SCREEN_ATTRIB)
if (Attribute != DEFAULT_SCREEN_ATTRIB)
{
CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, *From));
CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Attribute));
}
else
{

View file

@ -230,23 +230,25 @@ TuiSwapConsole(INT Next)
}
static VOID FASTCALL
TuiCopyRect(char *Dest, PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
TuiCopyRect(PCHAR Dest, PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
{
UINT SrcDelta, DestDelta;
LONG i;
PBYTE Src, SrcEnd;
PCHAR_INFO Src, SrcEnd;
Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
SrcDelta = Buff->ScreenBufferSize.X * 2;
SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
DestDelta = ConioRectWidth(Region) * 2;
SrcDelta = Buff->ScreenBufferSize.X * sizeof(CHAR_INFO);
SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * sizeof(CHAR_INFO);
DestDelta = ConioRectWidth(Region) * 2 /* 2 == sizeof(CHAR) + sizeof(BYTE) */;
for (i = Region->Top; i <= Region->Bottom; i++)
{
memcpy(Dest, Src, DestDelta);
ConsoleUnicodeCharToAnsiChar(Buff->Header.Console, (PCHAR)Dest, &Src->Char.UnicodeChar);
*(PBYTE)(Dest + 1) = (BYTE)Src->Attributes;
Src += SrcDelta;
if (SrcEnd <= Src)
{
Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * sizeof(CHAR_INFO);
}
Dest += DestDelta;
}
@ -501,7 +503,7 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
ConsoleDraw->CursorX = Buff->CursorPosition.X;
ConsoleDraw->CursorY = Buff->CursorPosition.Y;
TuiCopyRect((char*)(ConsoleDraw + 1), (PTEXTMODE_SCREEN_BUFFER)Buff, Region);
TuiCopyRect((PCHAR)(ConsoleDraw + 1), (PTEXTMODE_SCREEN_BUFFER)Buff, Region);
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
@ -516,17 +518,31 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
static VOID WINAPI
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length)
UINT ScrolledLines, PWCHAR Buffer, UINT Length)
{
DWORD BytesWritten;
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
PCHAR NewBuffer;
ULONG NewLength;
DWORD BytesWritten;
if (ActiveConsole->Console->ActiveBuffer != Buff) return;
if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
NewLength = WideCharToMultiByte(Console->OutputCodePage, 0,
Buffer, Length,
NULL, 0, NULL, NULL);
NewBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewLength * sizeof(CHAR));
if (!NewBuffer) return;
WideCharToMultiByte(Console->OutputCodePage, 0,
Buffer, Length,
NewBuffer, NewLength, NULL, NULL);
if (!WriteFile(ConsoleDeviceHandle, NewBuffer, NewLength * sizeof(CHAR), &BytesWritten, NULL))
{
DPRINT1("Error writing to BlueScreen\n");
}
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBuffer);
}
static BOOL WINAPI

View file

@ -126,12 +126,12 @@ typedef struct _TEXTMODE_BUFFER_INFO
typedef struct _TEXTMODE_SCREEN_BUFFER
{
CONSOLE_SCREEN_BUFFER; /* Screen buffer base class - MUST BE IN FIRST PLACE */
CONSOLE_SCREEN_BUFFER; /* Screen buffer base class - MUST BE IN FIRST PLACE */
BYTE *Buffer; /* CHAR_INFO */ /* Pointer to screen buffer */
PCHAR_INFO Buffer; /* Pointer to UNICODE screen buffer (Buffer->Char.UnicodeChar only is valid, not Char.AsciiChar) */
WORD ScreenDefaultAttrib; /* Default screen char attribute */
WORD PopupDefaultAttrib; /* Default popup char attribute */
WORD ScreenDefaultAttrib; /* Default screen char attribute */
WORD PopupDefaultAttrib; /* Default popup char attribute */
} TEXTMODE_SCREEN_BUFFER, *PTEXTMODE_SCREEN_BUFFER;
@ -189,7 +189,7 @@ typedef struct _FRONTEND_VTBL
SHORT CursorStartX,
SHORT CursorStartY,
UINT ScrolledLines,
CHAR *Buffer,
PWCHAR Buffer,
UINT Length);
BOOL (WINAPI *SetCursorInfo)(struct _CONSOLE* Console,
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
@ -286,7 +286,6 @@ typedef struct _CONSOLE
BOOLEAN QuickEdit;
BOOLEAN InsertMode;
UINT CodePage;
UINT OutputCodePage;
CONSOLE_SELECTION_INFO Selection; /* Contains information about the selection */
COORD dwSelectionCursor; /* Selection cursor position, most of the time different from Selection.dwSelectionAnchor */
@ -297,6 +296,7 @@ typedef struct _CONSOLE
BYTE PauseFlags;
HANDLE UnpauseEvent;
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
UINT OutputCodePage;
/**************************** Aliases and Histories ***************************/
struct _ALIAS_HEADER *Aliases;
@ -348,14 +348,20 @@ do { \
#define ConioRectWidth(Rect) \
(((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1)
PBYTE ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y);
#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
PCHAR_INFO ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y);
VOID FASTCALL ConioDrawConsole(PCONSOLE Console);
NTSTATUS ConioResizeBuffer(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
COORD Size);
NTSTATUS ConioWriteConsole(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER Buff,
CHAR *Buffer,
PWCHAR Buffer,
DWORD Length,
BOOL Attrib);
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console,

View file

@ -214,15 +214,11 @@ LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Inser
{
for (i = Pos; i < NewSize; i++)
{
CHAR AsciiChar;
WideCharToMultiByte(Console->OutputCodePage, 0,
&Console->LineBuffer[i], 1,
&AsciiChar, 1, NULL, NULL);
ConioWriteConsole(Console, ActiveBuffer, &AsciiChar, 1, TRUE);
ConioWriteConsole(Console, ActiveBuffer, &Console->LineBuffer[i], 1, TRUE);
}
for (; i < Console->LineSize; i++)
{
ConioWriteConsole(Console, ActiveBuffer, " ", 1, TRUE);
ConioWriteConsole(Console, ActiveBuffer, L" ", 1, TRUE);
}
Console->LinePos = i;
}
@ -413,7 +409,7 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
{
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
{
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), "\r", 1, TRUE);
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE);
}
}
@ -428,7 +424,7 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
{
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
{
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), "\n", 1, TRUE);
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE);
}
}
}

View file

@ -29,12 +29,6 @@
#define TAB_WIDTH 8
#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
/* PRIVATE FUNCTIONS **********************************************************/
@ -84,8 +78,9 @@ TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
NewBuffer->Vtbl = &TextVtbl;
NewBuffer->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
2 * TextModeInfo->ScreenBufferSize.X
* TextModeInfo->ScreenBufferSize.Y);
TextModeInfo->ScreenBufferSize.X *
TextModeInfo->ScreenBufferSize.Y *
sizeof(CHAR_INFO));
if (NewBuffer->Buffer == NULL)
{
CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
@ -137,23 +132,23 @@ TEXTMODE_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer)
}
PBYTE
PCHAR_INFO
ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
{
return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X)];
return &Buff->Buffer[((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X];
}
static VOID FASTCALL
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff)
{
PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y);
PCHAR_INFO Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y);
SHORT Pos;
for (Pos = 0; Pos < Buff->ScreenBufferSize.X; Pos++)
for (Pos = 0; Pos < Buff->ScreenBufferSize.X; Pos++, Ptr++)
{
/* Fill the cell */
*Ptr++ = ' ';
*Ptr++ = (BYTE)Buff->ScreenDefaultAttrib;
Ptr->Char.UnicodeChar = L' ';
Ptr->Attributes = Buff->ScreenDefaultAttrib;
}
}
@ -252,9 +247,9 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
SMALL_RECT* SrcRegion,
SMALL_RECT* DstRegion,
SMALL_RECT* ClipRegion,
WORD Fill)
CHAR_INFO FillChar)
{
int Width = ConioRectWidth(SrcRegion);
int Width = ConioRectWidth(SrcRegion);
int Height = ConioRectHeight(SrcRegion);
int SX, SY;
int DX, DY;
@ -273,8 +268,8 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
}
for (i = 0; i < Height; i++)
{
PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY);
PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY);
PCHAR_INFO SRow = ConioCoordToPointer(ScreenBuffer, 0, SY);
PCHAR_INFO DRow = ConioCoordToPointer(ScreenBuffer, 0, DY);
SX = SrcRegion->Left;
DX = DstRegion->Left;
@ -288,14 +283,14 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
}
for (j = 0; j < Width; j++)
{
WORD Cell = SRow[SX];
if (SX >= ClipRegion->Left && SX <= ClipRegion->Right
&& SY >= ClipRegion->Top && SY <= ClipRegion->Bottom)
CHAR_INFO Cell = SRow[SX];
if (SX >= ClipRegion->Left && SX <= ClipRegion->Right &&
SY >= ClipRegion->Top && SY <= ClipRegion->Bottom)
{
SRow[SX] = Fill;
SRow[SX] = FillChar;
}
if (DX >= ClipRegion->Left && DX <= ClipRegion->Right
&& DY >= ClipRegion->Top && DY <= ClipRegion->Bottom)
if (DX >= ClipRegion->Left && DX <= ClipRegion->Right &&
DY >= ClipRegion->Top && DY <= ClipRegion->Bottom)
{
DRow[DX] = Cell;
}
@ -322,11 +317,11 @@ ConioResizeBuffer(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
COORD Size)
{
BYTE * Buffer;
PCHAR_INFO Buffer;
DWORD Offset = 0;
BYTE * OldPtr;
PCHAR_INFO ptr;
USHORT CurrentY;
BYTE * OldBuffer;
PCHAR_INFO OldBuffer;
#ifdef HAVE_WMEMSET
USHORT value = MAKEWORD(' ', ScreenBuffer->ScreenDefaultAttrib);
#else
@ -355,7 +350,7 @@ ConioResizeBuffer(PCONSOLE Console,
return STATUS_NOT_SUPPORTED; // STATUS_SUCCESS
}
Buffer = ConsoleAllocHeap(0, Size.X * Size.Y * 2);
Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size.X * Size.Y * sizeof(CHAR_INFO));
if (!Buffer) return STATUS_NO_MEMORY;
DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->ScreenBufferSize.X, ScreenBuffer->ScreenBufferSize.Y, Size.X, Size.Y);
@ -363,28 +358,30 @@ ConioResizeBuffer(PCONSOLE Console,
for (CurrentY = 0; CurrentY < ScreenBuffer->ScreenBufferSize.Y && CurrentY < Size.Y; CurrentY++)
{
OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY);
ptr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY);
if (Size.X <= ScreenBuffer->ScreenBufferSize.X)
{
/* reduce size */
RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2);
Offset += (Size.X * 2);
/* Reduce size */
RtlCopyMemory(Buffer + Offset, ptr, Size.X * sizeof(CHAR_INFO));
Offset += Size.X;
}
else
{
/* enlarge size */
RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->ScreenBufferSize.X * 2);
Offset += (ScreenBuffer->ScreenBufferSize.X * 2);
/* Enlarge size */
RtlCopyMemory(Buffer + Offset, ptr, ScreenBuffer->ScreenBufferSize.X * sizeof(CHAR_INFO));
Offset += ScreenBuffer->ScreenBufferSize.X;
diff = Size.X - ScreenBuffer->ScreenBufferSize.X;
/* zero new part of it */
/* Zero new part of it */
#ifdef HAVE_WMEMSET
wmemset((PWCHAR)&Buffer[Offset], value, diff);
#else
for (i = 0; i < diff; i++)
{
Buffer[Offset++] = ' ';
Buffer[Offset++] = (BYTE)ScreenBuffer->ScreenDefaultAttrib;
ptr = Buffer + Offset;
ptr->Char.UnicodeChar = L' ';
ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib;
++Offset;
}
#endif
}
@ -398,8 +395,10 @@ ConioResizeBuffer(PCONSOLE Console,
#else
for (i = 0; i < diff; i++)
{
Buffer[Offset++] = ' ';
Buffer[Offset++] = (BYTE)ScreenBuffer->ScreenDefaultAttrib;
ptr = Buffer + Offset;
ptr->Char.UnicodeChar = L' ';
ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib;
++Offset;
}
#endif
}
@ -461,12 +460,12 @@ ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, UINT *Scroll
NTSTATUS
ConioWriteConsole(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER Buff,
CHAR *Buffer,
PWCHAR Buffer,
DWORD Length,
BOOL Attrib)
{
UINT i;
PBYTE Ptr;
PCHAR_INFO Ptr;
SMALL_RECT UpdateRect;
SHORT CursorStartX, CursorStartY;
UINT ScrolledLines;
@ -488,7 +487,7 @@ ConioWriteConsole(PCONSOLE Console,
if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
{
/* --- CR --- */
if (Buffer[i] == '\r')
if (Buffer[i] == L'\r')
{
Buff->CursorPosition.X = 0;
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
@ -496,14 +495,14 @@ ConioWriteConsole(PCONSOLE Console,
continue;
}
/* --- LF --- */
else if (Buffer[i] == '\n')
else if (Buffer[i] == L'\n')
{
Buff->CursorPosition.X = 0;
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
continue;
}
/* --- BS --- */
else if (Buffer[i] == '\b')
else if (Buffer[i] == L'\b')
{
/* Only handle BS if we're not on the first pos of the first line */
if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y)
@ -520,15 +519,15 @@ ConioWriteConsole(PCONSOLE Console,
Buff->CursorPosition.X--;
}
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
Ptr[0] = ' ';
Ptr[1] = (BYTE)Buff->ScreenDefaultAttrib;
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
Ptr->Char.UnicodeChar = L' ';
Ptr->Attributes = Buff->ScreenDefaultAttrib;
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
}
continue;
}
/* --- TAB --- */
else if (Buffer[i] == '\t')
else if (Buffer[i] == L'\t')
{
UINT EndX;
@ -538,8 +537,9 @@ ConioWriteConsole(PCONSOLE Console,
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
while (Buff->CursorPosition.X < EndX)
{
*Ptr++ = ' ';
*Ptr++ = (BYTE)Buff->ScreenDefaultAttrib;
Ptr->Char.UnicodeChar = L' ';
Ptr->Attributes = Buff->ScreenDefaultAttrib;
++Ptr;
Buff->CursorPosition.X++;
}
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1);
@ -558,7 +558,7 @@ ConioWriteConsole(PCONSOLE Console,
continue;
}
// /* --- BEL ---*/
// else if (Buffer[i] == '\a')
// else if (Buffer[i] == L'\a')
// {
// // FIXME: This MUST BE moved to the terminal emulator frontend!!
// DPRINT1("Bell\n");
@ -566,14 +566,13 @@ ConioWriteConsole(PCONSOLE Console,
// continue;
// }
}
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
Ptr[0] = Buffer[i];
if (Attrib)
{
Ptr[1] = (BYTE)Buff->ScreenDefaultAttrib;
}
Ptr->Char.UnicodeChar = Buffer[i];
if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib;
Buff->CursorPosition.X++;
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
{
@ -650,7 +649,7 @@ DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
PCONSOLE Console;
PTEXTMODE_SCREEN_BUFFER Buff;
PCHAR Buffer;
PVOID Buffer;
DWORD Written = 0;
ULONG Length;
@ -684,41 +683,44 @@ DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
{
if (WriteConsoleRequest->Unicode)
{
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)WriteConsoleRequest->Buffer,
Buffer = WriteConsoleRequest->Buffer;
}
else
{
Length = MultiByteToWideChar(Console->OutputCodePage, 0,
(PCHAR)WriteConsoleRequest->Buffer,
WriteConsoleRequest->NrCharactersToWrite,
NULL, 0, NULL, NULL);
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
NULL, 0);
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
if (Buffer)
{
WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)WriteConsoleRequest->Buffer,
MultiByteToWideChar(Console->OutputCodePage, 0,
(PCHAR)WriteConsoleRequest->Buffer,
WriteConsoleRequest->NrCharactersToWrite,
Buffer, Length, NULL, NULL);
(PWCHAR)Buffer, Length);
}
else
{
Status = STATUS_NO_MEMORY;
}
}
else
{
Buffer = (PCHAR)WriteConsoleRequest->Buffer;
}
if (Buffer)
{
if (NT_SUCCESS(Status))
{
Status = ConioWriteConsole(Console, Buff, Buffer,
WriteConsoleRequest->NrCharactersToWrite, TRUE);
Status = ConioWriteConsole(Console,
Buff,
Buffer,
WriteConsoleRequest->NrCharactersToWrite,
TRUE);
if (NT_SUCCESS(Status))
{
Written = WriteConsoleRequest->NrCharactersToWrite;
}
}
if (WriteConsoleRequest->Unicode)
if (!WriteConsoleRequest->Unicode)
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
}
@ -746,7 +748,7 @@ CSR_API(SrvReadConsoleOutput)
SMALL_RECT ReadRegion;
SMALL_RECT ScreenRect;
DWORD i;
PBYTE Ptr;
PCHAR_INFO Ptr;
LONG X, Y;
UINT CodePage;
@ -792,16 +794,16 @@ CSR_API(SrvReadConsoleOutput)
{
if (ReadOutputRequest->Unicode)
{
// ConsoleAnsiCharToUnicodeChar(ProcessData->Console, (PCHAR)Ptr++, &CurCharInfo->Char.UnicodeChar);
MultiByteToWideChar(CodePage, 0,
(PCHAR)Ptr++, 1,
&CurCharInfo->Char.UnicodeChar, 1);
CurCharInfo->Char.UnicodeChar = Ptr->Char.UnicodeChar;
}
else
{
CurCharInfo->Char.AsciiChar = *Ptr++;
// ConsoleUnicodeCharToAnsiChar(ProcessData->Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar);
WideCharToMultiByte(CodePage, 0, &Ptr->Char.UnicodeChar, 1,
&CurCharInfo->Char.AsciiChar, 1, NULL, NULL);
}
CurCharInfo->Attributes = *Ptr++;
CurCharInfo->Attributes = Ptr->Attributes;
++Ptr;
++CurCharInfo;
}
}
@ -824,13 +826,13 @@ CSR_API(SrvWriteConsoleOutput)
PCONSOLE Console;
PTEXTMODE_SCREEN_BUFFER Buff;
SMALL_RECT ScreenBuffer;
CHAR_INFO* CurCharInfo;
PCHAR_INFO CurCharInfo;
SMALL_RECT WriteRegion;
CHAR_INFO* CharInfo;
PCHAR_INFO CharInfo;
COORD BufferCoord;
COORD BufferSize;
NTSTATUS Status;
PBYTE Ptr;
PCHAR_INFO Ptr;
DPRINT("SrvWriteConsoleOutput\n");
@ -847,10 +849,10 @@ CSR_API(SrvWriteConsoleOutput)
}
Status = ConSrvGetTextModeBuffer(ProcessData,
WriteOutputRequest->OutputHandle,
&Buff,
GENERIC_WRITE,
TRUE);
WriteOutputRequest->OutputHandle,
&Buff,
GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
@ -876,21 +878,21 @@ CSR_API(SrvWriteConsoleOutput)
for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++)
{
CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y);
for (X = WriteRegion.Left; X <= WriteRegion.Right; X++)
{
CHAR AsciiChar;
if (WriteOutputRequest->Unicode)
{
ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar);
Ptr->Char.UnicodeChar = CurCharInfo->Char.UnicodeChar;
}
else
{
AsciiChar = CurCharInfo->Char.AsciiChar;
ConsoleAnsiCharToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char.AsciiChar);
}
*Ptr++ = AsciiChar;
*Ptr++ = (BYTE)CurCharInfo->Attributes;
CurCharInfo++;
Ptr->Attributes = CurCharInfo->Attributes;
++Ptr;
++CurCharInfo;
}
}
@ -942,7 +944,7 @@ CSR_API(SrvReadConsoleOutputString)
PVOID ReadBuffer;
DWORD i;
ULONG CodeSize;
BYTE Code;
PCHAR_INFO Ptr;
DPRINT("SrvReadConsoleOutputString\n");
@ -973,7 +975,11 @@ CSR_API(SrvReadConsoleOutputString)
return STATUS_INVALID_PARAMETER;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), ReadOutputCodeRequest->OutputHandle, &Buff, GENERIC_READ, TRUE);
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
ReadOutputCodeRequest->OutputHandle,
&Buff,
GENERIC_READ,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
@ -995,25 +1001,28 @@ CSR_API(SrvReadConsoleOutputString)
* TODO: Do NOT loop up to NumCodesToRead, but stop before
* if we are going to overflow...
*/
for (i = 0; i < min(ReadOutputCodeRequest->NumCodesToRead, Buff->ScreenBufferSize.X * Buff->ScreenBufferSize.Y * 2); ++i)
// Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work
for (i = 0; i < min(ReadOutputCodeRequest->NumCodesToRead, Buff->ScreenBufferSize.X * Buff->ScreenBufferSize.Y); ++i)
{
Code = Buff->Buffer[2 * (Xpos + Ypos * Buff->ScreenBufferSize.X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
// Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work either
Ptr = &Buff->Buffer[Xpos + Ypos * Buff->ScreenBufferSize.X];
switch (CodeType)
{
case CODE_UNICODE:
ConsoleAnsiCharToUnicodeChar(Console, (PWCHAR)ReadBuffer, (PCHAR)&Code);
case CODE_ASCII:
ConsoleUnicodeCharToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar);
break;
case CODE_ASCII:
*(PCHAR)ReadBuffer = (CHAR)Code;
case CODE_UNICODE:
*(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar;
break;
case CODE_ATTRIBUTE:
*(PWORD)ReadBuffer = (WORD)Code;
*(PWORD)ReadBuffer = Ptr->Attributes;
break;
}
ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
// ++Ptr;
Xpos++;
@ -1062,11 +1071,12 @@ CSR_API(SrvWriteConsoleOutputString)
PCONSOLE Console;
PTEXTMODE_SCREEN_BUFFER Buff;
USHORT CodeType;
PBYTE Buffer; // PUCHAR
PCHAR String, tmpString = NULL;
PVOID ReadBuffer = NULL;
PWCHAR tmpString = NULL;
DWORD X, Y, Length; // , Written = 0;
ULONG CodeSize;
SMALL_RECT UpdateRect;
PCHAR_INFO Ptr;
DPRINT("SrvWriteConsoleOutputString\n");
@ -1098,85 +1108,90 @@ CSR_API(SrvWriteConsoleOutputString)
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
WriteOutputCodeRequest->OutputHandle,
&Buff,
GENERIC_WRITE,
TRUE);
WriteOutputCodeRequest->OutputHandle,
&Buff,
GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
switch (CodeType)
if (CodeType == CODE_ASCII)
{
case CODE_UNICODE:
/* Convert the ASCII string into Unicode before writing it to the console */
Length = MultiByteToWideChar(Console->OutputCodePage, 0,
WriteOutputCodeRequest->pCode.AsciiChar,
WriteOutputCodeRequest->Length,
NULL, 0);
tmpString = ReadBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
if (ReadBuffer)
{
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)WriteOutputCodeRequest->pCode.UnicodeChar,
WriteOutputCodeRequest->Length,
NULL, 0, NULL, NULL);
tmpString = String = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
if (String)
{
WideCharToMultiByte(Console->OutputCodePage, 0,
(PWCHAR)WriteOutputCodeRequest->pCode.UnicodeChar,
WriteOutputCodeRequest->Length,
String, Length, NULL, NULL);
}
else
{
Status = STATUS_NO_MEMORY;
}
break;
MultiByteToWideChar(Console->OutputCodePage, 0,
WriteOutputCodeRequest->pCode.AsciiChar,
WriteOutputCodeRequest->Length,
(PWCHAR)ReadBuffer, Length);
}
case CODE_ASCII:
String = (PCHAR)WriteOutputCodeRequest->pCode.AsciiChar;
break;
case CODE_ATTRIBUTE:
default:
// *(ReadBuffer++) = Code;
String = (PCHAR)WriteOutputCodeRequest->pCode.Attribute;
break;
else
{
Status = STATUS_NO_MEMORY;
}
}
else
{
/* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */
ReadBuffer = WriteOutputCodeRequest->pCode.pCode;
}
if (String && NT_SUCCESS(Status))
{
X = WriteOutputCodeRequest->Coord.X;
Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
Length = WriteOutputCodeRequest->Length;
Buffer = &Buff->Buffer[2 * (Y * Buff->ScreenBufferSize.X + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
if (ReadBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup;
while (Length--)
X = WriteOutputCodeRequest->Coord.X;
Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
Length = WriteOutputCodeRequest->Length;
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work
// Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work
while (Length--)
{
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either
Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X];
switch (CodeType)
{
*Buffer = *String++;
// ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
String = (PCHAR)((ULONG_PTR)String + CodeSize);
// Written++;
Buffer += 2;
if (++X == Buff->ScreenBufferSize.X)
case CODE_ASCII:
case CODE_UNICODE:
Ptr->Char.UnicodeChar = *(PWCHAR)ReadBuffer;
break;
case CODE_ATTRIBUTE:
Ptr->Attributes = *(PWORD)ReadBuffer;
break;
}
ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
// ++Ptr;
// Written++;
if (++X == Buff->ScreenBufferSize.X)
{
X = 0;
if (++Y == Buff->ScreenBufferSize.Y)
{
if (++Y == Buff->ScreenBufferSize.Y)
{
Y = 0;
Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0);
}
X = 0;
Y = 0;
}
}
if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
{
ConioComputeUpdateRect(Buff, &UpdateRect, &WriteOutputCodeRequest->Coord,
WriteOutputCodeRequest->Length);
ConioDrawRegion(Console, &UpdateRect);
}
// WriteOutputCodeRequest->EndCoord.X = X;
// WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y;
}
if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
{
ConioComputeUpdateRect(Buff, &UpdateRect, &WriteOutputCodeRequest->Coord,
WriteOutputCodeRequest->Length);
ConioDrawRegion(Console, &UpdateRect);
}
// WriteOutputCodeRequest->EndCoord.X = X;
// WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y;
Cleanup:
if (tmpString)
RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
@ -1194,56 +1209,77 @@ CSR_API(SrvFillConsoleOutput)
PTEXTMODE_SCREEN_BUFFER Buff;
DWORD X, Y, Length; // , Written = 0;
USHORT CodeType;
BYTE Code;
PBYTE Buffer;
PVOID Code = NULL;
PCHAR_INFO Ptr;
SMALL_RECT UpdateRect;
DPRINT("SrvFillConsoleOutput\n");
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), FillOutputRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE);
CodeType = FillOutputRequest->CodeType;
if ( (CodeType != CODE_ASCII ) &&
(CodeType != CODE_UNICODE ) &&
(CodeType != CODE_ATTRIBUTE) )
{
return STATUS_INVALID_PARAMETER;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
FillOutputRequest->OutputHandle,
&Buff,
GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
Console = Buff->Header.Console;
CodeType = FillOutputRequest->CodeType;
switch (CodeType)
{
case CODE_ASCII:
/* On-place conversion from the ASCII char to the UNICODE char */
ConsoleAnsiCharToUnicodeChar(Console, &FillOutputRequest->Code.UnicodeChar, &FillOutputRequest->Code.AsciiChar);
/* Fall through */
case CODE_UNICODE:
Code = &FillOutputRequest->Code.UnicodeChar;
break;
case CODE_ATTRIBUTE:
Code = &FillOutputRequest->Code.Attribute;
break;
}
X = FillOutputRequest->Coord.X;
Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
Length = FillOutputRequest->Length;
Buffer = &Buff->Buffer[2 * (Y * Buff->ScreenBufferSize.X + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
switch (CodeType)
{
case CODE_ASCII:
Code = (BYTE)FillOutputRequest->Code.AsciiChar;
break;
case CODE_UNICODE:
ConsoleUnicodeCharToAnsiChar(Console, (PCHAR)&Code, &FillOutputRequest->Code.UnicodeChar);
break;
case CODE_ATTRIBUTE:
Code = (BYTE)FillOutputRequest->Code.Attribute;
break;
default:
ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_INVALID_PARAMETER;
}
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work
// Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work
while (Length--)
{
*Buffer = Code;
Buffer += 2;
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either
Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X];
switch (CodeType)
{
case CODE_ASCII:
case CODE_UNICODE:
Ptr->Char.UnicodeChar = *(PWCHAR)Code;
break;
case CODE_ATTRIBUTE:
Ptr->Attributes = *(PWORD)Code;
break;
}
// ++Ptr;
// Written++;
if (++X == Buff->ScreenBufferSize.X)
{
X = 0;
if (++Y == Buff->ScreenBufferSize.Y)
{
Y = 0;
Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0);
}
X = 0;
}
}
@ -1341,15 +1377,14 @@ CSR_API(SrvScrollConsoleScreenBuffer)
HANDLE OutputHandle;
BOOLEAN UseClipRectangle;
COORD DestinationOrigin;
CHAR_INFO Fill;
CHAR FillChar;
CHAR_INFO FillChar;
DPRINT("SrvScrollConsoleScreenBuffer\n");
OutputHandle = ScrollScreenBufferRequest->OutputHandle;
UseClipRectangle = ScrollScreenBufferRequest->UseClipRectangle;
DestinationOrigin = ScrollScreenBufferRequest->DestinationOrigin;
Fill = ScrollScreenBufferRequest->Fill;
FillChar = ScrollScreenBufferRequest->Fill;
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), OutputHandle, &Buff, GENERIC_WRITE, TRUE);
if (!NT_SUCCESS(Status)) return Status;
@ -1396,12 +1431,10 @@ CSR_API(SrvScrollConsoleScreenBuffer)
DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1,
DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1);
if (ScrollScreenBufferRequest->Unicode)
ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar);
else
FillChar = Fill.Char.AsciiChar;
if (!ScrollScreenBufferRequest->Unicode)
ConsoleAnsiCharToUnicodeChar(Console, &FillChar.Char.UnicodeChar, &FillChar.Char.AsciiChar);
ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, Fill.Attributes << 8 | (BYTE)FillChar);
ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, FillChar);
if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
{