- 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:
Hermès Bélusca-Maïto 2013-04-11 23:37:09 +00:00
parent 2b02f27941
commit 0777ed55e5
14 changed files with 556 additions and 494 deletions

View file

@ -1566,7 +1566,7 @@ NtUserCloseWindowStation(
typedef enum _CONSOLECONTROL typedef enum _CONSOLECONTROL
{ {
GuiConsoleWndClassAtom, GuiConsoleWndClassAtom,
TuiConsoleWndClassAtom, ConsoleAcquireDisplayOwnership,
} CONSOLECONTROL, *PCONSOLECONTROL; } CONSOLECONTROL, *PCONSOLECONTROL;
NTSTATUS NTSTATUS

View file

@ -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;

View file

@ -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))

View file

@ -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 */

View file

@ -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;
} }

View file

@ -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:

View file

@ -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,

View file

@ -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
* van Geldorp * 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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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;
} }

View file

@ -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 *********************************************************/

View file

@ -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);

View file

@ -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)));