mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +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
|
||||
{
|
||||
GuiConsoleWndClassAtom,
|
||||
TuiConsoleWndClassAtom,
|
||||
ConsoleAcquireDisplayOwnership,
|
||||
} CONSOLECONTROL, *PCONSOLECONTROL;
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -40,7 +40,7 @@ static
|
|||
PALIAS_HEADER
|
||||
IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName)
|
||||
{
|
||||
while(RootHeader)
|
||||
while (RootHeader)
|
||||
{
|
||||
INT diff = _wcsicmp(RootHeader->lpExeName, lpExeName);
|
||||
if (!diff) return RootHeader;
|
||||
|
@ -93,7 +93,7 @@ IntGetAliasEntry(PALIAS_HEADER Header, LPCWSTR lpSrcName)
|
|||
if (Header == NULL) return NULL;
|
||||
|
||||
RootHeader = Header->Data;
|
||||
while(RootHeader)
|
||||
while (RootHeader)
|
||||
{
|
||||
INT diff;
|
||||
DPRINT("IntGetAliasEntry->lpSource %S\n", RootHeader->lpSource);
|
||||
|
@ -151,7 +151,7 @@ IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader)
|
|||
{
|
||||
UINT length = 0;
|
||||
|
||||
while(RootHeader)
|
||||
while (RootHeader)
|
||||
{
|
||||
length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR);
|
||||
RootHeader = RootHeader->Next;
|
||||
|
@ -169,7 +169,7 @@ IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader, LPWSTR TargetBuffer, UINT Tar
|
|||
UINT Length;
|
||||
|
||||
TargetBufferSize /= sizeof(WCHAR);
|
||||
while(RootHeader)
|
||||
while (RootHeader)
|
||||
{
|
||||
Length = wcslen(RootHeader->lpExeName) + 1;
|
||||
if (TargetBufferSize > Offset + Length)
|
||||
|
@ -194,7 +194,7 @@ IntGetAllConsoleAliasesLength(PALIAS_HEADER Header)
|
|||
UINT Length = 0;
|
||||
PALIAS_ENTRY CurEntry = Header->Data;
|
||||
|
||||
while(CurEntry)
|
||||
while (CurEntry)
|
||||
{
|
||||
Length += wcslen(CurEntry->lpSource);
|
||||
Length += wcslen(CurEntry->lpTarget);
|
||||
|
@ -217,7 +217,7 @@ IntGetAllConsoleAliases(PALIAS_HEADER Header, LPWSTR TargetBuffer, UINT TargetBu
|
|||
UINT SrcLength, TargetLength;
|
||||
|
||||
TargetBufferLength /= sizeof(WCHAR);
|
||||
while(CurEntry)
|
||||
while (CurEntry)
|
||||
{
|
||||
SrcLength = wcslen(CurEntry->lpSource) + 1;
|
||||
TargetLength = wcslen(CurEntry->lpTarget) + 1;
|
||||
|
|
|
@ -772,7 +772,7 @@ CSR_API(SrvGetConsoleInput)
|
|||
GetInputRequest->InputsRead = 0;
|
||||
|
||||
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.HandleEntry = HandleEntry;
|
||||
|
@ -855,7 +855,7 @@ CSR_API(SrvFlushConsoleInputBuffer)
|
|||
&InputBuffer,
|
||||
GENERIC_WRITE,
|
||||
TRUE);
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Discard all entries in the input event queue */
|
||||
while (!IsListEmpty(&InputBuffer->InputEvents))
|
||||
|
|
|
@ -10,27 +10,35 @@
|
|||
|
||||
/* 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) \
|
||||
(Console)->TermIFace.Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
|
||||
(ScrolledLines), (Buffer), (Length))
|
||||
#define ConioSetCursorInfo(Console, Buff) (Console)->TermIFace.Vtbl->SetCursorInfo((Console), (Buff))
|
||||
(Console)->TermIFace.Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
|
||||
(ScrolledLines), (Buffer), (Length))
|
||||
#define ConioSetCursorInfo(Console, Buff) \
|
||||
(Console)->TermIFace.Vtbl->SetCursorInfo((Console), (Buff))
|
||||
#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) \
|
||||
(Console)->TermIFace.Vtbl->UpdateScreenInfo((Console), (Buff))
|
||||
#define ConioChangeTitle(Console) (Console)->TermIFace.Vtbl->ChangeTitle(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))
|
||||
(Console)->TermIFace.Vtbl->UpdateScreenInfo((Console), (Buff))
|
||||
#define ConioIsBufferResizeSupported(Console) \
|
||||
(Console)->TermIFace.Vtbl->IsBufferResizeSupported(Console)
|
||||
#define ConioChangeTitle(Console) \
|
||||
(Console)->TermIFace.Vtbl->ChangeTitle(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) \
|
||||
(Console)->TermIFace.Vtbl->ProcessKeyCallback((Console), (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down))
|
||||
(Console)->TermIFace.Vtbl->ProcessKeyCallback((Console), (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down))
|
||||
#define ConioGetLargestConsoleWindowSize(Console, pSize) \
|
||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize((Console), (pSize))
|
||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize((Console), (pSize))
|
||||
#define ConioGetConsoleWindowHandle(Console) \
|
||||
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle((Console))
|
||||
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle(Console)
|
||||
#define ConioRefreshInternalInfo(Console) \
|
||||
(Console)->TermIFace.Vtbl->RefreshInternalInfo((Console))
|
||||
(Console)->TermIFace.Vtbl->RefreshInternalInfo(Console)
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -30,7 +30,7 @@ do { \
|
|||
((Rect)->Left) = left; \
|
||||
((Rect)->Bottom) = bottom; \
|
||||
((Rect)->Right) = right; \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#define ConioIsRectEmpty(Rect) \
|
||||
(((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
|
||||
ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
|
||||
{
|
||||
|
@ -1148,8 +1261,8 @@ CSR_API(SrvGetConsoleCursorInfo)
|
|||
|
||||
CursorInfoRequest->Info.bVisible = Buff->CursorInfo.bVisible;
|
||||
CursorInfoRequest->Info.dwSize = Buff->CursorInfo.dwSize;
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1195,7 +1308,6 @@ CSR_API(SrvSetConsoleCursorInfo)
|
|||
}
|
||||
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1237,7 +1349,6 @@ CSR_API(SrvSetConsoleCursorPosition)
|
|||
}
|
||||
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1266,7 +1377,6 @@ CSR_API(SrvSetConsoleTextAttribute)
|
|||
}
|
||||
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1374,7 +1484,6 @@ CSR_API(SrvGetConsoleScreenBufferInfo)
|
|||
pInfo->dwMaximumWindowSize = Buff->ScreenBufferSize;
|
||||
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1411,7 +1520,6 @@ CSR_API(SrvSetConsoleActiveScreenBuffer)
|
|||
ConioDrawConsole(Console);
|
||||
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1503,7 +1611,6 @@ CSR_API(SrvScrollConsoleScreenBuffer)
|
|||
}
|
||||
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1517,8 +1624,8 @@ CSR_API(SrvSetConsoleScreenBufferSize)
|
|||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Status = ConioResizeBuffer(Buff->Header.Console, Buff, SetScreenBufferSizeRequest->Size);
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
|
||||
ConSrvReleaseScreenBuffer(Buff, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,7 @@
|
|||
#include "include/settings.h"
|
||||
|
||||
#include "frontends/gui/guiterm.h"
|
||||
|
||||
#ifdef TUI_CONSOLE
|
||||
#include "frontends/tui/tuiterm.h"
|
||||
#endif
|
||||
#include "frontends/tui/tuiterm.h"
|
||||
|
||||
#include "include/console.h"
|
||||
#include "console.h"
|
||||
|
@ -57,13 +54,11 @@ static RTL_RESOURCE ListLock;
|
|||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
#ifdef TUI_CONSOLE
|
||||
static BOOL
|
||||
DtbgIsDesktopVisible(VOID)
|
||||
{
|
||||
return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
|
||||
}
|
||||
#endif
|
||||
|
||||
static ULONG
|
||||
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 fail, try to start the GUI-mode terminal emulator.
|
||||
*/
|
||||
#ifdef TUI_CONSOLE
|
||||
GuiMode = DtbgIsDesktopVisible();
|
||||
#else
|
||||
GuiMode = TRUE;
|
||||
#endif
|
||||
|
||||
#ifdef TUI_CONSOLE
|
||||
if (!GuiMode)
|
||||
{
|
||||
DPRINT1("CONSRV: Opening text-mode terminal emulator\n");
|
||||
|
@ -660,7 +650,6 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
|
|||
GuiMode = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Try to open the GUI-mode terminal emulator. Two cases are possible:
|
||||
|
|
|
@ -70,7 +70,7 @@ do { \
|
|||
ConsoleLeaderCID = ProcessData->Process->ClientId; \
|
||||
SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_PID, (LONG_PTR)(ConsoleLeaderCID.UniqueProcess)); \
|
||||
SetWindowLongPtrW((GuiData)->hWindow, GWLP_CONSOLE_LEADER_TID, (LONG_PTR)(ConsoleLeaderCID.UniqueThread )); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
/**************************************************************/
|
||||
|
||||
static BOOL ConsInitialized = FALSE;
|
||||
|
@ -185,7 +185,7 @@ GuiConsoleAppendMenuItems(HMENU hMenu,
|
|||
NULL);
|
||||
}
|
||||
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
|
||||
|
@ -209,8 +209,6 @@ static VOID
|
|||
GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord);
|
||||
static VOID WINAPI
|
||||
GuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region);
|
||||
static NTSTATUS WINAPI
|
||||
GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size);
|
||||
static VOID
|
||||
GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData);
|
||||
|
||||
|
@ -510,7 +508,7 @@ GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord)
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
@ -861,7 +859,7 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
|||
GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||
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;
|
||||
int OldScrollX = -1, OldScrollY = -1;
|
||||
|
@ -870,16 +868,16 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
|||
xScroll.cbSize = sizeof(SCROLLINFO);
|
||||
xScroll.fMask = SIF_POS;
|
||||
// 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_VERT, &xScroll))OldScrollY = xScroll.nPos;
|
||||
if (GetScrollInfo(GuiData->hWindow, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos;
|
||||
if (GetScrollInfo(GuiData->hWindow, SB_VERT, &xScroll))OldScrollY = xScroll.nPos;
|
||||
|
||||
// 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
|
||||
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
|
||||
|
@ -888,12 +886,12 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
|||
}
|
||||
}
|
||||
// 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
|
||||
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
|
||||
|
@ -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
|
||||
// was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling)
|
||||
// and their associated scrollbar is left alone.
|
||||
if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY))
|
||||
if ((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY))
|
||||
{
|
||||
Buff->ShowX = NewScrollX;
|
||||
Buff->ShowY = NewScrollY;
|
||||
|
@ -918,12 +916,12 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
|||
NULL,
|
||||
NULL,
|
||||
SW_INVALIDATE);
|
||||
if(NewScrollX >= 0)
|
||||
if (NewScrollX >= 0)
|
||||
{
|
||||
xScroll.nPos = NewScrollX;
|
||||
SetScrollInfo(GuiData->hWindow, SB_HORZ, &xScroll, TRUE);
|
||||
}
|
||||
if(NewScrollY >= 0)
|
||||
if (NewScrollY >= 0)
|
||||
{
|
||||
xScroll.nPos = NewScrollY;
|
||||
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));
|
||||
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.Y < Console->ActiveBuffer->ScreenBufferSize.Y) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical 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
|
||||
|
||||
minMaxInfo->ptMaxTrackSize.x = windx;
|
||||
minMaxInfo->ptMaxTrackSize.y = windy;
|
||||
|
@ -1366,29 +1364,29 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
|
|||
windy = HIWORD(lParam);
|
||||
|
||||
// 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.Y < Buff->ScreenBufferSize.Y) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical 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
|
||||
|
||||
charx = windx / GuiData->CharWidth;
|
||||
chary = windy / GuiData->CharHeight;
|
||||
|
||||
// Character alignment (round size up or down)
|
||||
if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
|
||||
if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
|
||||
if ((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
|
||||
if ((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
|
||||
|
||||
// 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(chary < Buff->ScreenBufferSize.Y)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical 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
|
||||
|
||||
charx = windx / GuiData->CharWidth;
|
||||
chary = windy / GuiData->CharHeight;
|
||||
|
||||
// Character alignment (round size up or down)
|
||||
if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
|
||||
if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
|
||||
if ((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
|
||||
if ((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
|
||||
|
||||
// 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.Y = (chary <= Buff->ScreenBufferSize.Y) ? chary : Buff->ScreenBufferSize.Y;
|
||||
|
@ -1397,8 +1395,8 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
|
|||
GuiConsoleResizeWindow(GuiData);
|
||||
|
||||
// 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.Y - Buff->ShowY) < Console->ConsoleSize.Y) Buff->ShowY = Buff->ScreenBufferSize.Y - Console->ConsoleSize.Y;
|
||||
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;
|
||||
InvalidateRect(GuiData->hWindow, NULL, TRUE);
|
||||
|
||||
GuiData->WindowSizeLock = FALSE;
|
||||
|
@ -1809,7 +1807,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
* So first empty the message queue.
|
||||
*/
|
||||
/*
|
||||
while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
|
||||
while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&Msg);
|
||||
DispatchMessageW(&Msg);
|
||||
|
@ -1873,7 +1871,7 @@ GuiConsoleGuiThread(PVOID Data)
|
|||
|
||||
SetEvent(*GraphicsStartupEvent);
|
||||
|
||||
while(GetMessageW(&msg, NULL, 0, 0))
|
||||
while (GetMessageW(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
|
@ -2122,114 +2120,10 @@ GuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static NTSTATUS WINAPI
|
||||
GuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size)
|
||||
static BOOL WINAPI
|
||||
GuiIsBufferResizeSupported(PCONSOLE Console)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static VOID WINAPI
|
||||
|
@ -2365,7 +2259,7 @@ static FRONTEND_VTBL GuiVtbl =
|
|||
GuiSetCursorInfo,
|
||||
GuiSetScreenInfo,
|
||||
GuiUpdateScreenInfo,
|
||||
GuiResizeBuffer,
|
||||
GuiIsBufferResizeSupported,
|
||||
GuiResizeTerminal,
|
||||
GuiProcessKeyCallback,
|
||||
GuiRefreshInternalInfo,
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Server DLL
|
||||
* FILE: win32ss/user/consrv/frontends/tui/tuiterm.c
|
||||
* PURPOSE: TUI Terminal Front-End
|
||||
* PURPOSE: TUI Terminal Front-End - Virtual Consoles...
|
||||
* PROGRAMMERS: David Welch
|
||||
* Gé van Geldorp
|
||||
* Jeffrey Morlan
|
||||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#ifdef TUI_CONSOLE
|
||||
|
||||
#include "consrv.h"
|
||||
#include "settings.h"
|
||||
#include "tuiconsole.h"
|
||||
#include "include/conio.h"
|
||||
// #include "include/console.h"
|
||||
#include "include/settings.h"
|
||||
#include "tuiterm.h"
|
||||
#include <drivers/blue/ntddblue.h>
|
||||
|
||||
#define NDEBUG
|
||||
|
@ -22,24 +22,35 @@
|
|||
|
||||
/* 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 */
|
||||
#define TUI_CONSOLE_WINDOW_CLASS L"TuiConsoleWindowClass"
|
||||
|
||||
typedef struct _TUI_CONSOLE_DATA
|
||||
{
|
||||
CRITICAL_SECTION Lock;
|
||||
LIST_ENTRY Entry; /* Entry in the list of virtual consoles */
|
||||
// HANDLE hTuiInitEvent;
|
||||
|
||||
HWND hWindow;
|
||||
HWND hWindow; /* Handle to the console's window (used for the window's procedure */
|
||||
|
||||
PCONSOLE Console;
|
||||
// TUI_CONSOLE_INFO TuiInfo;
|
||||
PCONSOLE Console; /* Pointer to the owned console */
|
||||
// TUI_CONSOLE_INFO TuiInfo; /* TUI terminal settings */
|
||||
} 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 HANDLE ConsoleDeviceHandle;
|
||||
static PCONSOLE ActiveConsole;
|
||||
|
||||
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
|
||||
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;
|
||||
ANSI_STRING Title;
|
||||
PVOID Buffer;
|
||||
|
@ -178,28 +175,26 @@ TuiSwapConsole(INT Next)
|
|||
|
||||
if (0 != Next)
|
||||
{
|
||||
/* alt-tab, swap consoles */
|
||||
/* move SwapConsole to next console, and print its title */
|
||||
EnterCriticalSection(&ActiveConsoleLock);
|
||||
if (!SwapConsole)
|
||||
{
|
||||
SwapConsole = ActiveConsole;
|
||||
}
|
||||
/*
|
||||
* Alt-Tab, swap consoles.
|
||||
* move SwapConsole to next console, and print its title.
|
||||
*/
|
||||
EnterCriticalSection(&ActiveVirtConsLock);
|
||||
if (!SwapConsole) SwapConsole = ActiveConsole;
|
||||
|
||||
SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev);
|
||||
Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title);
|
||||
SwapConsole = (0 < Next ? GetNextConsole(SwapConsole) : GetPrevConsole(SwapConsole));
|
||||
Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Console->Title);
|
||||
Title.Length = 0;
|
||||
Buffer = RtlAllocateHeap(ConSrvHeap,
|
||||
0,
|
||||
sizeof(COORD) + Title.MaximumLength);
|
||||
pos = (PCOORD )Buffer;
|
||||
Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof( COORD ));
|
||||
Buffer = RtlAllocateHeap(ConSrvHeap, 0,
|
||||
sizeof(COORD) + Title.MaximumLength);
|
||||
pos = (PCOORD)Buffer;
|
||||
Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof(COORD));
|
||||
|
||||
RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE);
|
||||
pos->Y = PhysicalConsoleSize.Y / 2;
|
||||
RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Console->Title, FALSE);
|
||||
pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
|
||||
/* redraw the console to clear off old title */
|
||||
ConioDrawConsole(ActiveConsole);
|
||||
pos->Y = PhysicalConsoleSize.Y / 2;
|
||||
/* Redraw the console to clear off old title */
|
||||
ConioDrawConsole(ActiveConsole->Console);
|
||||
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
|
||||
NULL, 0, Buffer, sizeof(COORD) + Title.Length,
|
||||
&BytesReturned, NULL))
|
||||
|
@ -207,28 +202,28 @@ TuiSwapConsole(INT Next)
|
|||
DPRINT1( "Error writing to console\n" );
|
||||
}
|
||||
RtlFreeHeap(ConSrvHeap, 0, Buffer);
|
||||
LeaveCriticalSection(&ActiveConsoleLock);
|
||||
LeaveCriticalSection(&ActiveVirtConsLock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (NULL != SwapConsole)
|
||||
{
|
||||
EnterCriticalSection(&ActiveConsoleLock);
|
||||
EnterCriticalSection(&ActiveVirtConsLock);
|
||||
if (SwapConsole != ActiveConsole)
|
||||
{
|
||||
/* first remove swapconsole from the list */
|
||||
SwapConsole->Prev->Next = SwapConsole->Next;
|
||||
SwapConsole->Next->Prev = SwapConsole->Prev;
|
||||
/* now insert before activeconsole */
|
||||
SwapConsole->Next = ActiveConsole;
|
||||
SwapConsole->Prev = ActiveConsole->Prev;
|
||||
ActiveConsole->Prev->Next = SwapConsole;
|
||||
ActiveConsole->Prev = SwapConsole;
|
||||
/* First remove swapconsole from the list */
|
||||
SwapConsole->Entry.Blink->Flink = SwapConsole->Entry.Flink;
|
||||
SwapConsole->Entry.Flink->Blink = SwapConsole->Entry.Blink;
|
||||
/* Now insert before activeconsole */
|
||||
SwapConsole->Entry.Flink = &ActiveConsole->Entry;
|
||||
SwapConsole->Entry.Blink = ActiveConsole->Entry.Blink;
|
||||
ActiveConsole->Entry.Blink->Flink = &SwapConsole->Entry;
|
||||
ActiveConsole->Entry.Blink = &SwapConsole->Entry;
|
||||
}
|
||||
ActiveConsole = SwapConsole;
|
||||
SwapConsole = NULL;
|
||||
ConioDrawConsole(ActiveConsole);
|
||||
LeaveCriticalSection(&ActiveConsoleLock);
|
||||
ConioDrawConsole(ActiveConsole->Console);
|
||||
LeaveCriticalSection(&ActiveVirtConsLock);
|
||||
return TRUE;
|
||||
}
|
||||
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
|
||||
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
|
||||
TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
||||
{
|
||||
|
@ -354,10 +468,7 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
|||
PCONSOLE_DRAW ConsoleDraw;
|
||||
UINT ConsoleDrawSize;
|
||||
|
||||
if (ActiveConsole != Console)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (ActiveConsole->Console != Console) return;
|
||||
|
||||
ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
|
||||
(ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
|
||||
|
@ -387,34 +498,13 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
|
|||
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
|
||||
TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
||||
{
|
||||
CONSOLE_CURSOR_INFO Info;
|
||||
DWORD BytesReturned;
|
||||
|
||||
if (ActiveConsole->ActiveBuffer != Buff)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (ActiveConsole->Console->ActiveBuffer != Buff) return TRUE;
|
||||
|
||||
Info.dwSize = ConioEffectiveCursorSize(Console, 100);
|
||||
Info.bVisible = Buff->CursorInfo.bVisible;
|
||||
|
@ -435,10 +525,7 @@ TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, UINT OldCursorX,
|
|||
CONSOLE_SCREEN_BUFFER_INFO Info;
|
||||
DWORD BytesReturned;
|
||||
|
||||
if (ActiveConsole->ActiveBuffer != Buff)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (ActiveConsole->Console->ActiveBuffer != Buff) return TRUE;
|
||||
|
||||
Info.dwCursorPosition = Buff->CursorPosition;
|
||||
Info.wAttributes = Buff->ScreenDefaultAttrib;
|
||||
|
@ -460,35 +547,46 @@ TuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
TuiIsBufferResizeSupported(PCONSOLE Console)
|
||||
{
|
||||
return (Console && Console->State == CONSOLE_INITIALIZING ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -500,57 +598,18 @@ TuiChangeIcon(PCONSOLE Console, HICON hWindowIcon)
|
|||
static HWND WINAPI
|
||||
TuiGetConsoleWindowHandle(PCONSOLE Console)
|
||||
{
|
||||
return Console->hWindow;
|
||||
PTUI_CONSOLE_DATA TuiData = Console->TermIFace.Data;
|
||||
return TuiData->hWindow;
|
||||
}
|
||||
|
||||
static NTSTATUS WINAPI
|
||||
TuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size)
|
||||
static VOID WINAPI
|
||||
TuiGetLargestConsoleWindowSize(PCONSOLE Console, PCOORD pSize)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
if (!pSize) return;
|
||||
*pSize = PhysicalConsoleSize;
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
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 =
|
||||
static FRONTEND_VTBL TuiVtbl =
|
||||
{
|
||||
TuiCleanupConsole,
|
||||
TuiWriteStream,
|
||||
|
@ -558,72 +617,86 @@ static TERMINAL_VTBL TuiVtbl =
|
|||
TuiSetCursorInfo,
|
||||
TuiSetScreenInfo,
|
||||
TuiUpdateScreenInfo,
|
||||
TuiIsBufferResizeSupported,
|
||||
TuiResizeTerminal,
|
||||
TuiProcessKeyCallback,
|
||||
TuiRefreshInternalInfo,
|
||||
TuiChangeTitle,
|
||||
TuiChangeIcon,
|
||||
TuiGetConsoleWindowHandle,
|
||||
TuiResizeBuffer,
|
||||
TuiProcessKeyCallback
|
||||
TuiGetLargestConsoleWindowSize
|
||||
};
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
TuiInitConsole(PCONSOLE Console,
|
||||
PCONSOLE_INFO ConsoleInfo)
|
||||
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
PCONSOLE_INFO ConsoleInfo,
|
||||
DWORD ProcessId)
|
||||
{
|
||||
PTUI_CONSOLE_DATA TuiData;
|
||||
HANDLE ThreadHandle;
|
||||
|
||||
if (!ConsInitialized)
|
||||
{
|
||||
ConsInitialized = TRUE;
|
||||
if (!TuiInit(Console->CodePage))
|
||||
{
|
||||
ConsInitialized = FALSE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
if (Console == NULL || ConsoleInfo == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Initialize the TUI terminal emulator */
|
||||
if (!TuiInit(Console->CodePage)) return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* Initialize the console */
|
||||
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,
|
||||
0,
|
||||
TuiConsoleThread,
|
||||
(PVOID)Console,
|
||||
(PVOID)TuiData,
|
||||
0,
|
||||
NULL);
|
||||
if (NULL == ThreadHandle)
|
||||
{
|
||||
DPRINT1("CONSRV: Unable to create console thread\n");
|
||||
TuiCleanupConsole(Console);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
CloseHandle(ThreadHandle);
|
||||
|
||||
EnterCriticalSection(&ActiveConsoleLock);
|
||||
if (NULL != ActiveConsole)
|
||||
{
|
||||
Console->Prev = ActiveConsole;
|
||||
Console->Next = ActiveConsole->Next;
|
||||
ActiveConsole->Next->Prev = Console;
|
||||
ActiveConsole->Next = Console;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console->Prev = Console;
|
||||
Console->Next = Console;
|
||||
}
|
||||
ActiveConsole = Console;
|
||||
LeaveCriticalSection(&ActiveConsoleLock);
|
||||
/*
|
||||
* Insert the newly created console in the list of virtual consoles
|
||||
* and activate it (give it the focus).
|
||||
*/
|
||||
EnterCriticalSection(&ActiveVirtConsLock);
|
||||
InsertTailList(&VirtConsList, &TuiData->Entry);
|
||||
ActiveConsole = TuiData;
|
||||
LeaveCriticalSection(&ActiveVirtConsLock);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
PCONSOLE FASTCALL
|
||||
TuiGetFocusConsole(VOID)
|
||||
{
|
||||
return ActiveConsole;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#include "conio.h"
|
||||
#pragma once
|
||||
|
||||
NTSTATUS FASTCALL TuiInitConsole(PCONSOLE Console,
|
||||
PCONSOLE_INFO ConsoleInfo);
|
||||
PCONSOLE FASTCALL TuiGetFocusConsole(VOID);
|
||||
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
PCONSOLE_INFO ConsoleInfo,
|
||||
DWORD ProcessId);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -108,9 +108,7 @@ typedef struct _FRONTEND_VTBL
|
|||
UINT OldCursorY);
|
||||
BOOL (WINAPI *UpdateScreenInfo)(struct _CONSOLE* Console,
|
||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
||||
NTSTATUS (WINAPI *ResizeBuffer)(struct _CONSOLE* Console,
|
||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
|
||||
COORD Size);
|
||||
BOOL (WINAPI *IsBufferResizeSupported)(struct _CONSOLE* Console);
|
||||
VOID (WINAPI *ResizeTerminal)(struct _CONSOLE* Console);
|
||||
BOOL (WINAPI *ProcessKeyCallback)(struct _CONSOLE* Console,
|
||||
MSG* msg,
|
||||
|
@ -156,7 +154,6 @@ typedef struct _CONSOLE
|
|||
CRITICAL_SECTION Lock;
|
||||
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 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) \
|
||||
(((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);
|
||||
NTSTATUS FASTCALL ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff,
|
||||
CHAR *Buffer, DWORD Length, BOOL Attrib);
|
||||
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale);
|
||||
NTSTATUS FASTCALL ConioResizeBuffer(PCONSOLE Console,
|
||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
|
||||
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 */
|
||||
|
|
|
@ -584,20 +584,8 @@ NtUserConsoleControl(
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ HINSTANCE hModClient = NULL;
|
|||
BOOL ClientPfnInit = FALSE;
|
||||
PEPROCESS gpepCSRSS = NULL;
|
||||
ATOM gaGuiConsoleWndClass;
|
||||
ATOM gaTuiConsoleWndClass;
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ extern PPROCESSINFO ppiScrnSaver;
|
|||
extern PPROCESSINFO gppiInputProvider;
|
||||
extern PEPROCESS gpepCSRSS;
|
||||
extern ATOM gaGuiConsoleWndClass;
|
||||
extern ATOM gaTuiConsoleWndClass;
|
||||
|
||||
INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
|
||||
VOID FASTCALL CleanupUserImpl(VOID);
|
||||
|
|
|
@ -3741,8 +3741,7 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
|
|||
case QUERY_WINDOW_UNIQUE_PROCESS_ID:
|
||||
{
|
||||
if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
|
||||
( (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) ||
|
||||
(pWnd->pcls->atomClassName == gaTuiConsoleWndClass) ) )
|
||||
(pWnd->pcls->atomClassName == gaGuiConsoleWndClass) )
|
||||
{
|
||||
// IntGetWindowLong(offset == 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:
|
||||
{
|
||||
if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
|
||||
( (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) ||
|
||||
(pWnd->pcls->atomClassName == gaTuiConsoleWndClass) ) )
|
||||
(pWnd->pcls->atomClassName == gaGuiConsoleWndClass) )
|
||||
{
|
||||
// IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_TID)
|
||||
Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_TID)));
|
||||
|
|
Loading…
Reference in a new issue