- 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
typedef enum _CONSOLECONTROL
{
GuiConsoleWndClassAtom,
- TuiConsoleWndClassAtom,
+ ConsoleAcquireDisplayOwnership,
} CONSOLECONTROL, *PCONSOLECONTROL;
NTSTATUS
PALIAS_HEADER
IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName)
{
- while(RootHeader)
+ while (RootHeader)
{
INT diff = _wcsicmp(RootHeader->lpExeName, lpExeName);
if (!diff) return RootHeader;
if (Header == NULL) return NULL;
RootHeader = Header->Data;
- while(RootHeader)
+ while (RootHeader)
{
INT diff;
DPRINT("IntGetAliasEntry->lpSource %S\n", RootHeader->lpSource);
{
UINT length = 0;
- while(RootHeader)
+ while (RootHeader)
{
length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR);
RootHeader = RootHeader->Next;
UINT Length;
TargetBufferSize /= sizeof(WCHAR);
- while(RootHeader)
+ while (RootHeader)
{
Length = wcslen(RootHeader->lpExeName) + 1;
if (TargetBufferSize > Offset + Length)
UINT Length = 0;
PALIAS_ENTRY CurEntry = Header->Data;
- while(CurEntry)
+ while (CurEntry)
{
Length += wcslen(CurEntry->lpSource);
Length += wcslen(CurEntry->lpTarget);
UINT SrcLength, TargetLength;
TargetBufferLength /= sizeof(WCHAR);
- while(CurEntry)
+ while (CurEntry)
{
SrcLength = wcslen(CurEntry->lpSource) + 1;
TargetLength = wcslen(CurEntry->lpTarget) + 1;
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;
&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))
/* 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 */
((Rect)->Left) = left; \
((Rect)->Bottom) = bottom; \
((Rect)->Right) = right; \
-} while(0)
+} while (0)
#define ConioIsRectEmpty(Rect) \
(((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
}
}
+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)
{
CursorInfoRequest->Info.bVisible = Buff->CursorInfo.bVisible;
CursorInfoRequest->Info.dwSize = Buff->CursorInfo.dwSize;
- ConSrvReleaseScreenBuffer(Buff, TRUE);
+ ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_SUCCESS;
}
}
ConSrvReleaseScreenBuffer(Buff, TRUE);
-
return STATUS_SUCCESS;
}
}
ConSrvReleaseScreenBuffer(Buff, TRUE);
-
return STATUS_SUCCESS;
}
}
ConSrvReleaseScreenBuffer(Buff, TRUE);
-
return STATUS_SUCCESS;
}
pInfo->dwMaximumWindowSize = Buff->ScreenBufferSize;
ConSrvReleaseScreenBuffer(Buff, TRUE);
-
return STATUS_SUCCESS;
}
ConioDrawConsole(Console);
ConSrvReleaseScreenBuffer(Buff, TRUE);
-
return STATUS_SUCCESS;
}
}
ConSrvReleaseScreenBuffer(Buff, TRUE);
-
return STATUS_SUCCESS;
}
if (!NT_SUCCESS(Status)) return Status;
Status = ConioResizeBuffer(Buff->Header.Console, Buff, SetScreenBufferSizeRequest->Size);
- ConSrvReleaseScreenBuffer(Buff, TRUE);
+ ConSrvReleaseScreenBuffer(Buff, TRUE);
return Status;
}
#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"
/* PRIVATE FUNCTIONS **********************************************************/
-#ifdef TUI_CONSOLE
static BOOL
DtbgIsDesktopVisible(VOID)
{
return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
}
-#endif
static ULONG
ConSrvConsoleCtrlEventTimeout(DWORD Event,
* 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");
GuiMode = TRUE;
}
}
-#endif
/*
* Try to open the GUI-mode terminal emulator. Two cases are possible:
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;
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
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);
{
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);
}
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;
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
}
}
// 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
// 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;
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);
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;
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;
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;
* 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);
SetEvent(*GraphicsStartupEvent);
- while(GetMessageW(&msg, NULL, 0, 0))
+ while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
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
GuiSetCursorInfo,
GuiSetScreenInfo,
GuiUpdateScreenInfo,
- GuiResizeBuffer,
+ GuiIsBufferResizeSupported,
GuiResizeTerminal,
GuiProcessKeyCallback,
GuiRefreshInternalInfo,
* 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
/* 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;
/**\
\******************************************************************************/
-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;
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))
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
}
}
-static BOOL WINAPI
-TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down)
+static VOID FASTCALL
+TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
{
- if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) &&
- VK_TAB == VirtualKeyCode)
+ UINT SrcDelta, DestDelta;
+ LONG i;
+ PBYTE Src, SrcEnd;
+
+ Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
+ SrcDelta = Buff->ScreenBufferSize.X * 2;
+ SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
+ DestDelta = ConioRectWidth(Region) * 2;
+ for (i = Region->Top; i <= Region->Bottom; i++)
{
- if (Down)
+ memcpy(Dest, Src, DestDelta);
+ Src += SrcDelta;
+ if (SrcEnd <= Src)
{
- TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
+ Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
}
+ Dest += DestDelta;
+ }
+}
- return TRUE;
+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);
+ }
}
- else if (VK_MENU == VirtualKeyCode && !Down)
+ 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)
{
- return TuiSwapConsole(0);
+ DPRINT1("CONSRV: Unable to create console window\n");
+ return 1;
}
+ TuiData->hWindow = NewWindow;
- return FALSE;
+ 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 FASTCALL
+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);
+ ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen",
+ FILE_ALL_ACCESS,
+ 0, NULL,
+ OPEN_EXISTING,
+ 0, NULL);
if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle)
{
DPRINT1("Failed to open BlueScreen.\n");
}
ActiveConsole = NULL;
- InitializeCriticalSection(&ActiveConsoleLock);
+ 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");
- return FALSE;
+ 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 = GWLP_CONSOLEWND_ALLOC;
+ wc.cbWndExtra = 0;
wc.hInstance = ConSrvDllInstance;
ConsoleClassAtom = RegisterClassExW(&wc);
if (ConsoleClassAtom == 0)
{
DPRINT1("Failed to register TUI console wndproc\n");
- return FALSE;
+ Ret = FALSE;
}
else
{
- NtUserConsoleControl(TuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM));
+ Ret = TRUE;
}
- return TRUE;
+Quit:
+ if (Ret == FALSE)
+ {
+ DeleteCriticalSection(&ActiveVirtConsLock);
+ CloseHandle(ConsoleDeviceHandle);
+ }
+
+ ConsInitialized = Ret;
+ return Ret;
}
-static VOID FASTCALL
-TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
+
+
+/******************************************************************************
+ * TUI Console Driver *
+ ******************************************************************************/
+
+static VOID WINAPI
+TuiCleanupConsole(PCONSOLE Console)
{
- UINT SrcDelta, DestDelta;
- LONG i;
- PBYTE Src, SrcEnd;
+ 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);
+}
- Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
- SrcDelta = Buff->ScreenBufferSize.X * 2;
- SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
- DestDelta = ConioRectWidth(Region) * 2;
- for (i = Region->Top; i <= Region->Bottom; i++)
+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))
{
- memcpy(Dest, Src, DestDelta);
- Src += SrcDelta;
- if (SrcEnd <= Src)
- {
- Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
- }
- Dest += DestDelta;
+ DPRINT1("Error writing to BlueScreen\n");
}
}
PCONSOLE_DRAW ConsoleDraw;
UINT ConsoleDrawSize;
- if (ActiveConsole != Console)
- {
- return;
- }
+ if (ActiveConsole->Console != Console) return;
ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
(ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
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;
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;
return TRUE;
}
-static VOID WINAPI
-TuiChangeTitle(PCONSOLE Console)
+static BOOL WINAPI
+TuiIsBufferResizeSupported(PCONSOLE Console)
{
+ return (Console && Console->State == CONSOLE_INITIALIZING ? TRUE : FALSE);
}
static VOID WINAPI
-TuiCleanupConsole(PCONSOLE Console)
+TuiResizeTerminal(PCONSOLE Console)
{
- DestroyWindow(Console->hWindow);
-
- EnterCriticalSection(&ActiveConsoleLock);
+}
- /* Switch to next console */
- if (ActiveConsole == 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)
{
- ActiveConsole = Console->Next != Console ? Console->Next : NULL;
- }
+ if (Down)
+ {
+ TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
+ }
- if (Console->Next != Console)
- {
- Console->Prev->Next = Console->Next;
- Console->Next->Prev = Console->Prev;
+ return TRUE;
}
- LeaveCriticalSection(&ActiveConsoleLock);
-
- if (NULL != ActiveConsole)
+ else if (VK_MENU == VirtualKeyCode && !Down)
{
- ConioDrawConsole(ActiveConsole);
+ return TuiSwapConsole(0);
}
+
+ return FALSE;
+}
+
+static VOID WINAPI
+TuiRefreshInternalInfo(PCONSOLE Console)
+{
+}
+
+static VOID WINAPI
+TuiChangeTitle(PCONSOLE Console)
+{
}
static BOOL WINAPI
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,
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 */
* 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 */
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,
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" */
#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 */
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;
}
BOOL ClientPfnInit = FALSE;
PEPROCESS gpepCSRSS = NULL;
ATOM gaGuiConsoleWndClass;
-ATOM gaTuiConsoleWndClass;
/* PRIVATE FUNCTIONS *********************************************************/
extern PPROCESSINFO gppiInputProvider;
extern PEPROCESS gpepCSRSS;
extern ATOM gaGuiConsoleWndClass;
-extern ATOM gaTuiConsoleWndClass;
INIT_FUNCTION NTSTATUS NTAPI InitUserImpl(VOID);
VOID FASTCALL CleanupUserImpl(VOID);
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)));
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)));