mirror of
https://github.com/reactos/reactos.git
synced 2024-07-13 08:05:12 +00:00
[CONSRV]
- 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:
parent
3ada1fe593
commit
d224604eef
|
@ -99,7 +99,7 @@ ConioProcessInputEvent(PCONSOLE Console,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add event to the queue */
|
/* Add event to the queue */
|
||||||
ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
|
ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
|
||||||
if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES;
|
if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
|
|
@ -744,8 +744,6 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l
|
||||||
{
|
{
|
||||||
PCONSOLE Console = GuiData->Console;
|
PCONSOLE Console = GuiData->Console;
|
||||||
PCONSOLE_SCREEN_BUFFER ActiveBuffer;
|
PCONSOLE_SCREEN_BUFFER ActiveBuffer;
|
||||||
MSG Message;
|
|
||||||
WORD VirtualKeyCode = LOWORD(wParam);
|
|
||||||
|
|
||||||
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
|
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)
|
if (Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
|
WORD VirtualKeyCode = LOWORD(wParam);
|
||||||
|
|
||||||
if (msg != WM_KEYDOWN) goto Quit;
|
if (msg != WM_KEYDOWN) goto Quit;
|
||||||
|
|
||||||
if (VirtualKeyCode == VK_RETURN)
|
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 */
|
/* Cancel selection if ESC or Ctrl-C are pressed */
|
||||||
GuiConsoleUpdateSelection(Console, NULL);
|
GuiConsoleUpdateSelection(Console, NULL);
|
||||||
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
|
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
|
||||||
|
|
||||||
goto Quit;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Console->Selection.dwFlags & CONSOLE_MOUSE_SELECTION) == 0)
|
if ((Console->Selection.dwFlags & CONSOLE_MOUSE_SELECTION) == 0)
|
||||||
{
|
{
|
||||||
/* Selection mode with keyboard */
|
/* Keyboard selection mode */
|
||||||
BOOL Interpreted = FALSE;
|
BOOL Interpreted = FALSE;
|
||||||
BOOL MajPressed = (GetKeyState(VK_SHIFT) & 0x8000);
|
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 */
|
/* Emit an error beep sound */
|
||||||
SendNotifyMessage(GuiData->hWindow, PM_CONSOLE_BEEP, 0, 0);
|
SendNotifyMessage(GuiData->hWindow, PM_CONSOLE_BEEP, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goto Quit;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Selection mode with mouse, clear the selection if needed */
|
/* Mouse selection mode */
|
||||||
|
|
||||||
if (!IsSystemKey(VirtualKeyCode))
|
if (!IsSystemKey(VirtualKeyCode))
|
||||||
{
|
{
|
||||||
|
/* Clear the selection and send the key into the input buffer */
|
||||||
GuiConsoleUpdateSelection(Console, NULL);
|
GuiConsoleUpdateSelection(Console, NULL);
|
||||||
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
|
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) == 0)
|
if ((Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) == 0)
|
||||||
{
|
{
|
||||||
|
MSG Message;
|
||||||
|
|
||||||
Message.hwnd = GuiData->hWindow;
|
Message.hwnd = GuiData->hWindow;
|
||||||
Message.message = msg;
|
Message.message = msg;
|
||||||
Message.wParam = wParam;
|
Message.wParam = wParam;
|
||||||
|
@ -2247,7 +2258,7 @@ GuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY,
|
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;
|
PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data;
|
||||||
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
||||||
|
|
|
@ -20,13 +20,6 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
|
||||||
|
|
||||||
/* Copied from consrv/text.c */
|
|
||||||
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
|
|
||||||
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
|
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -45,7 +38,7 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
|
||||||
BOOL InlineCopyMode = (GetKeyState(VK_SHIFT) & 0x8000);
|
BOOL InlineCopyMode = (GetKeyState(VK_SHIFT) & 0x8000);
|
||||||
|
|
||||||
HANDLE hData;
|
HANDLE hData;
|
||||||
PBYTE ptr;
|
PCHAR_INFO ptr;
|
||||||
LPWSTR data, dstPos;
|
LPWSTR data, dstPos;
|
||||||
ULONG selWidth, selHeight;
|
ULONG selWidth, selHeight;
|
||||||
ULONG xPos, yPos, size;
|
ULONG xPos, yPos, size;
|
||||||
|
@ -90,7 +83,7 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
|
||||||
/* Copy only the characters, leave attributes alone */
|
/* Copy only the characters, leave attributes alone */
|
||||||
for (xPos = 0; xPos < selWidth; xPos++)
|
for (xPos = 0; xPos < selWidth; xPos++)
|
||||||
{
|
{
|
||||||
ConsoleAnsiCharToUnicodeChar(Console, &dstPos[xPos], (LPCSTR)&ptr[xPos * 2]);
|
dstPos[xPos] = ptr[xPos].Char.UnicodeChar;
|
||||||
}
|
}
|
||||||
dstPos += selWidth;
|
dstPos += selWidth;
|
||||||
|
|
||||||
|
@ -192,9 +185,9 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||||
|
|
||||||
ULONG TopLine, BottomLine, LeftChar, RightChar;
|
ULONG TopLine, BottomLine, LeftChar, RightChar;
|
||||||
ULONG Line, Char, Start;
|
ULONG Line, Char, Start;
|
||||||
PBYTE From;
|
PCHAR_INFO From;
|
||||||
PWCHAR To;
|
PWCHAR To;
|
||||||
BYTE LastAttribute, Attribute;
|
WORD LastAttribute, Attribute;
|
||||||
ULONG CursorX, CursorY, CursorHeight;
|
ULONG CursorX, CursorY, CursorHeight;
|
||||||
HBRUSH CursorBrush, OldBrush;
|
HBRUSH CursorBrush, OldBrush;
|
||||||
HFONT OldFont;
|
HFONT OldFont;
|
||||||
|
@ -205,35 +198,40 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||||
BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buffer->ViewOrigin.Y;
|
BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buffer->ViewOrigin.Y;
|
||||||
LeftChar = rc->left / GuiData->CharWidth + Buffer->ViewOrigin.X;
|
LeftChar = rc->left / GuiData->CharWidth + Buffer->ViewOrigin.X;
|
||||||
RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1 + 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)));
|
SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute)));
|
||||||
SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute)));
|
SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute)));
|
||||||
|
|
||||||
if (BottomLine >= Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1;
|
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);
|
OldFont = SelectObject(hDC, GuiData->Font);
|
||||||
|
|
||||||
for (Line = TopLine; Line <= BottomLine; Line++)
|
for (Line = TopLine; Line <= BottomLine; Line++)
|
||||||
{
|
{
|
||||||
WCHAR LineBuffer[80];
|
WCHAR LineBuffer[80]; // Buffer containing a part or all the line to be displayed
|
||||||
From = ConioCoordToPointer(Buffer, LeftChar, Line);
|
From = ConioCoordToPointer(Buffer, LeftChar, Line); // Get the first code of the line
|
||||||
Start = LeftChar;
|
Start = LeftChar;
|
||||||
To = LineBuffer;
|
To = LineBuffer;
|
||||||
|
|
||||||
for (Char = LeftChar; Char <= RightChar; Char++)
|
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,
|
TextOutW(hDC,
|
||||||
(Start - Buffer->ViewOrigin.X) * GuiData->CharWidth,
|
(Start - Buffer->ViewOrigin.X) * GuiData->CharWidth ,
|
||||||
(Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight,
|
(Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight,
|
||||||
LineBuffer,
|
LineBuffer,
|
||||||
Char - Start);
|
Char - Start);
|
||||||
Start = Char;
|
Start = Char;
|
||||||
To = LineBuffer;
|
To = LineBuffer;
|
||||||
Attribute = *(From + 1);
|
Attribute = From->Attributes;
|
||||||
if (Attribute != LastAttribute)
|
if (Attribute != LastAttribute)
|
||||||
{
|
{
|
||||||
SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute)));
|
SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute)));
|
||||||
|
@ -242,15 +240,12 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiByteToWideChar(Console->OutputCodePage,
|
*(To++) = (From++)->Char.UnicodeChar;
|
||||||
0, (PCHAR)From, 1, To, 1);
|
|
||||||
To++;
|
|
||||||
From += 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextOutW(hDC,
|
TextOutW(hDC,
|
||||||
(Start - Buffer->ViewOrigin.X) * GuiData->CharWidth,
|
(Start - Buffer->ViewOrigin.X) * GuiData->CharWidth ,
|
||||||
(Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight,
|
(Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight,
|
||||||
LineBuffer,
|
LineBuffer,
|
||||||
RightChar - Start + 1);
|
RightChar - Start + 1);
|
||||||
}
|
}
|
||||||
|
@ -268,11 +263,11 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||||
TopLine <= CursorY && CursorY <= BottomLine)
|
TopLine <= CursorY && CursorY <= BottomLine)
|
||||||
{
|
{
|
||||||
CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -230,23 +230,25 @@ TuiSwapConsole(INT Next)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID FASTCALL
|
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;
|
UINT SrcDelta, DestDelta;
|
||||||
LONG i;
|
LONG i;
|
||||||
PBYTE Src, SrcEnd;
|
PCHAR_INFO Src, SrcEnd;
|
||||||
|
|
||||||
Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
|
Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
|
||||||
SrcDelta = Buff->ScreenBufferSize.X * 2;
|
SrcDelta = Buff->ScreenBufferSize.X * sizeof(CHAR_INFO);
|
||||||
SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
|
SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * sizeof(CHAR_INFO);
|
||||||
DestDelta = ConioRectWidth(Region) * 2;
|
DestDelta = ConioRectWidth(Region) * 2 /* 2 == sizeof(CHAR) + sizeof(BYTE) */;
|
||||||
for (i = Region->Top; i <= Region->Bottom; i++)
|
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;
|
Src += SrcDelta;
|
||||||
if (SrcEnd <= Src)
|
if (SrcEnd <= Src)
|
||||||
{
|
{
|
||||||
Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
|
Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * sizeof(CHAR_INFO);
|
||||||
}
|
}
|
||||||
Dest += DestDelta;
|
Dest += DestDelta;
|
||||||
}
|
}
|
||||||
|
@ -501,7 +503,7 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
||||||
ConsoleDraw->CursorX = Buff->CursorPosition.X;
|
ConsoleDraw->CursorX = Buff->CursorPosition.X;
|
||||||
ConsoleDraw->CursorY = Buff->CursorPosition.Y;
|
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,
|
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
|
||||||
NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
|
NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
|
||||||
|
@ -516,17 +518,31 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY,
|
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;
|
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
||||||
|
PCHAR NewBuffer;
|
||||||
|
ULONG NewLength;
|
||||||
|
DWORD BytesWritten;
|
||||||
|
|
||||||
if (ActiveConsole->Console->ActiveBuffer != Buff) return;
|
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");
|
DPRINT1("Error writing to BlueScreen\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
|
|
|
@ -126,12 +126,12 @@ typedef struct _TEXTMODE_BUFFER_INFO
|
||||||
|
|
||||||
typedef struct _TEXTMODE_SCREEN_BUFFER
|
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 ScreenDefaultAttrib; /* Default screen char attribute */
|
||||||
WORD PopupDefaultAttrib; /* Default popup char attribute */
|
WORD PopupDefaultAttrib; /* Default popup char attribute */
|
||||||
} TEXTMODE_SCREEN_BUFFER, *PTEXTMODE_SCREEN_BUFFER;
|
} TEXTMODE_SCREEN_BUFFER, *PTEXTMODE_SCREEN_BUFFER;
|
||||||
|
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ typedef struct _FRONTEND_VTBL
|
||||||
SHORT CursorStartX,
|
SHORT CursorStartX,
|
||||||
SHORT CursorStartY,
|
SHORT CursorStartY,
|
||||||
UINT ScrolledLines,
|
UINT ScrolledLines,
|
||||||
CHAR *Buffer,
|
PWCHAR Buffer,
|
||||||
UINT Length);
|
UINT Length);
|
||||||
BOOL (WINAPI *SetCursorInfo)(struct _CONSOLE* Console,
|
BOOL (WINAPI *SetCursorInfo)(struct _CONSOLE* Console,
|
||||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
||||||
|
@ -286,7 +286,6 @@ typedef struct _CONSOLE
|
||||||
BOOLEAN QuickEdit;
|
BOOLEAN QuickEdit;
|
||||||
BOOLEAN InsertMode;
|
BOOLEAN InsertMode;
|
||||||
UINT CodePage;
|
UINT CodePage;
|
||||||
UINT OutputCodePage;
|
|
||||||
|
|
||||||
CONSOLE_SELECTION_INFO Selection; /* Contains information about the selection */
|
CONSOLE_SELECTION_INFO Selection; /* Contains information about the selection */
|
||||||
COORD dwSelectionCursor; /* Selection cursor position, most of the time different from Selection.dwSelectionAnchor */
|
COORD dwSelectionCursor; /* Selection cursor position, most of the time different from Selection.dwSelectionAnchor */
|
||||||
|
@ -297,6 +296,7 @@ typedef struct _CONSOLE
|
||||||
BYTE PauseFlags;
|
BYTE PauseFlags;
|
||||||
HANDLE UnpauseEvent;
|
HANDLE UnpauseEvent;
|
||||||
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
|
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
|
||||||
|
UINT OutputCodePage;
|
||||||
|
|
||||||
/**************************** Aliases and Histories ***************************/
|
/**************************** Aliases and Histories ***************************/
|
||||||
struct _ALIAS_HEADER *Aliases;
|
struct _ALIAS_HEADER *Aliases;
|
||||||
|
@ -348,14 +348,20 @@ do { \
|
||||||
#define ConioRectWidth(Rect) \
|
#define ConioRectWidth(Rect) \
|
||||||
(((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1)
|
(((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);
|
VOID FASTCALL ConioDrawConsole(PCONSOLE Console);
|
||||||
NTSTATUS ConioResizeBuffer(PCONSOLE Console,
|
NTSTATUS ConioResizeBuffer(PCONSOLE Console,
|
||||||
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||||
COORD Size);
|
COORD Size);
|
||||||
NTSTATUS ConioWriteConsole(PCONSOLE Console,
|
NTSTATUS ConioWriteConsole(PCONSOLE Console,
|
||||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||||
CHAR *Buffer,
|
PWCHAR Buffer,
|
||||||
DWORD Length,
|
DWORD Length,
|
||||||
BOOL Attrib);
|
BOOL Attrib);
|
||||||
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console,
|
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console,
|
||||||
|
|
|
@ -214,15 +214,11 @@ LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Inser
|
||||||
{
|
{
|
||||||
for (i = Pos; i < NewSize; i++)
|
for (i = Pos; i < NewSize; i++)
|
||||||
{
|
{
|
||||||
CHAR AsciiChar;
|
ConioWriteConsole(Console, ActiveBuffer, &Console->LineBuffer[i], 1, TRUE);
|
||||||
WideCharToMultiByte(Console->OutputCodePage, 0,
|
|
||||||
&Console->LineBuffer[i], 1,
|
|
||||||
&AsciiChar, 1, NULL, NULL);
|
|
||||||
ConioWriteConsole(Console, ActiveBuffer, &AsciiChar, 1, TRUE);
|
|
||||||
}
|
}
|
||||||
for (; i < Console->LineSize; i++)
|
for (; i < Console->LineSize; i++)
|
||||||
{
|
{
|
||||||
ConioWriteConsole(Console, ActiveBuffer, " ", 1, TRUE);
|
ConioWriteConsole(Console, ActiveBuffer, L" ", 1, TRUE);
|
||||||
}
|
}
|
||||||
Console->LinePos = i;
|
Console->LinePos = i;
|
||||||
}
|
}
|
||||||
|
@ -413,7 +409,7 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
|
||||||
{
|
{
|
||||||
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
|
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)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,6 @@
|
||||||
|
|
||||||
#define TAB_WIDTH 8
|
#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 **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
@ -84,8 +78,9 @@ TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
|
||||||
NewBuffer->Vtbl = &TextVtbl;
|
NewBuffer->Vtbl = &TextVtbl;
|
||||||
|
|
||||||
NewBuffer->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
|
NewBuffer->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
|
||||||
2 * TextModeInfo->ScreenBufferSize.X
|
TextModeInfo->ScreenBufferSize.X *
|
||||||
* TextModeInfo->ScreenBufferSize.Y);
|
TextModeInfo->ScreenBufferSize.Y *
|
||||||
|
sizeof(CHAR_INFO));
|
||||||
if (NewBuffer->Buffer == NULL)
|
if (NewBuffer->Buffer == NULL)
|
||||||
{
|
{
|
||||||
CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
|
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)
|
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
|
static VOID FASTCALL
|
||||||
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff)
|
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff)
|
||||||
{
|
{
|
||||||
PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y);
|
PCHAR_INFO Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y);
|
||||||
SHORT Pos;
|
SHORT Pos;
|
||||||
|
|
||||||
for (Pos = 0; Pos < Buff->ScreenBufferSize.X; Pos++)
|
for (Pos = 0; Pos < Buff->ScreenBufferSize.X; Pos++, Ptr++)
|
||||||
{
|
{
|
||||||
/* Fill the cell */
|
/* Fill the cell */
|
||||||
*Ptr++ = ' ';
|
Ptr->Char.UnicodeChar = L' ';
|
||||||
*Ptr++ = (BYTE)Buff->ScreenDefaultAttrib;
|
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,9 +247,9 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||||
SMALL_RECT* SrcRegion,
|
SMALL_RECT* SrcRegion,
|
||||||
SMALL_RECT* DstRegion,
|
SMALL_RECT* DstRegion,
|
||||||
SMALL_RECT* ClipRegion,
|
SMALL_RECT* ClipRegion,
|
||||||
WORD Fill)
|
CHAR_INFO FillChar)
|
||||||
{
|
{
|
||||||
int Width = ConioRectWidth(SrcRegion);
|
int Width = ConioRectWidth(SrcRegion);
|
||||||
int Height = ConioRectHeight(SrcRegion);
|
int Height = ConioRectHeight(SrcRegion);
|
||||||
int SX, SY;
|
int SX, SY;
|
||||||
int DX, DY;
|
int DX, DY;
|
||||||
|
@ -273,8 +268,8 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||||
}
|
}
|
||||||
for (i = 0; i < Height; i++)
|
for (i = 0; i < Height; i++)
|
||||||
{
|
{
|
||||||
PWORD SRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, SY);
|
PCHAR_INFO SRow = ConioCoordToPointer(ScreenBuffer, 0, SY);
|
||||||
PWORD DRow = (PWORD)ConioCoordToPointer(ScreenBuffer, 0, DY);
|
PCHAR_INFO DRow = ConioCoordToPointer(ScreenBuffer, 0, DY);
|
||||||
|
|
||||||
SX = SrcRegion->Left;
|
SX = SrcRegion->Left;
|
||||||
DX = DstRegion->Left;
|
DX = DstRegion->Left;
|
||||||
|
@ -288,14 +283,14 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||||
}
|
}
|
||||||
for (j = 0; j < Width; j++)
|
for (j = 0; j < Width; j++)
|
||||||
{
|
{
|
||||||
WORD Cell = SRow[SX];
|
CHAR_INFO Cell = SRow[SX];
|
||||||
if (SX >= ClipRegion->Left && SX <= ClipRegion->Right
|
if (SX >= ClipRegion->Left && SX <= ClipRegion->Right &&
|
||||||
&& SY >= ClipRegion->Top && SY <= ClipRegion->Bottom)
|
SY >= ClipRegion->Top && SY <= ClipRegion->Bottom)
|
||||||
{
|
{
|
||||||
SRow[SX] = Fill;
|
SRow[SX] = FillChar;
|
||||||
}
|
}
|
||||||
if (DX >= ClipRegion->Left && DX <= ClipRegion->Right
|
if (DX >= ClipRegion->Left && DX <= ClipRegion->Right &&
|
||||||
&& DY >= ClipRegion->Top && DY <= ClipRegion->Bottom)
|
DY >= ClipRegion->Top && DY <= ClipRegion->Bottom)
|
||||||
{
|
{
|
||||||
DRow[DX] = Cell;
|
DRow[DX] = Cell;
|
||||||
}
|
}
|
||||||
|
@ -322,11 +317,11 @@ ConioResizeBuffer(PCONSOLE Console,
|
||||||
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||||
COORD Size)
|
COORD Size)
|
||||||
{
|
{
|
||||||
BYTE * Buffer;
|
PCHAR_INFO Buffer;
|
||||||
DWORD Offset = 0;
|
DWORD Offset = 0;
|
||||||
BYTE * OldPtr;
|
PCHAR_INFO ptr;
|
||||||
USHORT CurrentY;
|
USHORT CurrentY;
|
||||||
BYTE * OldBuffer;
|
PCHAR_INFO OldBuffer;
|
||||||
#ifdef HAVE_WMEMSET
|
#ifdef HAVE_WMEMSET
|
||||||
USHORT value = MAKEWORD(' ', ScreenBuffer->ScreenDefaultAttrib);
|
USHORT value = MAKEWORD(' ', ScreenBuffer->ScreenDefaultAttrib);
|
||||||
#else
|
#else
|
||||||
|
@ -355,7 +350,7 @@ ConioResizeBuffer(PCONSOLE Console,
|
||||||
return STATUS_NOT_SUPPORTED; // STATUS_SUCCESS
|
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;
|
if (!Buffer) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->ScreenBufferSize.X, ScreenBuffer->ScreenBufferSize.Y, Size.X, Size.Y);
|
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++)
|
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)
|
if (Size.X <= ScreenBuffer->ScreenBufferSize.X)
|
||||||
{
|
{
|
||||||
/* reduce size */
|
/* Reduce size */
|
||||||
RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2);
|
RtlCopyMemory(Buffer + Offset, ptr, Size.X * sizeof(CHAR_INFO));
|
||||||
Offset += (Size.X * 2);
|
Offset += Size.X;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* enlarge size */
|
/* Enlarge size */
|
||||||
RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->ScreenBufferSize.X * 2);
|
RtlCopyMemory(Buffer + Offset, ptr, ScreenBuffer->ScreenBufferSize.X * sizeof(CHAR_INFO));
|
||||||
Offset += (ScreenBuffer->ScreenBufferSize.X * 2);
|
Offset += ScreenBuffer->ScreenBufferSize.X;
|
||||||
|
|
||||||
diff = Size.X - ScreenBuffer->ScreenBufferSize.X;
|
diff = Size.X - ScreenBuffer->ScreenBufferSize.X;
|
||||||
/* zero new part of it */
|
/* Zero new part of it */
|
||||||
#ifdef HAVE_WMEMSET
|
#ifdef HAVE_WMEMSET
|
||||||
wmemset((PWCHAR)&Buffer[Offset], value, diff);
|
wmemset((PWCHAR)&Buffer[Offset], value, diff);
|
||||||
#else
|
#else
|
||||||
for (i = 0; i < diff; i++)
|
for (i = 0; i < diff; i++)
|
||||||
{
|
{
|
||||||
Buffer[Offset++] = ' ';
|
ptr = Buffer + Offset;
|
||||||
Buffer[Offset++] = (BYTE)ScreenBuffer->ScreenDefaultAttrib;
|
ptr->Char.UnicodeChar = L' ';
|
||||||
|
ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib;
|
||||||
|
++Offset;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -398,8 +395,10 @@ ConioResizeBuffer(PCONSOLE Console,
|
||||||
#else
|
#else
|
||||||
for (i = 0; i < diff; i++)
|
for (i = 0; i < diff; i++)
|
||||||
{
|
{
|
||||||
Buffer[Offset++] = ' ';
|
ptr = Buffer + Offset;
|
||||||
Buffer[Offset++] = (BYTE)ScreenBuffer->ScreenDefaultAttrib;
|
ptr->Char.UnicodeChar = L' ';
|
||||||
|
ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib;
|
||||||
|
++Offset;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -461,12 +460,12 @@ ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, UINT *Scroll
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ConioWriteConsole(PCONSOLE Console,
|
ConioWriteConsole(PCONSOLE Console,
|
||||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||||
CHAR *Buffer,
|
PWCHAR Buffer,
|
||||||
DWORD Length,
|
DWORD Length,
|
||||||
BOOL Attrib)
|
BOOL Attrib)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
PBYTE Ptr;
|
PCHAR_INFO Ptr;
|
||||||
SMALL_RECT UpdateRect;
|
SMALL_RECT UpdateRect;
|
||||||
SHORT CursorStartX, CursorStartY;
|
SHORT CursorStartX, CursorStartY;
|
||||||
UINT ScrolledLines;
|
UINT ScrolledLines;
|
||||||
|
@ -488,7 +487,7 @@ ConioWriteConsole(PCONSOLE Console,
|
||||||
if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
|
if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
|
||||||
{
|
{
|
||||||
/* --- CR --- */
|
/* --- CR --- */
|
||||||
if (Buffer[i] == '\r')
|
if (Buffer[i] == L'\r')
|
||||||
{
|
{
|
||||||
Buff->CursorPosition.X = 0;
|
Buff->CursorPosition.X = 0;
|
||||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||||
|
@ -496,14 +495,14 @@ ConioWriteConsole(PCONSOLE Console,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* --- LF --- */
|
/* --- LF --- */
|
||||||
else if (Buffer[i] == '\n')
|
else if (Buffer[i] == L'\n')
|
||||||
{
|
{
|
||||||
Buff->CursorPosition.X = 0;
|
Buff->CursorPosition.X = 0;
|
||||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* --- BS --- */
|
/* --- 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 */
|
/* Only handle BS if we're not on the first pos of the first line */
|
||||||
if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y)
|
if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y)
|
||||||
|
@ -520,15 +519,15 @@ ConioWriteConsole(PCONSOLE Console,
|
||||||
Buff->CursorPosition.X--;
|
Buff->CursorPosition.X--;
|
||||||
}
|
}
|
||||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||||
Ptr[0] = ' ';
|
Ptr->Char.UnicodeChar = L' ';
|
||||||
Ptr[1] = (BYTE)Buff->ScreenDefaultAttrib;
|
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* --- TAB --- */
|
/* --- TAB --- */
|
||||||
else if (Buffer[i] == '\t')
|
else if (Buffer[i] == L'\t')
|
||||||
{
|
{
|
||||||
UINT EndX;
|
UINT EndX;
|
||||||
|
|
||||||
|
@ -538,8 +537,9 @@ ConioWriteConsole(PCONSOLE Console,
|
||||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||||
while (Buff->CursorPosition.X < EndX)
|
while (Buff->CursorPosition.X < EndX)
|
||||||
{
|
{
|
||||||
*Ptr++ = ' ';
|
Ptr->Char.UnicodeChar = L' ';
|
||||||
*Ptr++ = (BYTE)Buff->ScreenDefaultAttrib;
|
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||||
|
++Ptr;
|
||||||
Buff->CursorPosition.X++;
|
Buff->CursorPosition.X++;
|
||||||
}
|
}
|
||||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1);
|
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1);
|
||||||
|
@ -558,7 +558,7 @@ ConioWriteConsole(PCONSOLE Console,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// /* --- BEL ---*/
|
// /* --- BEL ---*/
|
||||||
// else if (Buffer[i] == '\a')
|
// else if (Buffer[i] == L'\a')
|
||||||
// {
|
// {
|
||||||
// // FIXME: This MUST BE moved to the terminal emulator frontend!!
|
// // FIXME: This MUST BE moved to the terminal emulator frontend!!
|
||||||
// DPRINT1("Bell\n");
|
// DPRINT1("Bell\n");
|
||||||
|
@ -566,14 +566,13 @@ ConioWriteConsole(PCONSOLE Console,
|
||||||
// continue;
|
// 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);
|
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||||
|
|
||||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||||
Ptr[0] = Buffer[i];
|
Ptr->Char.UnicodeChar = Buffer[i];
|
||||||
if (Attrib)
|
if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||||
{
|
|
||||||
Ptr[1] = (BYTE)Buff->ScreenDefaultAttrib;
|
|
||||||
}
|
|
||||||
Buff->CursorPosition.X++;
|
Buff->CursorPosition.X++;
|
||||||
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.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_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
|
||||||
PCONSOLE Console;
|
PCONSOLE Console;
|
||||||
PTEXTMODE_SCREEN_BUFFER Buff;
|
PTEXTMODE_SCREEN_BUFFER Buff;
|
||||||
PCHAR Buffer;
|
PVOID Buffer;
|
||||||
DWORD Written = 0;
|
DWORD Written = 0;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
|
||||||
|
@ -684,41 +683,44 @@ DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
|
||||||
{
|
{
|
||||||
if (WriteConsoleRequest->Unicode)
|
if (WriteConsoleRequest->Unicode)
|
||||||
{
|
{
|
||||||
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
|
Buffer = WriteConsoleRequest->Buffer;
|
||||||
(PWCHAR)WriteConsoleRequest->Buffer,
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Length = MultiByteToWideChar(Console->OutputCodePage, 0,
|
||||||
|
(PCHAR)WriteConsoleRequest->Buffer,
|
||||||
WriteConsoleRequest->NrCharactersToWrite,
|
WriteConsoleRequest->NrCharactersToWrite,
|
||||||
NULL, 0, NULL, NULL);
|
NULL, 0);
|
||||||
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
|
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
WideCharToMultiByte(Console->OutputCodePage, 0,
|
MultiByteToWideChar(Console->OutputCodePage, 0,
|
||||||
(PWCHAR)WriteConsoleRequest->Buffer,
|
(PCHAR)WriteConsoleRequest->Buffer,
|
||||||
WriteConsoleRequest->NrCharactersToWrite,
|
WriteConsoleRequest->NrCharactersToWrite,
|
||||||
Buffer, Length, NULL, NULL);
|
(PWCHAR)Buffer, Length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Buffer = (PCHAR)WriteConsoleRequest->Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = ConioWriteConsole(Console, Buff, Buffer,
|
Status = ConioWriteConsole(Console,
|
||||||
WriteConsoleRequest->NrCharactersToWrite, TRUE);
|
Buff,
|
||||||
|
Buffer,
|
||||||
|
WriteConsoleRequest->NrCharactersToWrite,
|
||||||
|
TRUE);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Written = WriteConsoleRequest->NrCharactersToWrite;
|
Written = WriteConsoleRequest->NrCharactersToWrite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WriteConsoleRequest->Unicode)
|
if (!WriteConsoleRequest->Unicode)
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -746,7 +748,7 @@ CSR_API(SrvReadConsoleOutput)
|
||||||
SMALL_RECT ReadRegion;
|
SMALL_RECT ReadRegion;
|
||||||
SMALL_RECT ScreenRect;
|
SMALL_RECT ScreenRect;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
PBYTE Ptr;
|
PCHAR_INFO Ptr;
|
||||||
LONG X, Y;
|
LONG X, Y;
|
||||||
UINT CodePage;
|
UINT CodePage;
|
||||||
|
|
||||||
|
@ -792,16 +794,16 @@ CSR_API(SrvReadConsoleOutput)
|
||||||
{
|
{
|
||||||
if (ReadOutputRequest->Unicode)
|
if (ReadOutputRequest->Unicode)
|
||||||
{
|
{
|
||||||
// ConsoleAnsiCharToUnicodeChar(ProcessData->Console, (PCHAR)Ptr++, &CurCharInfo->Char.UnicodeChar);
|
CurCharInfo->Char.UnicodeChar = Ptr->Char.UnicodeChar;
|
||||||
MultiByteToWideChar(CodePage, 0,
|
|
||||||
(PCHAR)Ptr++, 1,
|
|
||||||
&CurCharInfo->Char.UnicodeChar, 1);
|
|
||||||
}
|
}
|
||||||
else
|
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;
|
++CurCharInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -824,13 +826,13 @@ CSR_API(SrvWriteConsoleOutput)
|
||||||
PCONSOLE Console;
|
PCONSOLE Console;
|
||||||
PTEXTMODE_SCREEN_BUFFER Buff;
|
PTEXTMODE_SCREEN_BUFFER Buff;
|
||||||
SMALL_RECT ScreenBuffer;
|
SMALL_RECT ScreenBuffer;
|
||||||
CHAR_INFO* CurCharInfo;
|
PCHAR_INFO CurCharInfo;
|
||||||
SMALL_RECT WriteRegion;
|
SMALL_RECT WriteRegion;
|
||||||
CHAR_INFO* CharInfo;
|
PCHAR_INFO CharInfo;
|
||||||
COORD BufferCoord;
|
COORD BufferCoord;
|
||||||
COORD BufferSize;
|
COORD BufferSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PBYTE Ptr;
|
PCHAR_INFO Ptr;
|
||||||
|
|
||||||
DPRINT("SrvWriteConsoleOutput\n");
|
DPRINT("SrvWriteConsoleOutput\n");
|
||||||
|
|
||||||
|
@ -847,10 +849,10 @@ CSR_API(SrvWriteConsoleOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ConSrvGetTextModeBuffer(ProcessData,
|
Status = ConSrvGetTextModeBuffer(ProcessData,
|
||||||
WriteOutputRequest->OutputHandle,
|
WriteOutputRequest->OutputHandle,
|
||||||
&Buff,
|
&Buff,
|
||||||
GENERIC_WRITE,
|
GENERIC_WRITE,
|
||||||
TRUE);
|
TRUE);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
Console = Buff->Header.Console;
|
Console = Buff->Header.Console;
|
||||||
|
@ -876,21 +878,21 @@ CSR_API(SrvWriteConsoleOutput)
|
||||||
for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++)
|
for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++)
|
||||||
{
|
{
|
||||||
CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
|
CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X;
|
||||||
|
|
||||||
Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y);
|
Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y);
|
||||||
for (X = WriteRegion.Left; X <= WriteRegion.Right; X++)
|
for (X = WriteRegion.Left; X <= WriteRegion.Right; X++)
|
||||||
{
|
{
|
||||||
CHAR AsciiChar;
|
|
||||||
if (WriteOutputRequest->Unicode)
|
if (WriteOutputRequest->Unicode)
|
||||||
{
|
{
|
||||||
ConsoleUnicodeCharToAnsiChar(Console, &AsciiChar, &CurCharInfo->Char.UnicodeChar);
|
Ptr->Char.UnicodeChar = CurCharInfo->Char.UnicodeChar;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AsciiChar = CurCharInfo->Char.AsciiChar;
|
ConsoleAnsiCharToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char.AsciiChar);
|
||||||
}
|
}
|
||||||
*Ptr++ = AsciiChar;
|
Ptr->Attributes = CurCharInfo->Attributes;
|
||||||
*Ptr++ = (BYTE)CurCharInfo->Attributes;
|
++Ptr;
|
||||||
CurCharInfo++;
|
++CurCharInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,7 +944,7 @@ CSR_API(SrvReadConsoleOutputString)
|
||||||
PVOID ReadBuffer;
|
PVOID ReadBuffer;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
ULONG CodeSize;
|
ULONG CodeSize;
|
||||||
BYTE Code;
|
PCHAR_INFO Ptr;
|
||||||
|
|
||||||
DPRINT("SrvReadConsoleOutputString\n");
|
DPRINT("SrvReadConsoleOutputString\n");
|
||||||
|
|
||||||
|
@ -973,7 +975,11 @@ CSR_API(SrvReadConsoleOutputString)
|
||||||
return STATUS_INVALID_PARAMETER;
|
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;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
Console = Buff->Header.Console;
|
Console = Buff->Header.Console;
|
||||||
|
@ -995,25 +1001,28 @@ CSR_API(SrvReadConsoleOutputString)
|
||||||
* TODO: Do NOT loop up to NumCodesToRead, but stop before
|
* TODO: Do NOT loop up to NumCodesToRead, but stop before
|
||||||
* if we are going to overflow...
|
* 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)
|
switch (CodeType)
|
||||||
{
|
{
|
||||||
case CODE_UNICODE:
|
case CODE_ASCII:
|
||||||
ConsoleAnsiCharToUnicodeChar(Console, (PWCHAR)ReadBuffer, (PCHAR)&Code);
|
ConsoleUnicodeCharToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CODE_ASCII:
|
case CODE_UNICODE:
|
||||||
*(PCHAR)ReadBuffer = (CHAR)Code;
|
*(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CODE_ATTRIBUTE:
|
case CODE_ATTRIBUTE:
|
||||||
*(PWORD)ReadBuffer = (WORD)Code;
|
*(PWORD)ReadBuffer = Ptr->Attributes;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
|
ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
|
||||||
|
// ++Ptr;
|
||||||
|
|
||||||
Xpos++;
|
Xpos++;
|
||||||
|
|
||||||
|
@ -1062,11 +1071,12 @@ CSR_API(SrvWriteConsoleOutputString)
|
||||||
PCONSOLE Console;
|
PCONSOLE Console;
|
||||||
PTEXTMODE_SCREEN_BUFFER Buff;
|
PTEXTMODE_SCREEN_BUFFER Buff;
|
||||||
USHORT CodeType;
|
USHORT CodeType;
|
||||||
PBYTE Buffer; // PUCHAR
|
PVOID ReadBuffer = NULL;
|
||||||
PCHAR String, tmpString = NULL;
|
PWCHAR tmpString = NULL;
|
||||||
DWORD X, Y, Length; // , Written = 0;
|
DWORD X, Y, Length; // , Written = 0;
|
||||||
ULONG CodeSize;
|
ULONG CodeSize;
|
||||||
SMALL_RECT UpdateRect;
|
SMALL_RECT UpdateRect;
|
||||||
|
PCHAR_INFO Ptr;
|
||||||
|
|
||||||
DPRINT("SrvWriteConsoleOutputString\n");
|
DPRINT("SrvWriteConsoleOutputString\n");
|
||||||
|
|
||||||
|
@ -1098,85 +1108,90 @@ CSR_API(SrvWriteConsoleOutputString)
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||||
WriteOutputCodeRequest->OutputHandle,
|
WriteOutputCodeRequest->OutputHandle,
|
||||||
&Buff,
|
&Buff,
|
||||||
GENERIC_WRITE,
|
GENERIC_WRITE,
|
||||||
TRUE);
|
TRUE);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
Console = Buff->Header.Console;
|
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,
|
MultiByteToWideChar(Console->OutputCodePage, 0,
|
||||||
(PWCHAR)WriteOutputCodeRequest->pCode.UnicodeChar,
|
WriteOutputCodeRequest->pCode.AsciiChar,
|
||||||
WriteOutputCodeRequest->Length,
|
WriteOutputCodeRequest->Length,
|
||||||
NULL, 0, NULL, NULL);
|
(PWCHAR)ReadBuffer, Length);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
case CODE_ASCII:
|
{
|
||||||
String = (PCHAR)WriteOutputCodeRequest->pCode.AsciiChar;
|
Status = STATUS_NO_MEMORY;
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
case CODE_ATTRIBUTE:
|
else
|
||||||
default:
|
{
|
||||||
// *(ReadBuffer++) = Code;
|
/* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */
|
||||||
String = (PCHAR)WriteOutputCodeRequest->pCode.Attribute;
|
ReadBuffer = WriteOutputCodeRequest->pCode.pCode;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (String && NT_SUCCESS(Status))
|
if (ReadBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup;
|
||||||
{
|
|
||||||
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)];
|
|
||||||
|
|
||||||
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++;
|
case CODE_ASCII:
|
||||||
// ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
|
case CODE_UNICODE:
|
||||||
String = (PCHAR)((ULONG_PTR)String + CodeSize);
|
Ptr->Char.UnicodeChar = *(PWCHAR)ReadBuffer;
|
||||||
// Written++;
|
break;
|
||||||
Buffer += 2;
|
|
||||||
if (++X == Buff->ScreenBufferSize.X)
|
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;
|
||||||
{
|
|
||||||
Y = 0;
|
|
||||||
Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0);
|
|
||||||
}
|
|
||||||
X = 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)
|
if (tmpString)
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
|
||||||
|
|
||||||
|
@ -1194,56 +1209,77 @@ CSR_API(SrvFillConsoleOutput)
|
||||||
PTEXTMODE_SCREEN_BUFFER Buff;
|
PTEXTMODE_SCREEN_BUFFER Buff;
|
||||||
DWORD X, Y, Length; // , Written = 0;
|
DWORD X, Y, Length; // , Written = 0;
|
||||||
USHORT CodeType;
|
USHORT CodeType;
|
||||||
BYTE Code;
|
PVOID Code = NULL;
|
||||||
PBYTE Buffer;
|
PCHAR_INFO Ptr;
|
||||||
SMALL_RECT UpdateRect;
|
SMALL_RECT UpdateRect;
|
||||||
|
|
||||||
DPRINT("SrvFillConsoleOutput\n");
|
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;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
Console = Buff->Header.Console;
|
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;
|
X = FillOutputRequest->Coord.X;
|
||||||
Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
|
Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
|
||||||
Length = FillOutputRequest->Length;
|
Length = FillOutputRequest->Length;
|
||||||
Buffer = &Buff->Buffer[2 * (Y * Buff->ScreenBufferSize.X + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
|
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work
|
||||||
|
// Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (Length--)
|
while (Length--)
|
||||||
{
|
{
|
||||||
*Buffer = Code;
|
// Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either
|
||||||
Buffer += 2;
|
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++;
|
// Written++;
|
||||||
if (++X == Buff->ScreenBufferSize.X)
|
if (++X == Buff->ScreenBufferSize.X)
|
||||||
{
|
{
|
||||||
|
X = 0;
|
||||||
|
|
||||||
if (++Y == Buff->ScreenBufferSize.Y)
|
if (++Y == Buff->ScreenBufferSize.Y)
|
||||||
{
|
{
|
||||||
Y = 0;
|
Y = 0;
|
||||||
Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0);
|
|
||||||
}
|
}
|
||||||
X = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1341,15 +1377,14 @@ CSR_API(SrvScrollConsoleScreenBuffer)
|
||||||
HANDLE OutputHandle;
|
HANDLE OutputHandle;
|
||||||
BOOLEAN UseClipRectangle;
|
BOOLEAN UseClipRectangle;
|
||||||
COORD DestinationOrigin;
|
COORD DestinationOrigin;
|
||||||
CHAR_INFO Fill;
|
CHAR_INFO FillChar;
|
||||||
CHAR FillChar;
|
|
||||||
|
|
||||||
DPRINT("SrvScrollConsoleScreenBuffer\n");
|
DPRINT("SrvScrollConsoleScreenBuffer\n");
|
||||||
|
|
||||||
OutputHandle = ScrollScreenBufferRequest->OutputHandle;
|
OutputHandle = ScrollScreenBufferRequest->OutputHandle;
|
||||||
UseClipRectangle = ScrollScreenBufferRequest->UseClipRectangle;
|
UseClipRectangle = ScrollScreenBufferRequest->UseClipRectangle;
|
||||||
DestinationOrigin = ScrollScreenBufferRequest->DestinationOrigin;
|
DestinationOrigin = ScrollScreenBufferRequest->DestinationOrigin;
|
||||||
Fill = ScrollScreenBufferRequest->Fill;
|
FillChar = ScrollScreenBufferRequest->Fill;
|
||||||
|
|
||||||
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), OutputHandle, &Buff, GENERIC_WRITE, TRUE);
|
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), OutputHandle, &Buff, GENERIC_WRITE, TRUE);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
@ -1396,12 +1431,10 @@ CSR_API(SrvScrollConsoleScreenBuffer)
|
||||||
DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1,
|
DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1,
|
||||||
DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1);
|
DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1);
|
||||||
|
|
||||||
if (ScrollScreenBufferRequest->Unicode)
|
if (!ScrollScreenBufferRequest->Unicode)
|
||||||
ConsoleUnicodeCharToAnsiChar(Console, &FillChar, &Fill.Char.UnicodeChar);
|
ConsoleAnsiCharToUnicodeChar(Console, &FillChar.Char.UnicodeChar, &FillChar.Char.AsciiChar);
|
||||||
else
|
|
||||||
FillChar = Fill.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)
|
if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue