mirror of
https://github.com/reactos/reactos.git
synced 2024-10-07 01:44:21 +00:00
[CONSRV]
- Reintegrate the text-only frontend, deactivated in revision r58447. - Use a (temporary) helper ConioIsBufferResizeSupported to know whether or not the frontend supports screenbuffer resizing. In a near future, all the frontends will support that so this function will be removed. - Promote ConioResizeBuffer to be a function of the console server (not only reserved for the GUI frontend). [WIN32K] - Remove the support of registrating TUI notification window class (feature such as knowing at which console app the notification window belongs to is unneeded when using the TUI). - Start to introduce ConsoleAcquireDisplayOwnership, a win32k console control to let win32k release the display so that we can own it (it is step 0.0.1 on a scale of 0.0.0 to 1.0.0). Note that, as in trunk, getting a text-only interface when booting with the /CONSOLE switch still doesn't work (clash between text-mode and video-mode enabled by win32k). svn path=/branches/ros-csrss/; revision=58732
This commit is contained in:
parent
2b02f27941
commit
0777ed55e5
|
@ -1566,7 +1566,7 @@ NtUserCloseWindowStation(
|
||||||
typedef enum _CONSOLECONTROL
|
typedef enum _CONSOLECONTROL
|
||||||
{
|
{
|
||||||
GuiConsoleWndClassAtom,
|
GuiConsoleWndClassAtom,
|
||||||
TuiConsoleWndClassAtom,
|
ConsoleAcquireDisplayOwnership,
|
||||||
} CONSOLECONTROL, *PCONSOLECONTROL;
|
} CONSOLECONTROL, *PCONSOLECONTROL;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -40,7 +40,7 @@ static
|
||||||
PALIAS_HEADER
|
PALIAS_HEADER
|
||||||
IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName)
|
IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName)
|
||||||
{
|
{
|
||||||
while(RootHeader)
|
while (RootHeader)
|
||||||
{
|
{
|
||||||
INT diff = _wcsicmp(RootHeader->lpExeName, lpExeName);
|
INT diff = _wcsicmp(RootHeader->lpExeName, lpExeName);
|
||||||
if (!diff) return RootHeader;
|
if (!diff) return RootHeader;
|
||||||
|
@ -93,7 +93,7 @@ IntGetAliasEntry(PALIAS_HEADER Header, LPCWSTR lpSrcName)
|
||||||
if (Header == NULL) return NULL;
|
if (Header == NULL) return NULL;
|
||||||
|
|
||||||
RootHeader = Header->Data;
|
RootHeader = Header->Data;
|
||||||
while(RootHeader)
|
while (RootHeader)
|
||||||
{
|
{
|
||||||
INT diff;
|
INT diff;
|
||||||
DPRINT("IntGetAliasEntry->lpSource %S\n", RootHeader->lpSource);
|
DPRINT("IntGetAliasEntry->lpSource %S\n", RootHeader->lpSource);
|
||||||
|
@ -151,7 +151,7 @@ IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader)
|
||||||
{
|
{
|
||||||
UINT length = 0;
|
UINT length = 0;
|
||||||
|
|
||||||
while(RootHeader)
|
while (RootHeader)
|
||||||
{
|
{
|
||||||
length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR);
|
length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR);
|
||||||
RootHeader = RootHeader->Next;
|
RootHeader = RootHeader->Next;
|
||||||
|
@ -169,7 +169,7 @@ IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader, LPWSTR TargetBuffer, UINT Tar
|
||||||
UINT Length;
|
UINT Length;
|
||||||
|
|
||||||
TargetBufferSize /= sizeof(WCHAR);
|
TargetBufferSize /= sizeof(WCHAR);
|
||||||
while(RootHeader)
|
while (RootHeader)
|
||||||
{
|
{
|
||||||
Length = wcslen(RootHeader->lpExeName) + 1;
|
Length = wcslen(RootHeader->lpExeName) + 1;
|
||||||
if (TargetBufferSize > Offset + Length)
|
if (TargetBufferSize > Offset + Length)
|
||||||
|
@ -194,7 +194,7 @@ IntGetAllConsoleAliasesLength(PALIAS_HEADER Header)
|
||||||
UINT Length = 0;
|
UINT Length = 0;
|
||||||
PALIAS_ENTRY CurEntry = Header->Data;
|
PALIAS_ENTRY CurEntry = Header->Data;
|
||||||
|
|
||||||
while(CurEntry)
|
while (CurEntry)
|
||||||
{
|
{
|
||||||
Length += wcslen(CurEntry->lpSource);
|
Length += wcslen(CurEntry->lpSource);
|
||||||
Length += wcslen(CurEntry->lpTarget);
|
Length += wcslen(CurEntry->lpTarget);
|
||||||
|
@ -217,7 +217,7 @@ IntGetAllConsoleAliases(PALIAS_HEADER Header, LPWSTR TargetBuffer, UINT TargetBu
|
||||||
UINT SrcLength, TargetLength;
|
UINT SrcLength, TargetLength;
|
||||||
|
|
||||||
TargetBufferLength /= sizeof(WCHAR);
|
TargetBufferLength /= sizeof(WCHAR);
|
||||||
while(CurEntry)
|
while (CurEntry)
|
||||||
{
|
{
|
||||||
SrcLength = wcslen(CurEntry->lpSource) + 1;
|
SrcLength = wcslen(CurEntry->lpSource) + 1;
|
||||||
TargetLength = wcslen(CurEntry->lpTarget) + 1;
|
TargetLength = wcslen(CurEntry->lpTarget) + 1;
|
||||||
|
|
|
@ -772,7 +772,7 @@ CSR_API(SrvGetConsoleInput)
|
||||||
GetInputRequest->InputsRead = 0;
|
GetInputRequest->InputsRead = 0;
|
||||||
|
|
||||||
Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, GetInputRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE);
|
Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, GetInputRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE);
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
InputInfo.CallingThread = CsrGetClientThread();
|
InputInfo.CallingThread = CsrGetClientThread();
|
||||||
InputInfo.HandleEntry = HandleEntry;
|
InputInfo.HandleEntry = HandleEntry;
|
||||||
|
@ -855,7 +855,7 @@ CSR_API(SrvFlushConsoleInputBuffer)
|
||||||
&InputBuffer,
|
&InputBuffer,
|
||||||
GENERIC_WRITE,
|
GENERIC_WRITE,
|
||||||
TRUE);
|
TRUE);
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
/* Discard all entries in the input event queue */
|
/* Discard all entries in the input event queue */
|
||||||
while (!IsListEmpty(&InputBuffer->InputEvents))
|
while (!IsListEmpty(&InputBuffer->InputEvents))
|
||||||
|
|
|
@ -10,27 +10,35 @@
|
||||||
|
|
||||||
/* Macros used to call functions in the FRONTEND_VTBL virtual table */
|
/* Macros used to call functions in the FRONTEND_VTBL virtual table */
|
||||||
|
|
||||||
#define ConioDrawRegion(Console, Region) (Console)->TermIFace.Vtbl->DrawRegion((Console), (Region))
|
#define ConioDrawRegion(Console, Region) \
|
||||||
|
(Console)->TermIFace.Vtbl->DrawRegion((Console), (Region))
|
||||||
#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
|
#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
|
||||||
(Console)->TermIFace.Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
|
(Console)->TermIFace.Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
|
||||||
(ScrolledLines), (Buffer), (Length))
|
(ScrolledLines), (Buffer), (Length))
|
||||||
#define ConioSetCursorInfo(Console, Buff) (Console)->TermIFace.Vtbl->SetCursorInfo((Console), (Buff))
|
#define ConioSetCursorInfo(Console, Buff) \
|
||||||
|
(Console)->TermIFace.Vtbl->SetCursorInfo((Console), (Buff))
|
||||||
#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \
|
#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \
|
||||||
(Console)->TermIFace.Vtbl->SetScreenInfo((Console), (Buff), (OldCursorX), (OldCursorY))
|
(Console)->TermIFace.Vtbl->SetScreenInfo((Console), (Buff), (OldCursorX), (OldCursorY))
|
||||||
#define ConioUpdateScreenInfo(Console, Buff) \
|
#define ConioUpdateScreenInfo(Console, Buff) \
|
||||||
(Console)->TermIFace.Vtbl->UpdateScreenInfo((Console), (Buff))
|
(Console)->TermIFace.Vtbl->UpdateScreenInfo((Console), (Buff))
|
||||||
#define ConioChangeTitle(Console) (Console)->TermIFace.Vtbl->ChangeTitle(Console)
|
#define ConioIsBufferResizeSupported(Console) \
|
||||||
#define ConioCleanupConsole(Console) (Console)->TermIFace.Vtbl->CleanupConsole(Console)
|
(Console)->TermIFace.Vtbl->IsBufferResizeSupported(Console)
|
||||||
#define ConioChangeIcon(Console, hWindowIcon) (Console)->TermIFace.Vtbl->ChangeIcon((Console), (hWindowIcon))
|
#define ConioChangeTitle(Console) \
|
||||||
#define ConioResizeBuffer(Console, Buff, Size) (Console)->TermIFace.Vtbl->ResizeBuffer((Console), (Buff), (Size))
|
(Console)->TermIFace.Vtbl->ChangeTitle(Console)
|
||||||
#define ConioResizeTerminal(Console) (Console)->TermIFace.Vtbl->ResizeTerminal((Console))
|
#define ConioCleanupConsole(Console) \
|
||||||
|
(Console)->TermIFace.Vtbl->CleanupConsole(Console)
|
||||||
|
#define ConioChangeIcon(Console, hWindowIcon) \
|
||||||
|
(Console)->TermIFace.Vtbl->ChangeIcon((Console), (hWindowIcon))
|
||||||
|
// #define ConioResizeBuffer(Console, Buff, Size) (Console)->TermIFace.Vtbl->ResizeBuffer((Console), (Buff), (Size))
|
||||||
|
#define ConioResizeTerminal(Console) \
|
||||||
|
(Console)->TermIFace.Vtbl->ResizeTerminal(Console)
|
||||||
#define ConioProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) \
|
#define ConioProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) \
|
||||||
(Console)->TermIFace.Vtbl->ProcessKeyCallback((Console), (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down))
|
(Console)->TermIFace.Vtbl->ProcessKeyCallback((Console), (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down))
|
||||||
#define ConioGetLargestConsoleWindowSize(Console, pSize) \
|
#define ConioGetLargestConsoleWindowSize(Console, pSize) \
|
||||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize((Console), (pSize))
|
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize((Console), (pSize))
|
||||||
#define ConioGetConsoleWindowHandle(Console) \
|
#define ConioGetConsoleWindowHandle(Console) \
|
||||||
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle((Console))
|
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle(Console)
|
||||||
#define ConioRefreshInternalInfo(Console) \
|
#define ConioRefreshInternalInfo(Console) \
|
||||||
(Console)->TermIFace.Vtbl->RefreshInternalInfo((Console))
|
(Console)->TermIFace.Vtbl->RefreshInternalInfo(Console)
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -30,7 +30,7 @@ do { \
|
||||||
((Rect)->Left) = left; \
|
((Rect)->Left) = left; \
|
||||||
((Rect)->Bottom) = bottom; \
|
((Rect)->Bottom) = bottom; \
|
||||||
((Rect)->Right) = right; \
|
((Rect)->Right) = right; \
|
||||||
} while(0)
|
} while (0)
|
||||||
|
|
||||||
#define ConioIsRectEmpty(Rect) \
|
#define ConioIsRectEmpty(Rect) \
|
||||||
(((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
|
(((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
|
||||||
|
@ -401,6 +401,119 @@ ConioMoveRegion(PCONSOLE_SCREEN_BUFFER ScreenBuffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS FASTCALL
|
||||||
|
ConioResizeBuffer(PCONSOLE Console,
|
||||||
|
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
|
||||||
|
COORD Size)
|
||||||
|
{
|
||||||
|
BYTE * Buffer;
|
||||||
|
DWORD Offset = 0;
|
||||||
|
BYTE * OldPtr;
|
||||||
|
USHORT CurrentY;
|
||||||
|
BYTE * OldBuffer;
|
||||||
|
#ifdef HAVE_WMEMSET
|
||||||
|
USHORT value = MAKEWORD(' ', ScreenBuffer->ScreenDefaultAttrib);
|
||||||
|
#else
|
||||||
|
DWORD i;
|
||||||
|
#endif
|
||||||
|
DWORD diff;
|
||||||
|
|
||||||
|
/* Buffer size is not allowed to be smaller than window size */
|
||||||
|
if (Size.X < Console->ConsoleSize.X || Size.Y < Console->ConsoleSize.Y)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (Size.X == ScreenBuffer->ScreenBufferSize.X && Size.Y == ScreenBuffer->ScreenBufferSize.Y)
|
||||||
|
{
|
||||||
|
// FIXME: Trigger a buffer resize event ??
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ConioIsBufferResizeSupported(Console)) return STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
Buffer = RtlAllocateHeap(ConSrvHeap, 0, Size.X * Size.Y * 2);
|
||||||
|
if (!Buffer) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->ScreenBufferSize.X, ScreenBuffer->ScreenBufferSize.Y, Size.X, Size.Y);
|
||||||
|
OldBuffer = ScreenBuffer->Buffer;
|
||||||
|
|
||||||
|
for (CurrentY = 0; CurrentY < ScreenBuffer->ScreenBufferSize.Y && CurrentY < Size.Y; CurrentY++)
|
||||||
|
{
|
||||||
|
OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY);
|
||||||
|
if (Size.X <= ScreenBuffer->ScreenBufferSize.X)
|
||||||
|
{
|
||||||
|
/* reduce size */
|
||||||
|
RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2);
|
||||||
|
Offset += (Size.X * 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* enlarge size */
|
||||||
|
RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->ScreenBufferSize.X * 2);
|
||||||
|
Offset += (ScreenBuffer->ScreenBufferSize.X * 2);
|
||||||
|
|
||||||
|
diff = Size.X - ScreenBuffer->ScreenBufferSize.X;
|
||||||
|
/* 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++] = ScreenBuffer->ScreenDefaultAttrib;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Size.Y > ScreenBuffer->ScreenBufferSize.Y)
|
||||||
|
{
|
||||||
|
diff = Size.X * (Size.Y - ScreenBuffer->ScreenBufferSize.Y);
|
||||||
|
#ifdef HAVE_WMEMSET
|
||||||
|
wmemset((PWCHAR)&Buffer[Offset], value, diff);
|
||||||
|
#else
|
||||||
|
for (i = 0; i < diff; i++)
|
||||||
|
{
|
||||||
|
Buffer[Offset++] = ' ';
|
||||||
|
Buffer[Offset++] = ScreenBuffer->ScreenDefaultAttrib;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)InterlockedExchangePointer((PVOID volatile*)&ScreenBuffer->Buffer, Buffer);
|
||||||
|
RtlFreeHeap(ConSrvHeap, 0, OldBuffer);
|
||||||
|
ScreenBuffer->ScreenBufferSize = Size;
|
||||||
|
ScreenBuffer->VirtualY = 0;
|
||||||
|
|
||||||
|
/* Ensure cursor and window are within buffer */
|
||||||
|
if (ScreenBuffer->CursorPosition.X >= Size.X)
|
||||||
|
ScreenBuffer->CursorPosition.X = Size.X - 1;
|
||||||
|
if (ScreenBuffer->CursorPosition.Y >= Size.Y)
|
||||||
|
ScreenBuffer->CursorPosition.Y = Size.Y - 1;
|
||||||
|
if (ScreenBuffer->ShowX > Size.X - Console->ConsoleSize.X)
|
||||||
|
ScreenBuffer->ShowX = Size.X - Console->ConsoleSize.X;
|
||||||
|
if (ScreenBuffer->ShowY > Size.Y - Console->ConsoleSize.Y)
|
||||||
|
ScreenBuffer->ShowY = Size.Y - Console->ConsoleSize.Y;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trigger a buffer resize event
|
||||||
|
*/
|
||||||
|
if (Console->InputBuffer.Mode & ENABLE_WINDOW_INPUT)
|
||||||
|
{
|
||||||
|
INPUT_RECORD er;
|
||||||
|
|
||||||
|
er.EventType = WINDOW_BUFFER_SIZE_EVENT;
|
||||||
|
er.Event.WindowBufferSizeEvent.dwSize = ScreenBuffer->ScreenBufferSize;
|
||||||
|
|
||||||
|
ConioProcessInputEvent(Console, &er);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Should update scrollbar, but can't use anything that
|
||||||
|
* calls SendMessage or it could cause deadlock --> Use PostMessage */
|
||||||
|
// TODO: Tell the terminal to resize its scrollbars.
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
VOID WINAPI
|
VOID WINAPI
|
||||||
ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
|
ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
|
||||||
{
|
{
|
||||||
|
@ -1148,8 +1261,8 @@ CSR_API(SrvGetConsoleCursorInfo)
|
||||||
|
|
||||||
CursorInfoRequest->Info.bVisible = Buff->CursorInfo.bVisible;
|
CursorInfoRequest->Info.bVisible = Buff->CursorInfo.bVisible;
|
||||||
CursorInfoRequest->Info.dwSize = Buff->CursorInfo.dwSize;
|
CursorInfoRequest->Info.dwSize = Buff->CursorInfo.dwSize;
|
||||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1195,7 +1308,6 @@ CSR_API(SrvSetConsoleCursorInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,7 +1349,6 @@ CSR_API(SrvSetConsoleCursorPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1266,7 +1377,6 @@ CSR_API(SrvSetConsoleTextAttribute)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1374,7 +1484,6 @@ CSR_API(SrvGetConsoleScreenBufferInfo)
|
||||||
pInfo->dwMaximumWindowSize = Buff->ScreenBufferSize;
|
pInfo->dwMaximumWindowSize = Buff->ScreenBufferSize;
|
||||||
|
|
||||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1411,7 +1520,6 @@ CSR_API(SrvSetConsoleActiveScreenBuffer)
|
||||||
ConioDrawConsole(Console);
|
ConioDrawConsole(Console);
|
||||||
|
|
||||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1503,7 +1611,6 @@ CSR_API(SrvScrollConsoleScreenBuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1517,8 +1624,8 @@ CSR_API(SrvSetConsoleScreenBufferSize)
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
Status = ConioResizeBuffer(Buff->Header.Console, Buff, SetScreenBufferSizeRequest->Size);
|
Status = ConioResizeBuffer(Buff->Header.Console, Buff, SetScreenBufferSizeRequest->Size);
|
||||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
|
||||||
|
|
||||||
|
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,7 @@
|
||||||
#include "include/settings.h"
|
#include "include/settings.h"
|
||||||
|
|
||||||
#include "frontends/gui/guiterm.h"
|
#include "frontends/gui/guiterm.h"
|
||||||
|
#include "frontends/tui/tuiterm.h"
|
||||||
#ifdef TUI_CONSOLE
|
|
||||||
#include "frontends/tui/tuiterm.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "include/console.h"
|
#include "include/console.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
@ -57,13 +54,11 @@ static RTL_RESOURCE ListLock;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
#ifdef TUI_CONSOLE
|
|
||||||
static BOOL
|
static BOOL
|
||||||
DtbgIsDesktopVisible(VOID)
|
DtbgIsDesktopVisible(VOID)
|
||||||
{
|
{
|
||||||
return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
|
return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static ULONG
|
static ULONG
|
||||||
ConSrvConsoleCtrlEventTimeout(DWORD Event,
|
ConSrvConsoleCtrlEventTimeout(DWORD Event,
|
||||||
|
@ -640,13 +635,8 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
* If we are not in GUI-mode, start the text-mode terminal emulator.
|
* If we are not in GUI-mode, start the text-mode terminal emulator.
|
||||||
* If we fail, try to start the GUI-mode terminal emulator.
|
* If we fail, try to start the GUI-mode terminal emulator.
|
||||||
*/
|
*/
|
||||||
#ifdef TUI_CONSOLE
|
|
||||||
GuiMode = DtbgIsDesktopVisible();
|
GuiMode = DtbgIsDesktopVisible();
|
||||||
#else
|
|
||||||
GuiMode = TRUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TUI_CONSOLE
|
|
||||||
if (!GuiMode)
|
if (!GuiMode)
|
||||||
{
|
{
|
||||||
DPRINT1("CONSRV: Opening text-mode terminal emulator\n");
|
DPRINT1("CONSRV: Opening text-mode terminal emulator\n");
|
||||||
|
@ -660,7 +650,6 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
GuiMode = TRUE;
|
GuiMode = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to open the GUI-mode terminal emulator. Two cases are possible:
|
* Try to open the GUI-mode terminal emulator. Two cases are possible:
|
||||||
|
|
|
@ -70,7 +70,7 @@ do { \
|
||||||
ConsoleLeaderCID = ProcessData->Process->ClientId; \
|
ConsoleLeaderCID = ProcessData->Process->ClientId; \
|
||||||
SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_PID, (LONG_PTR)(ConsoleLeaderCID.UniqueProcess)); \
|
SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_PID, (LONG_PTR)(ConsoleLeaderCID.UniqueProcess)); \
|
||||||
SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_TID, (LONG_PTR)(ConsoleLeaderCID.UniqueThread )); \
|
SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_TID, (LONG_PTR)(ConsoleLeaderCID.UniqueThread )); \
|
||||||
} while(0)
|
} while (0)
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
|
||||||
static BOOL ConsInitialized = FALSE;
|
static BOOL ConsInitialized = FALSE;
|
||||||
|
@ -185,7 +185,7 @@ GuiConsoleAppendMenuItems(HMENU hMenu,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
} while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0));
|
} while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
|
@ -209,8 +209,6 @@ static VOID
|
||||||
GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord);
|
GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord);
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
GuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region);
|
GuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region);
|
||||||
static NTSTATUS WINAPI
|
|
||||||
GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size);
|
|
||||||
static VOID
|
static VOID
|
||||||
GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData);
|
GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData);
|
||||||
|
|
||||||
|
@ -510,7 +508,7 @@ GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord)
|
||||||
{
|
{
|
||||||
if ((rgn2 = CreateRectRgnIndirect(&newRect)))
|
if ((rgn2 = CreateRectRgnIndirect(&newRect)))
|
||||||
{
|
{
|
||||||
if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
|
if (CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
|
||||||
{
|
{
|
||||||
InvalidateRgn(GuiData->hWindow, rgn1, FALSE);
|
InvalidateRgn(GuiData->hWindow, rgn1, FALSE);
|
||||||
}
|
}
|
||||||
|
@ -861,7 +859,7 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
||||||
GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||||
Buff->CursorBlinkOn = !Buff->CursorBlinkOn;
|
Buff->CursorBlinkOn = !Buff->CursorBlinkOn;
|
||||||
|
|
||||||
if((GuiData->OldCursor.x != Buff->CursorPosition.X) || (GuiData->OldCursor.y != Buff->CursorPosition.Y))
|
if ((GuiData->OldCursor.x != Buff->CursorPosition.X) || (GuiData->OldCursor.y != Buff->CursorPosition.Y))
|
||||||
{
|
{
|
||||||
SCROLLINFO xScroll;
|
SCROLLINFO xScroll;
|
||||||
int OldScrollX = -1, OldScrollY = -1;
|
int OldScrollX = -1, OldScrollY = -1;
|
||||||
|
@ -870,16 +868,16 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
||||||
xScroll.cbSize = sizeof(SCROLLINFO);
|
xScroll.cbSize = sizeof(SCROLLINFO);
|
||||||
xScroll.fMask = SIF_POS;
|
xScroll.fMask = SIF_POS;
|
||||||
// Capture the original position of the scroll bars and save them.
|
// Capture the original position of the scroll bars and save them.
|
||||||
if(GetScrollInfo(GuiData->hWindow, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos;
|
if (GetScrollInfo(GuiData->hWindow, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos;
|
||||||
if(GetScrollInfo(GuiData->hWindow, SB_VERT, &xScroll))OldScrollY = xScroll.nPos;
|
if (GetScrollInfo(GuiData->hWindow, SB_VERT, &xScroll))OldScrollY = xScroll.nPos;
|
||||||
|
|
||||||
// If we successfully got the info for the horizontal scrollbar
|
// If we successfully got the info for the horizontal scrollbar
|
||||||
if(OldScrollX >= 0)
|
if (OldScrollX >= 0)
|
||||||
{
|
{
|
||||||
if((Buff->CursorPosition.X < Buff->ShowX)||(Buff->CursorPosition.X >= (Buff->ShowX + Console->ConsoleSize.X)))
|
if ((Buff->CursorPosition.X < Buff->ShowX)||(Buff->CursorPosition.X >= (Buff->ShowX + Console->ConsoleSize.X)))
|
||||||
{
|
{
|
||||||
// Handle the horizontal scroll bar
|
// Handle the horizontal scroll bar
|
||||||
if(Buff->CursorPosition.X >= Console->ConsoleSize.X) NewScrollX = Buff->CursorPosition.X - Console->ConsoleSize.X + 1;
|
if (Buff->CursorPosition.X >= Console->ConsoleSize.X) NewScrollX = Buff->CursorPosition.X - Console->ConsoleSize.X + 1;
|
||||||
else NewScrollX = 0;
|
else NewScrollX = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -888,12 +886,12 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we successfully got the info for the vertical scrollbar
|
// If we successfully got the info for the vertical scrollbar
|
||||||
if(OldScrollY >= 0)
|
if (OldScrollY >= 0)
|
||||||
{
|
{
|
||||||
if((Buff->CursorPosition.Y < Buff->ShowY) || (Buff->CursorPosition.Y >= (Buff->ShowY + Console->ConsoleSize.Y)))
|
if ((Buff->CursorPosition.Y < Buff->ShowY) || (Buff->CursorPosition.Y >= (Buff->ShowY + Console->ConsoleSize.Y)))
|
||||||
{
|
{
|
||||||
// Handle the vertical scroll bar
|
// Handle the vertical scroll bar
|
||||||
if(Buff->CursorPosition.Y >= Console->ConsoleSize.Y) NewScrollY = Buff->CursorPosition.Y - Console->ConsoleSize.Y + 1;
|
if (Buff->CursorPosition.Y >= Console->ConsoleSize.Y) NewScrollY = Buff->CursorPosition.Y - Console->ConsoleSize.Y + 1;
|
||||||
else NewScrollY = 0;
|
else NewScrollY = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -906,7 +904,7 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
||||||
// NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar
|
// NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar
|
||||||
// was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling)
|
// was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling)
|
||||||
// and their associated scrollbar is left alone.
|
// and their associated scrollbar is left alone.
|
||||||
if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY))
|
if ((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY))
|
||||||
{
|
{
|
||||||
Buff->ShowX = NewScrollX;
|
Buff->ShowX = NewScrollX;
|
||||||
Buff->ShowY = NewScrollY;
|
Buff->ShowY = NewScrollY;
|
||||||
|
@ -918,12 +916,12 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
SW_INVALIDATE);
|
SW_INVALIDATE);
|
||||||
if(NewScrollX >= 0)
|
if (NewScrollX >= 0)
|
||||||
{
|
{
|
||||||
xScroll.nPos = NewScrollX;
|
xScroll.nPos = NewScrollX;
|
||||||
SetScrollInfo(GuiData->hWindow, SB_HORZ, &xScroll, TRUE);
|
SetScrollInfo(GuiData->hWindow, SB_HORZ, &xScroll, TRUE);
|
||||||
}
|
}
|
||||||
if(NewScrollY >= 0)
|
if (NewScrollY >= 0)
|
||||||
{
|
{
|
||||||
xScroll.nPos = NewScrollY;
|
xScroll.nPos = NewScrollY;
|
||||||
SetScrollInfo(GuiData->hWindow, SB_VERT, &xScroll, TRUE);
|
SetScrollInfo(GuiData->hWindow, SB_VERT, &xScroll, TRUE);
|
||||||
|
@ -1338,8 +1336,8 @@ GuiConsoleGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData, PMINMAXINFO minMaxInfo)
|
||||||
windx = (Console->ActiveBuffer->ScreenBufferSize.X) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
|
windx = (Console->ActiveBuffer->ScreenBufferSize.X) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
|
||||||
windy = (Console->ActiveBuffer->ScreenBufferSize.Y) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
|
windy = (Console->ActiveBuffer->ScreenBufferSize.Y) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
|
||||||
|
|
||||||
if(Console->ConsoleSize.X < Console->ActiveBuffer->ScreenBufferSize.X) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar
|
if (Console->ConsoleSize.X < Console->ActiveBuffer->ScreenBufferSize.X) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar
|
||||||
if(Console->ConsoleSize.Y < Console->ActiveBuffer->ScreenBufferSize.Y) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar
|
if (Console->ConsoleSize.Y < Console->ActiveBuffer->ScreenBufferSize.Y) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar
|
||||||
|
|
||||||
minMaxInfo->ptMaxTrackSize.x = windx;
|
minMaxInfo->ptMaxTrackSize.x = windx;
|
||||||
minMaxInfo->ptMaxTrackSize.y = windy;
|
minMaxInfo->ptMaxTrackSize.y = windy;
|
||||||
|
@ -1366,29 +1364,29 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
|
||||||
windy = HIWORD(lParam);
|
windy = HIWORD(lParam);
|
||||||
|
|
||||||
// Compensate for existing scroll bars (because lParam values do not accommodate scroll bar)
|
// Compensate for existing scroll bars (because lParam values do not accommodate scroll bar)
|
||||||
if(Console->ConsoleSize.X < Buff->ScreenBufferSize.X) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar
|
if (Console->ConsoleSize.X < Buff->ScreenBufferSize.X) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar
|
||||||
if(Console->ConsoleSize.Y < Buff->ScreenBufferSize.Y) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar
|
if (Console->ConsoleSize.Y < Buff->ScreenBufferSize.Y) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar
|
||||||
|
|
||||||
charx = windx / GuiData->CharWidth;
|
charx = windx / GuiData->CharWidth;
|
||||||
chary = windy / GuiData->CharHeight;
|
chary = windy / GuiData->CharHeight;
|
||||||
|
|
||||||
// Character alignment (round size up or down)
|
// Character alignment (round size up or down)
|
||||||
if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
|
if ((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
|
||||||
if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
|
if ((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
|
||||||
|
|
||||||
// Compensate for added scroll bars in new window
|
// Compensate for added scroll bars in new window
|
||||||
if(charx < Buff->ScreenBufferSize.X)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar
|
if (charx < Buff->ScreenBufferSize.X)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar
|
||||||
if(chary < Buff->ScreenBufferSize.Y)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar
|
if (chary < Buff->ScreenBufferSize.Y)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar
|
||||||
|
|
||||||
charx = windx / GuiData->CharWidth;
|
charx = windx / GuiData->CharWidth;
|
||||||
chary = windy / GuiData->CharHeight;
|
chary = windy / GuiData->CharHeight;
|
||||||
|
|
||||||
// Character alignment (round size up or down)
|
// Character alignment (round size up or down)
|
||||||
if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
|
if ((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
|
||||||
if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
|
if ((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
|
||||||
|
|
||||||
// Resize window
|
// Resize window
|
||||||
if((charx != Console->ConsoleSize.X) || (chary != Console->ConsoleSize.Y))
|
if ((charx != Console->ConsoleSize.X) || (chary != Console->ConsoleSize.Y))
|
||||||
{
|
{
|
||||||
Console->ConsoleSize.X = (charx <= Buff->ScreenBufferSize.X) ? charx : Buff->ScreenBufferSize.X;
|
Console->ConsoleSize.X = (charx <= Buff->ScreenBufferSize.X) ? charx : Buff->ScreenBufferSize.X;
|
||||||
Console->ConsoleSize.Y = (chary <= Buff->ScreenBufferSize.Y) ? chary : Buff->ScreenBufferSize.Y;
|
Console->ConsoleSize.Y = (chary <= Buff->ScreenBufferSize.Y) ? chary : Buff->ScreenBufferSize.Y;
|
||||||
|
@ -1397,8 +1395,8 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
|
||||||
GuiConsoleResizeWindow(GuiData);
|
GuiConsoleResizeWindow(GuiData);
|
||||||
|
|
||||||
// Adjust the start of the visible area if we are attempting to show nonexistent areas
|
// Adjust the start of the visible area if we are attempting to show nonexistent areas
|
||||||
if((Buff->ScreenBufferSize.X - Buff->ShowX) < Console->ConsoleSize.X) Buff->ShowX = Buff->ScreenBufferSize.X - Console->ConsoleSize.X;
|
if ((Buff->ScreenBufferSize.X - Buff->ShowX) < Console->ConsoleSize.X) Buff->ShowX = Buff->ScreenBufferSize.X - Console->ConsoleSize.X;
|
||||||
if((Buff->ScreenBufferSize.Y - Buff->ShowY) < Console->ConsoleSize.Y) Buff->ShowY = Buff->ScreenBufferSize.Y - Console->ConsoleSize.Y;
|
if ((Buff->ScreenBufferSize.Y - Buff->ShowY) < Console->ConsoleSize.Y) Buff->ShowY = Buff->ScreenBufferSize.Y - Console->ConsoleSize.Y;
|
||||||
InvalidateRect(GuiData->hWindow, NULL, TRUE);
|
InvalidateRect(GuiData->hWindow, NULL, TRUE);
|
||||||
|
|
||||||
GuiData->WindowSizeLock = FALSE;
|
GuiData->WindowSizeLock = FALSE;
|
||||||
|
@ -1809,7 +1807,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
* So first empty the message queue.
|
* So first empty the message queue.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
|
while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
|
||||||
{
|
{
|
||||||
TranslateMessage(&Msg);
|
TranslateMessage(&Msg);
|
||||||
DispatchMessageW(&Msg);
|
DispatchMessageW(&Msg);
|
||||||
|
@ -1873,7 +1871,7 @@ GuiConsoleGuiThread(PVOID Data)
|
||||||
|
|
||||||
SetEvent(*GraphicsStartupEvent);
|
SetEvent(*GraphicsStartupEvent);
|
||||||
|
|
||||||
while(GetMessageW(&msg, NULL, 0, 0))
|
while (GetMessageW(&msg, NULL, 0, 0))
|
||||||
{
|
{
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessageW(&msg);
|
DispatchMessageW(&msg);
|
||||||
|
@ -2122,114 +2120,10 @@ GuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS WINAPI
|
static BOOL WINAPI
|
||||||
GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size)
|
GuiIsBufferResizeSupported(PCONSOLE Console)
|
||||||
{
|
{
|
||||||
BYTE * Buffer;
|
return TRUE;
|
||||||
DWORD Offset = 0;
|
|
||||||
BYTE * OldPtr;
|
|
||||||
USHORT CurrentY;
|
|
||||||
BYTE * OldBuffer;
|
|
||||||
#ifdef HAVE_WMEMSET
|
|
||||||
USHORT value = MAKEWORD(' ', ScreenBuffer->ScreenDefaultAttrib);
|
|
||||||
#else
|
|
||||||
DWORD i;
|
|
||||||
#endif
|
|
||||||
DWORD diff;
|
|
||||||
|
|
||||||
/* Buffer size is not allowed to be smaller than window size */
|
|
||||||
if (Size.X < Console->ConsoleSize.X || Size.Y < Console->ConsoleSize.Y)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (Size.X == ScreenBuffer->ScreenBufferSize.X && Size.Y == ScreenBuffer->ScreenBufferSize.Y)
|
|
||||||
{
|
|
||||||
// FIXME: Trigger a buffer resize event ??
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer = RtlAllocateHeap(ConSrvHeap, 0, Size.X * Size.Y * 2);
|
|
||||||
if (!Buffer)
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
|
|
||||||
DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->ScreenBufferSize.X, ScreenBuffer->ScreenBufferSize.Y, Size.X, Size.Y);
|
|
||||||
OldBuffer = ScreenBuffer->Buffer;
|
|
||||||
|
|
||||||
for (CurrentY = 0; CurrentY < ScreenBuffer->ScreenBufferSize.Y && CurrentY < Size.Y; CurrentY++)
|
|
||||||
{
|
|
||||||
OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY);
|
|
||||||
if (Size.X <= ScreenBuffer->ScreenBufferSize.X)
|
|
||||||
{
|
|
||||||
/* reduce size */
|
|
||||||
RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2);
|
|
||||||
Offset += (Size.X * 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* enlarge size */
|
|
||||||
RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->ScreenBufferSize.X * 2);
|
|
||||||
Offset += (ScreenBuffer->ScreenBufferSize.X * 2);
|
|
||||||
|
|
||||||
diff = Size.X - ScreenBuffer->ScreenBufferSize.X;
|
|
||||||
/* 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++] = ScreenBuffer->ScreenDefaultAttrib;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Size.Y > ScreenBuffer->ScreenBufferSize.Y)
|
|
||||||
{
|
|
||||||
diff = Size.X * (Size.Y - ScreenBuffer->ScreenBufferSize.Y);
|
|
||||||
#ifdef HAVE_WMEMSET
|
|
||||||
wmemset((PWCHAR)&Buffer[Offset], value, diff);
|
|
||||||
#else
|
|
||||||
for (i = 0; i < diff; i++)
|
|
||||||
{
|
|
||||||
Buffer[Offset++] = ' ';
|
|
||||||
Buffer[Offset++] = ScreenBuffer->ScreenDefaultAttrib;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)InterlockedExchangePointer((PVOID volatile*)&ScreenBuffer->Buffer, Buffer);
|
|
||||||
RtlFreeHeap(ConSrvHeap, 0, OldBuffer);
|
|
||||||
ScreenBuffer->ScreenBufferSize = Size;
|
|
||||||
ScreenBuffer->VirtualY = 0;
|
|
||||||
|
|
||||||
/* Ensure cursor and window are within buffer */
|
|
||||||
if (ScreenBuffer->CursorPosition.X >= Size.X)
|
|
||||||
ScreenBuffer->CursorPosition.X = Size.X - 1;
|
|
||||||
if (ScreenBuffer->CursorPosition.Y >= Size.Y)
|
|
||||||
ScreenBuffer->CursorPosition.Y = Size.Y - 1;
|
|
||||||
if (ScreenBuffer->ShowX > Size.X - Console->ConsoleSize.X)
|
|
||||||
ScreenBuffer->ShowX = Size.X - Console->ConsoleSize.X;
|
|
||||||
if (ScreenBuffer->ShowY > Size.Y - Console->ConsoleSize.Y)
|
|
||||||
ScreenBuffer->ShowY = Size.Y - Console->ConsoleSize.Y;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Trigger a buffer resize event
|
|
||||||
*/
|
|
||||||
if (Console->InputBuffer.Mode & ENABLE_WINDOW_INPUT)
|
|
||||||
{
|
|
||||||
INPUT_RECORD er;
|
|
||||||
|
|
||||||
er.EventType = WINDOW_BUFFER_SIZE_EVENT;
|
|
||||||
er.Event.WindowBufferSizeEvent.dwSize = ScreenBuffer->ScreenBufferSize;
|
|
||||||
|
|
||||||
ConioProcessInputEvent(Console, &er);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Should update scrollbar, but can't use anything that
|
|
||||||
* calls SendMessage or it could cause deadlock --> Use PostMessage */
|
|
||||||
// TODO: Tell the terminal to resize its scrollbars.
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
|
@ -2365,7 +2259,7 @@ static FRONTEND_VTBL GuiVtbl =
|
||||||
GuiSetCursorInfo,
|
GuiSetCursorInfo,
|
||||||
GuiSetScreenInfo,
|
GuiSetScreenInfo,
|
||||||
GuiUpdateScreenInfo,
|
GuiUpdateScreenInfo,
|
||||||
GuiResizeBuffer,
|
GuiIsBufferResizeSupported,
|
||||||
GuiResizeTerminal,
|
GuiResizeTerminal,
|
||||||
GuiProcessKeyCallback,
|
GuiProcessKeyCallback,
|
||||||
GuiRefreshInternalInfo,
|
GuiRefreshInternalInfo,
|
||||||
|
|
|
@ -2,18 +2,18 @@
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS Console Server DLL
|
* PROJECT: ReactOS Console Server DLL
|
||||||
* FILE: win32ss/user/consrv/frontends/tui/tuiterm.c
|
* FILE: win32ss/user/consrv/frontends/tui/tuiterm.c
|
||||||
* PURPOSE: TUI Terminal Front-End
|
* PURPOSE: TUI Terminal Front-End - Virtual Consoles...
|
||||||
* PROGRAMMERS: David Welch
|
* PROGRAMMERS: David Welch
|
||||||
* Gé van Geldorp
|
* Gé van Geldorp
|
||||||
* Jeffrey Morlan
|
* Jeffrey Morlan
|
||||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef TUI_CONSOLE
|
|
||||||
|
|
||||||
#include "consrv.h"
|
#include "consrv.h"
|
||||||
#include "settings.h"
|
#include "include/conio.h"
|
||||||
#include "tuiconsole.h"
|
// #include "include/console.h"
|
||||||
|
#include "include/settings.h"
|
||||||
|
#include "tuiterm.h"
|
||||||
#include <drivers/blue/ntddblue.h>
|
#include <drivers/blue/ntddblue.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
@ -22,24 +22,35 @@
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
#define GetNextConsole(Console) \
|
||||||
|
CONTAINING_RECORD(Console->Entry.Flink, TUI_CONSOLE_DATA, Entry)
|
||||||
|
|
||||||
|
#define GetPrevConsole(Console) \
|
||||||
|
CONTAINING_RECORD(Console->Entry.Blink, TUI_CONSOLE_DATA, Entry)
|
||||||
|
|
||||||
|
|
||||||
/* TUI Console Window Class name */
|
/* TUI Console Window Class name */
|
||||||
#define TUI_CONSOLE_WINDOW_CLASS L"TuiConsoleWindowClass"
|
#define TUI_CONSOLE_WINDOW_CLASS L"TuiConsoleWindowClass"
|
||||||
|
|
||||||
typedef struct _TUI_CONSOLE_DATA
|
typedef struct _TUI_CONSOLE_DATA
|
||||||
{
|
{
|
||||||
CRITICAL_SECTION Lock;
|
CRITICAL_SECTION Lock;
|
||||||
|
LIST_ENTRY Entry; /* Entry in the list of virtual consoles */
|
||||||
// HANDLE hTuiInitEvent;
|
// HANDLE hTuiInitEvent;
|
||||||
|
|
||||||
HWND hWindow;
|
HWND hWindow; /* Handle to the console's window (used for the window's procedure */
|
||||||
|
|
||||||
PCONSOLE Console;
|
PCONSOLE Console; /* Pointer to the owned console */
|
||||||
// TUI_CONSOLE_INFO TuiInfo;
|
// TUI_CONSOLE_INFO TuiInfo; /* TUI terminal settings */
|
||||||
} TUI_CONSOLE_DATA, *PTUI_CONSOLE_DATA;
|
} TUI_CONSOLE_DATA, *PTUI_CONSOLE_DATA;
|
||||||
|
|
||||||
CRITICAL_SECTION ActiveConsoleLock;
|
/* List of the maintained virtual consoles and its lock */
|
||||||
|
static LIST_ENTRY VirtConsList;
|
||||||
|
static PTUI_CONSOLE_DATA ActiveConsole; /* The active console on screen */
|
||||||
|
static CRITICAL_SECTION ActiveVirtConsLock;
|
||||||
|
|
||||||
static COORD PhysicalConsoleSize;
|
static COORD PhysicalConsoleSize;
|
||||||
static HANDLE ConsoleDeviceHandle;
|
static HANDLE ConsoleDeviceHandle;
|
||||||
static PCONSOLE ActiveConsole;
|
|
||||||
|
|
||||||
static BOOL ConsInitialized = FALSE;
|
static BOOL ConsInitialized = FALSE;
|
||||||
|
|
||||||
|
@ -153,24 +164,10 @@ done:
|
||||||
/**\
|
/**\
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
|
|
||||||
static LRESULT CALLBACK
|
|
||||||
TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
if (msg == WM_ACTIVATE)
|
|
||||||
{
|
|
||||||
if (LOWORD(wParam) != WA_INACTIVE)
|
|
||||||
{
|
|
||||||
SetFocus(hWnd);
|
|
||||||
ConioDrawConsole(ActiveConsole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DefWindowProcW(hWnd, msg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL FASTCALL
|
static BOOL FASTCALL
|
||||||
TuiSwapConsole(INT Next)
|
TuiSwapConsole(INT Next)
|
||||||
{
|
{
|
||||||
static PCONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */
|
static PTUI_CONSOLE_DATA SwapConsole = NULL; /* Console we are thinking about swapping with */
|
||||||
DWORD BytesReturned;
|
DWORD BytesReturned;
|
||||||
ANSI_STRING Title;
|
ANSI_STRING Title;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
|
@ -178,28 +175,26 @@ TuiSwapConsole(INT Next)
|
||||||
|
|
||||||
if (0 != Next)
|
if (0 != Next)
|
||||||
{
|
{
|
||||||
/* alt-tab, swap consoles */
|
/*
|
||||||
/* move SwapConsole to next console, and print its title */
|
* Alt-Tab, swap consoles.
|
||||||
EnterCriticalSection(&ActiveConsoleLock);
|
* move SwapConsole to next console, and print its title.
|
||||||
if (!SwapConsole)
|
*/
|
||||||
{
|
EnterCriticalSection(&ActiveVirtConsLock);
|
||||||
SwapConsole = ActiveConsole;
|
if (!SwapConsole) SwapConsole = ActiveConsole;
|
||||||
}
|
|
||||||
|
|
||||||
SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev);
|
SwapConsole = (0 < Next ? GetNextConsole(SwapConsole) : GetPrevConsole(SwapConsole));
|
||||||
Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title);
|
Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Console->Title);
|
||||||
Title.Length = 0;
|
Title.Length = 0;
|
||||||
Buffer = RtlAllocateHeap(ConSrvHeap,
|
Buffer = RtlAllocateHeap(ConSrvHeap, 0,
|
||||||
0,
|
sizeof(COORD) + Title.MaximumLength);
|
||||||
sizeof(COORD) + Title.MaximumLength);
|
pos = (PCOORD)Buffer;
|
||||||
pos = (PCOORD )Buffer;
|
Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof(COORD));
|
||||||
Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof( COORD ));
|
|
||||||
|
|
||||||
RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE);
|
RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Console->Title, FALSE);
|
||||||
pos->Y = PhysicalConsoleSize.Y / 2;
|
|
||||||
pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
|
pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
|
||||||
/* redraw the console to clear off old title */
|
pos->Y = PhysicalConsoleSize.Y / 2;
|
||||||
ConioDrawConsole(ActiveConsole);
|
/* Redraw the console to clear off old title */
|
||||||
|
ConioDrawConsole(ActiveConsole->Console);
|
||||||
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
|
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
|
||||||
NULL, 0, Buffer, sizeof(COORD) + Title.Length,
|
NULL, 0, Buffer, sizeof(COORD) + Title.Length,
|
||||||
&BytesReturned, NULL))
|
&BytesReturned, NULL))
|
||||||
|
@ -207,28 +202,28 @@ TuiSwapConsole(INT Next)
|
||||||
DPRINT1( "Error writing to console\n" );
|
DPRINT1( "Error writing to console\n" );
|
||||||
}
|
}
|
||||||
RtlFreeHeap(ConSrvHeap, 0, Buffer);
|
RtlFreeHeap(ConSrvHeap, 0, Buffer);
|
||||||
LeaveCriticalSection(&ActiveConsoleLock);
|
LeaveCriticalSection(&ActiveVirtConsLock);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (NULL != SwapConsole)
|
else if (NULL != SwapConsole)
|
||||||
{
|
{
|
||||||
EnterCriticalSection(&ActiveConsoleLock);
|
EnterCriticalSection(&ActiveVirtConsLock);
|
||||||
if (SwapConsole != ActiveConsole)
|
if (SwapConsole != ActiveConsole)
|
||||||
{
|
{
|
||||||
/* first remove swapconsole from the list */
|
/* First remove swapconsole from the list */
|
||||||
SwapConsole->Prev->Next = SwapConsole->Next;
|
SwapConsole->Entry.Blink->Flink = SwapConsole->Entry.Flink;
|
||||||
SwapConsole->Next->Prev = SwapConsole->Prev;
|
SwapConsole->Entry.Flink->Blink = SwapConsole->Entry.Blink;
|
||||||
/* now insert before activeconsole */
|
/* Now insert before activeconsole */
|
||||||
SwapConsole->Next = ActiveConsole;
|
SwapConsole->Entry.Flink = &ActiveConsole->Entry;
|
||||||
SwapConsole->Prev = ActiveConsole->Prev;
|
SwapConsole->Entry.Blink = ActiveConsole->Entry.Blink;
|
||||||
ActiveConsole->Prev->Next = SwapConsole;
|
ActiveConsole->Entry.Blink->Flink = &SwapConsole->Entry;
|
||||||
ActiveConsole->Prev = SwapConsole;
|
ActiveConsole->Entry.Blink = &SwapConsole->Entry;
|
||||||
}
|
}
|
||||||
ActiveConsole = SwapConsole;
|
ActiveConsole = SwapConsole;
|
||||||
SwapConsole = NULL;
|
SwapConsole = NULL;
|
||||||
ConioDrawConsole(ActiveConsole);
|
ConioDrawConsole(ActiveConsole->Console);
|
||||||
LeaveCriticalSection(&ActiveConsoleLock);
|
LeaveCriticalSection(&ActiveVirtConsLock);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -237,92 +232,6 @@ TuiSwapConsole(INT Next)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
|
||||||
TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down)
|
|
||||||
{
|
|
||||||
if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) &&
|
|
||||||
VK_TAB == VirtualKeyCode)
|
|
||||||
{
|
|
||||||
if (Down)
|
|
||||||
{
|
|
||||||
TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else if (VK_MENU == VirtualKeyCode && !Down)
|
|
||||||
{
|
|
||||||
return TuiSwapConsole(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL FASTCALL
|
|
||||||
TuiInit(DWORD OemCP)
|
|
||||||
{
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
|
|
||||||
DWORD BytesReturned;
|
|
||||||
WNDCLASSEXW wc;
|
|
||||||
ATOM ConsoleClassAtom;
|
|
||||||
USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
|
|
||||||
|
|
||||||
ScmLoadDriver(L"Blue");
|
|
||||||
|
|
||||||
ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL,
|
|
||||||
OPEN_EXISTING, 0, NULL);
|
|
||||||
if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle)
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to open BlueScreen.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
|
|
||||||
&OemCP, sizeof(OemCP), NULL, 0,
|
|
||||||
&BytesReturned, NULL))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to load the font for codepage %d\n", OemCP);
|
|
||||||
/* Let's suppose the font is good enough to continue */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
|
|
||||||
&TextAttribute, sizeof(TextAttribute), NULL, 0,
|
|
||||||
&BytesReturned, NULL))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to set text attribute\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ActiveConsole = NULL;
|
|
||||||
InitializeCriticalSection(&ActiveConsoleLock);
|
|
||||||
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
|
|
||||||
NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to get console info\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
PhysicalConsoleSize = ScrInfo.dwSize;
|
|
||||||
|
|
||||||
RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
|
|
||||||
wc.cbSize = sizeof(WNDCLASSEXW);
|
|
||||||
wc.lpszClassName = TUI_CONSOLE_WINDOW_CLASS;
|
|
||||||
wc.lpfnWndProc = TuiConsoleWndProc;
|
|
||||||
wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC;
|
|
||||||
wc.hInstance = ConSrvDllInstance;
|
|
||||||
|
|
||||||
ConsoleClassAtom = RegisterClassExW(&wc);
|
|
||||||
if (ConsoleClassAtom == 0)
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to register TUI console wndproc\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NtUserConsoleControl(TuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM));
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID FASTCALL
|
static VOID FASTCALL
|
||||||
TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
|
TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
|
||||||
{
|
{
|
||||||
|
@ -346,6 +255,211 @@ TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LRESULT CALLBACK
|
||||||
|
TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
if (msg == WM_ACTIVATE)
|
||||||
|
{
|
||||||
|
if (LOWORD(wParam) != WA_INACTIVE)
|
||||||
|
{
|
||||||
|
SetFocus(hWnd);
|
||||||
|
ConioDrawConsole(ActiveConsole->Console);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI
|
||||||
|
TuiConsoleThread(PVOID Data)
|
||||||
|
{
|
||||||
|
PTUI_CONSOLE_DATA TuiData = (PTUI_CONSOLE_DATA)Data;
|
||||||
|
PCONSOLE Console = TuiData->Console;
|
||||||
|
HWND NewWindow;
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
NewWindow = CreateWindowW(TUI_CONSOLE_WINDOW_CLASS,
|
||||||
|
Console->Title.Buffer,
|
||||||
|
0,
|
||||||
|
-32000, -32000, 0, 0,
|
||||||
|
NULL, NULL,
|
||||||
|
ConSrvDllInstance,
|
||||||
|
(PVOID)Console);
|
||||||
|
if (NULL == NewWindow)
|
||||||
|
{
|
||||||
|
DPRINT1("CONSRV: Unable to create console window\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TuiData->hWindow = NewWindow;
|
||||||
|
|
||||||
|
SetForegroundWindow(TuiData->hWindow);
|
||||||
|
NtUserConsoleControl(ConsoleAcquireDisplayOwnership, NULL, 0);
|
||||||
|
|
||||||
|
while (GetMessageW(&msg, NULL, 0, 0))
|
||||||
|
{
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessageW(&msg);
|
||||||
|
|
||||||
|
if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
|
||||||
|
msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN ||
|
||||||
|
msg.message == WM_KEYUP || msg.message == WM_SYSKEYUP)
|
||||||
|
{
|
||||||
|
ConioProcessKey(Console, &msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
TuiInit(DWORD OemCP)
|
||||||
|
{
|
||||||
|
BOOL Ret = FALSE;
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
|
||||||
|
DWORD BytesReturned;
|
||||||
|
WNDCLASSEXW wc;
|
||||||
|
ATOM ConsoleClassAtom;
|
||||||
|
USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
|
||||||
|
|
||||||
|
/* Exit if we were already initialized */
|
||||||
|
if (ConsInitialized) return TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the TUI front-end:
|
||||||
|
* - load the console driver,
|
||||||
|
* - set default screen attributes,
|
||||||
|
* - grab the console size.
|
||||||
|
*/
|
||||||
|
ScmLoadDriver(L"Blue");
|
||||||
|
|
||||||
|
ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen",
|
||||||
|
FILE_ALL_ACCESS,
|
||||||
|
0, NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0, NULL);
|
||||||
|
if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to open BlueScreen.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
|
||||||
|
&OemCP, sizeof(OemCP), NULL, 0,
|
||||||
|
&BytesReturned, NULL))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to load the font for codepage %d\n", OemCP);
|
||||||
|
/* Let's suppose the font is good enough to continue */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
|
||||||
|
&TextAttribute, sizeof(TextAttribute), NULL, 0,
|
||||||
|
&BytesReturned, NULL))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to set text attribute\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ActiveConsole = NULL;
|
||||||
|
InitializeListHead(&VirtConsList);
|
||||||
|
InitializeCriticalSection(&ActiveVirtConsLock);
|
||||||
|
|
||||||
|
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
|
||||||
|
NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to get console info\n");
|
||||||
|
Ret = FALSE;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
PhysicalConsoleSize = ScrInfo.dwSize;
|
||||||
|
|
||||||
|
/* Register the TUI notification window class */
|
||||||
|
RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
|
||||||
|
wc.cbSize = sizeof(WNDCLASSEXW);
|
||||||
|
wc.lpszClassName = TUI_CONSOLE_WINDOW_CLASS;
|
||||||
|
wc.lpfnWndProc = TuiConsoleWndProc;
|
||||||
|
wc.cbWndExtra = 0;
|
||||||
|
wc.hInstance = ConSrvDllInstance;
|
||||||
|
|
||||||
|
ConsoleClassAtom = RegisterClassExW(&wc);
|
||||||
|
if (ConsoleClassAtom == 0)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to register TUI console wndproc\n");
|
||||||
|
Ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Ret = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
if (Ret == FALSE)
|
||||||
|
{
|
||||||
|
DeleteCriticalSection(&ActiveVirtConsLock);
|
||||||
|
CloseHandle(ConsoleDeviceHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsInitialized = Ret;
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TUI Console Driver *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
static VOID WINAPI
|
||||||
|
TuiCleanupConsole(PCONSOLE Console)
|
||||||
|
{
|
||||||
|
PTUI_CONSOLE_DATA TuiData = Console->TermIFace.Data;
|
||||||
|
|
||||||
|
/* Close the notification window */
|
||||||
|
DestroyWindow(TuiData->hWindow);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the active console to the next one
|
||||||
|
* and remove the console from the list.
|
||||||
|
*/
|
||||||
|
EnterCriticalSection(&ActiveVirtConsLock);
|
||||||
|
ActiveConsole = GetNextConsole(TuiData);
|
||||||
|
RemoveEntryList(&TuiData->Entry);
|
||||||
|
|
||||||
|
// /* Switch to next console */
|
||||||
|
// if (ActiveConsole == TuiData)
|
||||||
|
// if (ActiveConsole->Console == Console)
|
||||||
|
// {
|
||||||
|
// ActiveConsole = (TuiData->Entry.Flink != TuiData->Entry ? GetNextConsole(TuiData) : NULL);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (GetNextConsole(TuiData) != TuiData)
|
||||||
|
// {
|
||||||
|
// TuiData->Entry.Blink->Flink = TuiData->Entry.Flink;
|
||||||
|
// TuiData->Entry.Flink->Blink = TuiData->Entry.Blink;
|
||||||
|
// }
|
||||||
|
|
||||||
|
LeaveCriticalSection(&ActiveVirtConsLock);
|
||||||
|
|
||||||
|
/* Switch to the next console */
|
||||||
|
if (NULL != ActiveConsole) ConioDrawConsole(ActiveConsole->Console);
|
||||||
|
|
||||||
|
Console->TermIFace.Data = NULL;
|
||||||
|
DeleteCriticalSection(&TuiData->Lock);
|
||||||
|
RtlFreeHeap(ConSrvHeap, 0, TuiData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID WINAPI
|
||||||
|
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, LONG CursorStartX, LONG CursorStartY,
|
||||||
|
UINT ScrolledLines, CHAR *Buffer, UINT Length)
|
||||||
|
{
|
||||||
|
DWORD BytesWritten;
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
||||||
|
|
||||||
|
if (ActiveConsole->Console->ActiveBuffer != Buff) return;
|
||||||
|
|
||||||
|
if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
|
||||||
|
{
|
||||||
|
DPRINT1("Error writing to BlueScreen\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
||||||
{
|
{
|
||||||
|
@ -354,10 +468,7 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
||||||
PCONSOLE_DRAW ConsoleDraw;
|
PCONSOLE_DRAW ConsoleDraw;
|
||||||
UINT ConsoleDrawSize;
|
UINT ConsoleDrawSize;
|
||||||
|
|
||||||
if (ActiveConsole != Console)
|
if (ActiveConsole->Console != Console) return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
|
ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
|
||||||
(ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
|
(ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
|
||||||
|
@ -387,34 +498,13 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
||||||
RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw);
|
RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
|
||||||
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, LONG CursorStartX, LONG CursorStartY,
|
|
||||||
UINT ScrolledLines, CHAR *Buffer, UINT Length)
|
|
||||||
{
|
|
||||||
DWORD BytesWritten;
|
|
||||||
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
|
|
||||||
|
|
||||||
if (ActiveConsole->ActiveBuffer != Buff)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
|
|
||||||
{
|
|
||||||
DPRINT1("Error writing to BlueScreen\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
||||||
{
|
{
|
||||||
CONSOLE_CURSOR_INFO Info;
|
CONSOLE_CURSOR_INFO Info;
|
||||||
DWORD BytesReturned;
|
DWORD BytesReturned;
|
||||||
|
|
||||||
if (ActiveConsole->ActiveBuffer != Buff)
|
if (ActiveConsole->Console->ActiveBuffer != Buff) return TRUE;
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Info.dwSize = ConioEffectiveCursorSize(Console, 100);
|
Info.dwSize = ConioEffectiveCursorSize(Console, 100);
|
||||||
Info.bVisible = Buff->CursorInfo.bVisible;
|
Info.bVisible = Buff->CursorInfo.bVisible;
|
||||||
|
@ -435,10 +525,7 @@ TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, UINT OldCursorX,
|
||||||
CONSOLE_SCREEN_BUFFER_INFO Info;
|
CONSOLE_SCREEN_BUFFER_INFO Info;
|
||||||
DWORD BytesReturned;
|
DWORD BytesReturned;
|
||||||
|
|
||||||
if (ActiveConsole->ActiveBuffer != Buff)
|
if (ActiveConsole->Console->ActiveBuffer != Buff) return TRUE;
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Info.dwCursorPosition = Buff->CursorPosition;
|
Info.dwCursorPosition = Buff->CursorPosition;
|
||||||
Info.wAttributes = Buff->ScreenDefaultAttrib;
|
Info.wAttributes = Buff->ScreenDefaultAttrib;
|
||||||
|
@ -460,35 +547,46 @@ TuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL WINAPI
|
||||||
|
TuiIsBufferResizeSupported(PCONSOLE Console)
|
||||||
|
{
|
||||||
|
return (Console && Console->State == CONSOLE_INITIALIZING ? TRUE : FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiChangeTitle(PCONSOLE Console)
|
TuiResizeTerminal(PCONSOLE Console)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL WINAPI
|
||||||
|
TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down)
|
||||||
|
{
|
||||||
|
if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) &&
|
||||||
|
VK_TAB == VirtualKeyCode)
|
||||||
|
{
|
||||||
|
if (Down)
|
||||||
|
{
|
||||||
|
TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (VK_MENU == VirtualKeyCode && !Down)
|
||||||
|
{
|
||||||
|
return TuiSwapConsole(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID WINAPI
|
||||||
|
TuiRefreshInternalInfo(PCONSOLE Console)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
TuiCleanupConsole(PCONSOLE Console)
|
TuiChangeTitle(PCONSOLE Console)
|
||||||
{
|
{
|
||||||
DestroyWindow(Console->hWindow);
|
|
||||||
|
|
||||||
EnterCriticalSection(&ActiveConsoleLock);
|
|
||||||
|
|
||||||
/* Switch to next console */
|
|
||||||
if (ActiveConsole == Console)
|
|
||||||
{
|
|
||||||
ActiveConsole = Console->Next != Console ? Console->Next : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Console->Next != Console)
|
|
||||||
{
|
|
||||||
Console->Prev->Next = Console->Next;
|
|
||||||
Console->Next->Prev = Console->Prev;
|
|
||||||
}
|
|
||||||
LeaveCriticalSection(&ActiveConsoleLock);
|
|
||||||
|
|
||||||
if (NULL != ActiveConsole)
|
|
||||||
{
|
|
||||||
ConioDrawConsole(ActiveConsole);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
|
@ -500,57 +598,18 @@ TuiChangeIcon(PCONSOLE Console, HICON hWindowIcon)
|
||||||
static HWND WINAPI
|
static HWND WINAPI
|
||||||
TuiGetConsoleWindowHandle(PCONSOLE Console)
|
TuiGetConsoleWindowHandle(PCONSOLE Console)
|
||||||
{
|
{
|
||||||
return Console->hWindow;
|
PTUI_CONSOLE_DATA TuiData = Console->TermIFace.Data;
|
||||||
|
return TuiData->hWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS WINAPI
|
static VOID WINAPI
|
||||||
TuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size)
|
TuiGetLargestConsoleWindowSize(PCONSOLE Console, PCOORD pSize)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
if (!pSize) return;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
*pSize = PhysicalConsoleSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI
|
static FRONTEND_VTBL TuiVtbl =
|
||||||
TuiConsoleThread(PVOID Data)
|
|
||||||
{
|
|
||||||
PCONSOLE Console = (PCONSOLE) Data;
|
|
||||||
HWND NewWindow;
|
|
||||||
MSG msg;
|
|
||||||
|
|
||||||
NewWindow = CreateWindowW(TUI_CONSOLE_WINDOW_CLASS,
|
|
||||||
Console->Title.Buffer,
|
|
||||||
0,
|
|
||||||
-32000, -32000, 0, 0,
|
|
||||||
NULL, NULL,
|
|
||||||
ConSrvDllInstance,
|
|
||||||
(PVOID)Console);
|
|
||||||
if (NULL == NewWindow)
|
|
||||||
{
|
|
||||||
DPRINT1("CONSRV: Unable to create console window\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
Console->hWindow = NewWindow;
|
|
||||||
|
|
||||||
SetForegroundWindow(Console->hWindow);
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
GetMessageW(&msg, 0, 0, 0);
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
|
|
||||||
if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
|
|
||||||
msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN ||
|
|
||||||
msg.message == WM_KEYUP || msg.message == WM_SYSKEYUP)
|
|
||||||
{
|
|
||||||
ConioProcessKey(Console, &msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static TERMINAL_VTBL TuiVtbl =
|
|
||||||
{
|
{
|
||||||
TuiCleanupConsole,
|
TuiCleanupConsole,
|
||||||
TuiWriteStream,
|
TuiWriteStream,
|
||||||
|
@ -558,72 +617,86 @@ static TERMINAL_VTBL TuiVtbl =
|
||||||
TuiSetCursorInfo,
|
TuiSetCursorInfo,
|
||||||
TuiSetScreenInfo,
|
TuiSetScreenInfo,
|
||||||
TuiUpdateScreenInfo,
|
TuiUpdateScreenInfo,
|
||||||
|
TuiIsBufferResizeSupported,
|
||||||
|
TuiResizeTerminal,
|
||||||
|
TuiProcessKeyCallback,
|
||||||
|
TuiRefreshInternalInfo,
|
||||||
TuiChangeTitle,
|
TuiChangeTitle,
|
||||||
TuiChangeIcon,
|
TuiChangeIcon,
|
||||||
TuiGetConsoleWindowHandle,
|
TuiGetConsoleWindowHandle,
|
||||||
TuiResizeBuffer,
|
TuiGetLargestConsoleWindowSize
|
||||||
TuiProcessKeyCallback
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
TuiInitConsole(PCONSOLE Console,
|
TuiInitConsole(PCONSOLE Console,
|
||||||
PCONSOLE_INFO ConsoleInfo)
|
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
|
||||||
|
PCONSOLE_INFO ConsoleInfo,
|
||||||
|
DWORD ProcessId)
|
||||||
{
|
{
|
||||||
|
PTUI_CONSOLE_DATA TuiData;
|
||||||
HANDLE ThreadHandle;
|
HANDLE ThreadHandle;
|
||||||
|
|
||||||
if (!ConsInitialized)
|
if (Console == NULL || ConsoleInfo == NULL)
|
||||||
{
|
return STATUS_INVALID_PARAMETER;
|
||||||
ConsInitialized = TRUE;
|
|
||||||
if (!TuiInit(Console->CodePage))
|
|
||||||
{
|
|
||||||
ConsInitialized = FALSE;
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Initialize the TUI terminal emulator */
|
||||||
|
if (!TuiInit(Console->CodePage)) return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
/* Initialize the console */
|
||||||
Console->TermIFace.Vtbl = &TuiVtbl;
|
Console->TermIFace.Vtbl = &TuiVtbl;
|
||||||
Console->hWindow = NULL;
|
|
||||||
Console->Size = PhysicalConsoleSize;
|
|
||||||
Console->ActiveBuffer->ScreenBufferSize = PhysicalConsoleSize;
|
|
||||||
|
|
||||||
|
TuiData = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY,
|
||||||
|
sizeof(TUI_CONSOLE_DATA));
|
||||||
|
if (!TuiData)
|
||||||
|
{
|
||||||
|
DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
Console->TermIFace.Data = (PVOID)TuiData;
|
||||||
|
TuiData->Console = Console;
|
||||||
|
TuiData->hWindow = NULL;
|
||||||
|
|
||||||
|
InitializeCriticalSection(&TuiData->Lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HACK: Resize the console since we don't support for now changing
|
||||||
|
* the console size when we display it with the hardware.
|
||||||
|
*/
|
||||||
|
Console->ConsoleSize = PhysicalConsoleSize;
|
||||||
|
ConioResizeBuffer(Console, Console->ActiveBuffer, PhysicalConsoleSize);
|
||||||
|
Console->ActiveBuffer->DisplayMode |= CONSOLE_FULLSCREEN_MODE;
|
||||||
|
// ConioResizeTerminal(Console);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contrary to what we do in the GUI front-end, here we create
|
||||||
|
* an input thread for each console. It will dispatch all the
|
||||||
|
* input messages to the proper console (on the GUI it is done
|
||||||
|
* via the default GUI dispatch thread).
|
||||||
|
*/
|
||||||
ThreadHandle = CreateThread(NULL,
|
ThreadHandle = CreateThread(NULL,
|
||||||
0,
|
0,
|
||||||
TuiConsoleThread,
|
TuiConsoleThread,
|
||||||
(PVOID)Console,
|
(PVOID)TuiData,
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
if (NULL == ThreadHandle)
|
if (NULL == ThreadHandle)
|
||||||
{
|
{
|
||||||
DPRINT1("CONSRV: Unable to create console thread\n");
|
DPRINT1("CONSRV: Unable to create console thread\n");
|
||||||
|
TuiCleanupConsole(Console);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
CloseHandle(ThreadHandle);
|
CloseHandle(ThreadHandle);
|
||||||
|
|
||||||
EnterCriticalSection(&ActiveConsoleLock);
|
/*
|
||||||
if (NULL != ActiveConsole)
|
* Insert the newly created console in the list of virtual consoles
|
||||||
{
|
* and activate it (give it the focus).
|
||||||
Console->Prev = ActiveConsole;
|
*/
|
||||||
Console->Next = ActiveConsole->Next;
|
EnterCriticalSection(&ActiveVirtConsLock);
|
||||||
ActiveConsole->Next->Prev = Console;
|
InsertTailList(&VirtConsList, &TuiData->Entry);
|
||||||
ActiveConsole->Next = Console;
|
ActiveConsole = TuiData;
|
||||||
}
|
LeaveCriticalSection(&ActiveVirtConsLock);
|
||||||
else
|
|
||||||
{
|
|
||||||
Console->Prev = Console;
|
|
||||||
Console->Next = Console;
|
|
||||||
}
|
|
||||||
ActiveConsole = Console;
|
|
||||||
LeaveCriticalSection(&ActiveConsoleLock);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCONSOLE FASTCALL
|
|
||||||
TuiGetFocusConsole(VOID)
|
|
||||||
{
|
|
||||||
return ActiveConsole;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -9,10 +9,11 @@
|
||||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conio.h"
|
#pragma once
|
||||||
|
|
||||||
NTSTATUS FASTCALL TuiInitConsole(PCONSOLE Console,
|
NTSTATUS FASTCALL TuiInitConsole(PCONSOLE Console,
|
||||||
PCONSOLE_INFO ConsoleInfo);
|
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
|
||||||
PCONSOLE FASTCALL TuiGetFocusConsole(VOID);
|
PCONSOLE_INFO ConsoleInfo,
|
||||||
|
DWORD ProcessId);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -108,9 +108,7 @@ typedef struct _FRONTEND_VTBL
|
||||||
UINT OldCursorY);
|
UINT OldCursorY);
|
||||||
BOOL (WINAPI *UpdateScreenInfo)(struct _CONSOLE* Console,
|
BOOL (WINAPI *UpdateScreenInfo)(struct _CONSOLE* Console,
|
||||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
||||||
NTSTATUS (WINAPI *ResizeBuffer)(struct _CONSOLE* Console,
|
BOOL (WINAPI *IsBufferResizeSupported)(struct _CONSOLE* Console);
|
||||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
|
|
||||||
COORD Size);
|
|
||||||
VOID (WINAPI *ResizeTerminal)(struct _CONSOLE* Console);
|
VOID (WINAPI *ResizeTerminal)(struct _CONSOLE* Console);
|
||||||
BOOL (WINAPI *ProcessKeyCallback)(struct _CONSOLE* Console,
|
BOOL (WINAPI *ProcessKeyCallback)(struct _CONSOLE* Console,
|
||||||
MSG* msg,
|
MSG* msg,
|
||||||
|
@ -156,7 +154,6 @@ typedef struct _CONSOLE
|
||||||
CRITICAL_SECTION Lock;
|
CRITICAL_SECTION Lock;
|
||||||
CONSOLE_STATE State; /* State of the console */
|
CONSOLE_STATE State; /* State of the console */
|
||||||
|
|
||||||
// struct _CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel */
|
|
||||||
LIST_ENTRY Entry; /* Entry in the list of consoles */
|
LIST_ENTRY Entry; /* Entry in the list of consoles */
|
||||||
LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */
|
LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */
|
||||||
|
|
||||||
|
@ -230,10 +227,19 @@ NTSTATUS FASTCALL ConioProcessInputEvent(PCONSOLE Console,
|
||||||
#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 FASTCALL ConioCoordToPointer(PCONSOLE_SCREEN_BUFFER Buf, ULONG X, ULONG Y);
|
PBYTE FASTCALL ConioCoordToPointer(PCONSOLE_SCREEN_BUFFER Buf,
|
||||||
|
ULONG X,
|
||||||
|
ULONG Y);
|
||||||
VOID FASTCALL ConioDrawConsole(PCONSOLE Console);
|
VOID FASTCALL ConioDrawConsole(PCONSOLE Console);
|
||||||
NTSTATUS FASTCALL ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff,
|
NTSTATUS FASTCALL ConioResizeBuffer(PCONSOLE Console,
|
||||||
CHAR *Buffer, DWORD Length, BOOL Attrib);
|
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
|
||||||
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale);
|
COORD Size);
|
||||||
|
NTSTATUS FASTCALL ConioWriteConsole(PCONSOLE Console,
|
||||||
|
PCONSOLE_SCREEN_BUFFER Buff,
|
||||||
|
CHAR *Buffer,
|
||||||
|
DWORD Length,
|
||||||
|
BOOL Attrib);
|
||||||
|
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console,
|
||||||
|
DWORD Scale);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -584,20 +584,8 @@ NtUserConsoleControl(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TuiConsoleWndClassAtom:
|
case ConsoleAcquireDisplayOwnership:
|
||||||
{
|
{
|
||||||
_SEH2_TRY
|
|
||||||
{
|
|
||||||
ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1);
|
|
||||||
ASSERT(ConsoleCtrlInfoLength == sizeof(ATOM));
|
|
||||||
gaTuiConsoleWndClass = *(ATOM*)ConsoleCtrlInfo;
|
|
||||||
}
|
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
Status = _SEH2_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH2_END;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ HINSTANCE hModClient = NULL;
|
||||||
BOOL ClientPfnInit = FALSE;
|
BOOL ClientPfnInit = FALSE;
|
||||||
PEPROCESS gpepCSRSS = NULL;
|
PEPROCESS gpepCSRSS = NULL;
|
||||||
ATOM gaGuiConsoleWndClass;
|
ATOM gaGuiConsoleWndClass;
|
||||||
ATOM gaTuiConsoleWndClass;
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ extern PPROCESSINFO ppiScrnSaver;
|
||||||
extern PPROCESSINFO gppiInputProvider;
|
extern PPROCESSINFO gppiInputProvider;
|
||||||
extern PEPROCESS gpepCSRSS;
|
extern PEPROCESS gpepCSRSS;
|
||||||
extern ATOM gaGuiConsoleWndClass;
|
extern ATOM gaGuiConsoleWndClass;
|
||||||
extern ATOM gaTuiConsoleWndClass;
|
|
||||||
|
|
||||||
INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
|
INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
|
||||||
VOID FASTCALL CleanupUserImpl(VOID);
|
VOID FASTCALL CleanupUserImpl(VOID);
|
||||||
|
|
|
@ -3741,8 +3741,7 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
|
||||||
case QUERY_WINDOW_UNIQUE_PROCESS_ID:
|
case QUERY_WINDOW_UNIQUE_PROCESS_ID:
|
||||||
{
|
{
|
||||||
if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
|
if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
|
||||||
( (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) ||
|
(pWnd->pcls->atomClassName == gaGuiConsoleWndClass) )
|
||||||
(pWnd->pcls->atomClassName == gaTuiConsoleWndClass) ) )
|
|
||||||
{
|
{
|
||||||
// IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_PID)
|
// IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_PID)
|
||||||
Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_PID)));
|
Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_PID)));
|
||||||
|
@ -3757,8 +3756,7 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
|
||||||
case QUERY_WINDOW_UNIQUE_THREAD_ID:
|
case QUERY_WINDOW_UNIQUE_THREAD_ID:
|
||||||
{
|
{
|
||||||
if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
|
if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
|
||||||
( (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) ||
|
(pWnd->pcls->atomClassName == gaGuiConsoleWndClass) )
|
||||||
(pWnd->pcls->atomClassName == gaTuiConsoleWndClass) ) )
|
|
||||||
{
|
{
|
||||||
// IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_TID)
|
// IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_TID)
|
||||||
Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_TID)));
|
Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_TID)));
|
||||||
|
|
Loading…
Reference in a new issue