mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 17:33:18 +00:00
Sync with trunk r63878.
svn path=/branches/shell-experiments/; revision=63879
This commit is contained in:
parent
6f51eb4048
commit
810048d98e
56 changed files with 1172 additions and 346 deletions
|
@ -372,28 +372,22 @@ FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam)
|
|||
|
||||
pti = Wnd->head.pti;
|
||||
|
||||
if (!IsListEmpty(&pti->SentMessagesListHead))
|
||||
Entry = pti->SentMessagesListHead.Flink;
|
||||
while (Entry != &pti->SentMessagesListHead)
|
||||
{
|
||||
// Scan sent queue messages to see if we received async messages.
|
||||
Entry = pti->SentMessagesListHead.Flink;
|
||||
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
|
||||
do
|
||||
{
|
||||
if (IsListEmpty(Entry)) return;
|
||||
if (!Message) return;
|
||||
Entry = Message->ListEntry.Flink;
|
||||
Entry = Entry->Flink;
|
||||
|
||||
if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW &&
|
||||
Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
|
||||
Message->Msg.wParam == wParam )
|
||||
{
|
||||
ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd,!!wParam);
|
||||
RemoveEntryList(&Message->ListEntry); // Purge the entry.
|
||||
ExFreePoolWithTag(Message, TAG_USRMSG);
|
||||
}
|
||||
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
|
||||
if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW &&
|
||||
Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
|
||||
Message->Msg.wParam == wParam)
|
||||
{
|
||||
ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd, !!wParam);
|
||||
RemoveEntryList(&Message->ListEntry); // Purge the entry.
|
||||
ClearMsgBitsMask(pti, Message->QS_Flags);
|
||||
ExFreePoolWithTag(Message, TAG_USRMSG);
|
||||
}
|
||||
while (Entry != &pti->SentMessagesListHead);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console,
|
|||
if (Buffer == Console->ActiveBuffer) return STATUS_SUCCESS;
|
||||
|
||||
/* If old buffer has no handles, it's now unreferenced */
|
||||
if (Console->ActiveBuffer->Header.HandleCount == 0)
|
||||
if (Console->ActiveBuffer->Header.ReferenceCount == 0)
|
||||
{
|
||||
ConioDeleteScreenBuffer(Console->ActiveBuffer);
|
||||
}
|
||||
|
@ -207,6 +207,13 @@ ConDrvGetActiveScreenBuffer(IN PCONSOLE Console)
|
|||
|
||||
/* PUBLIC DRIVER APIS *********************************************************/
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvWriteConsoleOutputVDM(IN PCONSOLE Console,
|
||||
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||
IN PCHAR_CELL CharInfo/*Buffer*/,
|
||||
IN COORD CharInfoSize,
|
||||
IN OUT PSMALL_RECT WriteRegion,
|
||||
IN BOOLEAN DrawRegion);
|
||||
NTSTATUS NTAPI
|
||||
ConDrvInvalidateBitMapRect(IN PCONSOLE Console,
|
||||
IN PCONSOLE_SCREEN_BUFFER Buffer,
|
||||
|
@ -218,6 +225,19 @@ ConDrvInvalidateBitMapRect(IN PCONSOLE Console,
|
|||
/* Validity check */
|
||||
ASSERT(Console == Buffer->Header.Console);
|
||||
|
||||
/* In text-mode only, draw the VDM buffer if present */
|
||||
if (GetType(Buffer) == TEXTMODE_BUFFER)
|
||||
{
|
||||
PTEXTMODE_SCREEN_BUFFER TextBuffer = (PTEXTMODE_SCREEN_BUFFER)Buffer;
|
||||
|
||||
/*Status =*/ ConDrvWriteConsoleOutputVDM(Buffer->Header.Console,
|
||||
TextBuffer,
|
||||
Console->VDMBuffer,
|
||||
Console->VDMBufferSize,
|
||||
Region,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/* If the output buffer is the current one, redraw the correct portion of the screen */
|
||||
if (Buffer == Console->ActiveBuffer) TermDrawRegion(Console, Region);
|
||||
|
||||
|
|
|
@ -722,6 +722,68 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: This function is strongly inspired by ConDrvWriteConsoleOutput...
|
||||
*/
|
||||
NTSTATUS NTAPI
|
||||
ConDrvWriteConsoleOutputVDM(IN PCONSOLE Console,
|
||||
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||
IN PCHAR_CELL CharInfo/*Buffer*/,
|
||||
IN COORD CharInfoSize,
|
||||
IN OUT PSMALL_RECT WriteRegion,
|
||||
IN BOOLEAN DrawRegion)
|
||||
{
|
||||
SHORT X, Y;
|
||||
SMALL_RECT ScreenBuffer;
|
||||
PCHAR_CELL CurCharInfo;
|
||||
SMALL_RECT CapturedWriteRegion;
|
||||
PCHAR_INFO Ptr;
|
||||
|
||||
if (Console == NULL || Buffer == NULL || CharInfo == NULL || WriteRegion == NULL)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Validity check */
|
||||
ASSERT(Console == Buffer->Header.Console);
|
||||
|
||||
CapturedWriteRegion = *WriteRegion;
|
||||
|
||||
/* Make sure WriteRegion is inside the screen buffer */
|
||||
ConioInitRect(&ScreenBuffer, 0, 0,
|
||||
Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
|
||||
if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer, &CapturedWriteRegion))
|
||||
{
|
||||
/*
|
||||
* It is okay to have a WriteRegion completely outside
|
||||
* the screen buffer. No data is written then.
|
||||
*/
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// CurCharInfo = CharInfo;
|
||||
|
||||
for (Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; ++Y)
|
||||
{
|
||||
/**/CurCharInfo = CharInfo + Y * CharInfoSize.X + CapturedWriteRegion.Left;/**/
|
||||
|
||||
Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y);
|
||||
for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; ++X)
|
||||
{
|
||||
ConsoleAnsiCharToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char);
|
||||
Ptr->Attributes = CurCharInfo->Attributes;
|
||||
++Ptr;
|
||||
++CurCharInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (DrawRegion) TermDrawRegion(Console, &CapturedWriteRegion);
|
||||
|
||||
*WriteRegion = CapturedWriteRegion;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvWriteConsole(IN PCONSOLE Console,
|
||||
IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||
|
|
|
@ -463,15 +463,15 @@ CSR_API(SrvReadConsoleOutput)
|
|||
|
||||
DPRINT("SrvReadConsoleOutput\n");
|
||||
|
||||
NumCells = (ReadOutputRequest->ReadRegion.Right - ReadOutputRequest->ReadRegion.Left + 1) *
|
||||
(ReadOutputRequest->ReadRegion.Bottom - ReadOutputRequest->ReadRegion.Top + 1);
|
||||
|
||||
/*
|
||||
* For optimization purposes, Windows (and hence ReactOS, too, for
|
||||
* compatibility reasons) uses a static buffer if no more than one
|
||||
* cell is read. Otherwise a new buffer is used.
|
||||
* The client-side expects that we know this behaviour.
|
||||
*/
|
||||
NumCells = (ReadOutputRequest->ReadRegion.Right - ReadOutputRequest->ReadRegion.Left + 1) *
|
||||
(ReadOutputRequest->ReadRegion.Bottom - ReadOutputRequest->ReadRegion.Top + 1);
|
||||
|
||||
if (NumCells <= 1)
|
||||
{
|
||||
/*
|
||||
|
@ -520,54 +520,95 @@ CSR_API(SrvWriteConsoleOutput)
|
|||
NTSTATUS Status;
|
||||
PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest;
|
||||
PTEXTMODE_SCREEN_BUFFER Buffer;
|
||||
PCSR_PROCESS Process = CsrGetClientThread()->Process;
|
||||
|
||||
ULONG NumCells;
|
||||
PCHAR_INFO CharInfo;
|
||||
|
||||
DPRINT("SrvWriteConsoleOutput\n");
|
||||
|
||||
/*
|
||||
* For optimization purposes, Windows (and hence ReactOS, too, for
|
||||
* compatibility reasons) uses a static buffer if no more than one
|
||||
* cell is written. Otherwise a new buffer is used.
|
||||
* The client-side expects that we know this behaviour.
|
||||
*/
|
||||
NumCells = (WriteOutputRequest->WriteRegion.Right - WriteOutputRequest->WriteRegion.Left + 1) *
|
||||
(WriteOutputRequest->WriteRegion.Bottom - WriteOutputRequest->WriteRegion.Top + 1);
|
||||
|
||||
if (NumCells <= 1)
|
||||
{
|
||||
/*
|
||||
* Adjust the internal pointer, because its old value points to
|
||||
* the static buffer in the original ApiMessage structure.
|
||||
*/
|
||||
// WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer;
|
||||
CharInfo = &WriteOutputRequest->StaticBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&WriteOutputRequest->CharInfo,
|
||||
NumCells,
|
||||
sizeof(CHAR_INFO)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CharInfo = WriteOutputRequest->CharInfo;
|
||||
}
|
||||
|
||||
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(Process),
|
||||
WriteOutputRequest->OutputHandle,
|
||||
&Buffer, GENERIC_WRITE, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/*
|
||||
* Validate the message buffer if we do not use a process' heap buffer
|
||||
* (CsrAllocateCaptureBuffer succeeded because we haven't allocated
|
||||
* a too large (>= 64 kB, size of the CSR heap) data buffer).
|
||||
*/
|
||||
if (!WriteOutputRequest->UseVirtualMemory)
|
||||
{
|
||||
/*
|
||||
* For optimization purposes, Windows (and hence ReactOS, too, for
|
||||
* compatibility reasons) uses a static buffer if no more than one
|
||||
* cell is written. Otherwise a new buffer is used.
|
||||
* The client-side expects that we know this behaviour.
|
||||
*/
|
||||
if (NumCells <= 1)
|
||||
{
|
||||
/*
|
||||
* Adjust the internal pointer, because its old value points to
|
||||
* the static buffer in the original ApiMessage structure.
|
||||
*/
|
||||
// WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer;
|
||||
CharInfo = &WriteOutputRequest->StaticBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&WriteOutputRequest->CharInfo,
|
||||
NumCells,
|
||||
sizeof(CHAR_INFO)))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
CharInfo = WriteOutputRequest->CharInfo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* This was not the case: we use a heap buffer. Retrieve its contents.
|
||||
*/
|
||||
ULONG Size = NumCells * sizeof(CHAR_INFO);
|
||||
|
||||
CharInfo = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size);
|
||||
if (CharInfo == NULL)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
Status = NtReadVirtualMemory(Process->ProcessHandle,
|
||||
WriteOutputRequest->CharInfo,
|
||||
CharInfo,
|
||||
Size,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ConsoleFreeHeap(CharInfo);
|
||||
// Status = STATUS_NO_MEMORY;
|
||||
goto Quit;
|
||||
}
|
||||
}
|
||||
|
||||
Status = ConDrvWriteConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
WriteOutputRequest->Unicode,
|
||||
CharInfo,
|
||||
&WriteOutputRequest->WriteRegion);
|
||||
|
||||
/* Free the temporary buffer if we used the process' heap buffer */
|
||||
if (WriteOutputRequest->UseVirtualMemory && CharInfo)
|
||||
ConsoleFreeHeap(CharInfo);
|
||||
|
||||
Quit:
|
||||
ConSrvReleaseScreenBuffer(Buffer, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -506,8 +506,8 @@ OnNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
|
|||
|
||||
GuiData->hWindow = hWnd;
|
||||
|
||||
GuiData->Font = CreateFontW(GuiData->GuiInfo.FontSize.X,
|
||||
0, // GuiData->GuiInfo.FontSize.Y,
|
||||
GuiData->Font = CreateFontW(GuiData->GuiInfo.FontSize.Y,
|
||||
0, // GuiData->GuiInfo.FontSize.X,
|
||||
0,
|
||||
TA_BASELINE,
|
||||
GuiData->GuiInfo.FontWeight,
|
||||
|
|
|
@ -98,8 +98,8 @@ GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
|
|||
}
|
||||
else if (!wcscmp(szValueName, L"FontSize"))
|
||||
{
|
||||
TermInfo->FontSize.X = LOWORD(Value);
|
||||
TermInfo->FontSize.Y = HIWORD(Value);
|
||||
TermInfo->FontSize.X = LOWORD(Value); // Width
|
||||
TermInfo->FontSize.Y = HIWORD(Value); // Height
|
||||
RetVal = TRUE;
|
||||
}
|
||||
else if (!wcscmp(szValueName, L"FontWeight"))
|
||||
|
@ -161,7 +161,7 @@ do {
|
|||
SetConsoleSetting(L"FaceName", REG_SZ, (wcslen(TermInfo->FaceName) + 1) * sizeof(WCHAR), TermInfo->FaceName, L'\0'); // wcsnlen
|
||||
SetConsoleSetting(L"FontFamily", REG_DWORD, sizeof(DWORD), &TermInfo->FontFamily, FF_DONTCARE);
|
||||
|
||||
Storage = MAKELONG(TermInfo->FontSize.X, TermInfo->FontSize.Y);
|
||||
Storage = MAKELONG(TermInfo->FontSize.X, TermInfo->FontSize.Y); // Width, Height
|
||||
SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &Storage, 0);
|
||||
|
||||
SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &TermInfo->FontWeight, FW_DONTCARE);
|
||||
|
@ -197,7 +197,7 @@ GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
|
|||
* 1. Load the default values
|
||||
*/
|
||||
// wcsncpy(TermInfo->FaceName, L"DejaVu Sans Mono", LF_FACESIZE);
|
||||
// TermInfo->FontSize = MAKELONG(12, 8); // 0x0008000C; // font is 8x12
|
||||
// TermInfo->FontSize = MAKELONG(8, 12); // 0x000C0008; // font is 8x12
|
||||
// TermInfo->FontSize = MAKELONG(16, 16); // font is 16x16
|
||||
// TermInfo->FontWeight = FW_NORMAL;
|
||||
|
||||
|
@ -207,7 +207,6 @@ GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
|
|||
TermInfo->FontSize.X = 0;
|
||||
TermInfo->FontSize.Y = 0;
|
||||
TermInfo->FontWeight = FW_DONTCARE;
|
||||
TermInfo->UseRasterFonts = TRUE;
|
||||
|
||||
TermInfo->FullScreen = FALSE;
|
||||
TermInfo->ShowWindow = SW_SHOWNORMAL;
|
||||
|
@ -333,7 +332,6 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
|||
GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily;
|
||||
GuiInfo->FontSize = GuiData->GuiInfo.FontSize;
|
||||
GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
|
||||
GuiInfo->UseRasterFonts = GuiData->GuiInfo.UseRasterFonts;
|
||||
GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen;
|
||||
GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
|
||||
GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
|
||||
|
@ -420,6 +418,92 @@ Quit:
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL
|
||||
ChangeFont(PGUI_CONSOLE_DATA GuiData,
|
||||
LPWSTR FaceName, // Points to a WCHAR array of LF_FACESIZE elements.
|
||||
ULONG FontFamily,
|
||||
COORD FontSize,
|
||||
ULONG FontWeight)
|
||||
{
|
||||
HDC hDC;
|
||||
HFONT OldFont, NewFont;
|
||||
TEXTMETRICW Metrics;
|
||||
SIZE CharSize;
|
||||
SIZE_T Length;
|
||||
|
||||
NewFont = CreateFontW(FontSize.Y,
|
||||
0, // FontSize.X,
|
||||
0,
|
||||
TA_BASELINE,
|
||||
FontWeight,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
OEM_CHARSET,
|
||||
OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
NONANTIALIASED_QUALITY,
|
||||
FIXED_PITCH | FontFamily /* FF_DONTCARE */,
|
||||
FaceName);
|
||||
if (NewFont == NULL)
|
||||
{
|
||||
DPRINT1("ChangeFont: CreateFont failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hDC = GetDC(GuiData->hWindow);
|
||||
if (hDC == NULL)
|
||||
{
|
||||
DPRINT1("ChangeFont: GetDC failed\n");
|
||||
DeleteObject(NewFont);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
OldFont = SelectObject(hDC, NewFont);
|
||||
if (OldFont == NULL)
|
||||
{
|
||||
DPRINT1("ChangeFont: SelectObject failed\n");
|
||||
ReleaseDC(GuiData->hWindow, hDC);
|
||||
DeleteObject(NewFont);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!GetTextMetricsW(hDC, &Metrics))
|
||||
{
|
||||
DPRINT1("ChangeFont: GetTextMetrics failed\n");
|
||||
SelectObject(hDC, OldFont);
|
||||
ReleaseDC(GuiData->hWindow, hDC);
|
||||
DeleteObject(NewFont);
|
||||
return FALSE;
|
||||
}
|
||||
GuiData->CharWidth = Metrics.tmMaxCharWidth;
|
||||
GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
|
||||
|
||||
/* Measure real char width more precisely if possible. */
|
||||
if (GetTextExtentPoint32W(hDC, L"R", 1, &CharSize))
|
||||
GuiData->CharWidth = CharSize.cx;
|
||||
|
||||
SelectObject(hDC, OldFont);
|
||||
ReleaseDC(GuiData->hWindow, hDC);
|
||||
|
||||
if (GuiData->Font != NULL) DeleteObject(GuiData->Font);
|
||||
GuiData->Font = NewFont;
|
||||
|
||||
Length = min(wcslen(FaceName) + 1, LF_FACESIZE); // wcsnlen
|
||||
wcsncpy(GuiData->GuiInfo.FaceName, FaceName, LF_FACESIZE);
|
||||
GuiData->GuiInfo.FaceName[Length] = L'\0'; // NULL-terminate
|
||||
GuiData->GuiInfo.FontFamily = FontFamily;
|
||||
GuiData->GuiInfo.FontSize = FontSize;
|
||||
GuiData->GuiInfo.FontWeight = FontWeight;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
|
||||
HANDLE hClientSection,
|
||||
|
@ -501,6 +585,15 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
|
|||
|
||||
// memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));
|
||||
|
||||
/* Change the font */
|
||||
ChangeFont(GuiData,
|
||||
GuiInfo->FaceName,
|
||||
GuiInfo->FontFamily,
|
||||
GuiInfo->FontSize,
|
||||
GuiInfo->FontWeight);
|
||||
// HACK, needed because changing font may change the size of the window
|
||||
/**/TermResizeTerminal(Console);/**/
|
||||
|
||||
/* Move the window to the user's values */
|
||||
GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition;
|
||||
GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin;
|
||||
|
@ -655,7 +748,6 @@ GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData,
|
|||
GuiInfo.FullScreen = !!pConInfo->FullScreen;
|
||||
GuiInfo.AutoPosition = !!pConInfo->AutoPosition;
|
||||
GuiInfo.WindowOrigin = pConInfo->WindowPosition;
|
||||
// BOOL GuiInfo.UseRasterFonts = pConInfo->
|
||||
// WORD GuiInfo.ShowWindow = pConInfo->
|
||||
|
||||
|
||||
|
@ -675,6 +767,15 @@ GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData,
|
|||
|
||||
// memcpy(&GuiData->GuiInfo, &GuiInfo, sizeof(GUI_CONSOLE_INFO));
|
||||
|
||||
/* Change the font */
|
||||
ChangeFont(GuiData,
|
||||
GuiInfo.FaceName,
|
||||
GuiInfo.FontFamily,
|
||||
GuiInfo.FontSize,
|
||||
GuiInfo.FontWeight);
|
||||
// HACK, needed because changing font may change the size of the window
|
||||
/**/TermResizeTerminal(Console);/**/
|
||||
|
||||
/* Move the window to the user's values */
|
||||
GuiData->GuiInfo.AutoPosition = GuiInfo.AutoPosition;
|
||||
GuiData->GuiInfo.WindowOrigin = GuiInfo.WindowOrigin;
|
||||
|
|
|
@ -34,7 +34,6 @@ typedef struct _GUI_CONSOLE_INFO
|
|||
ULONG FontFamily;
|
||||
COORD FontSize;
|
||||
ULONG FontWeight;
|
||||
BOOL UseRasterFonts;
|
||||
|
||||
BOOL FullScreen; /* Whether the console is displayed in full-screen or windowed mode */
|
||||
// ULONG HardwareState; /* _GDI_MANAGED, _DIRECT */
|
||||
|
|
|
@ -486,13 +486,15 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
* Set up GUI data
|
||||
*/
|
||||
|
||||
// Font data
|
||||
Length = min(wcslen(TermInfo.FaceName) + 1, LF_FACESIZE); // wcsnlen
|
||||
wcsncpy(GuiData->GuiInfo.FaceName, TermInfo.FaceName, LF_FACESIZE);
|
||||
GuiData->GuiInfo.FaceName[Length] = L'\0';
|
||||
GuiData->GuiInfo.FontFamily = TermInfo.FontFamily;
|
||||
GuiData->GuiInfo.FontSize = TermInfo.FontSize;
|
||||
GuiData->GuiInfo.FontWeight = TermInfo.FontWeight;
|
||||
GuiData->GuiInfo.UseRasterFonts = TermInfo.UseRasterFonts;
|
||||
|
||||
// Display
|
||||
GuiData->GuiInfo.FullScreen = TermInfo.FullScreen;
|
||||
GuiData->GuiInfo.ShowWindow = TermInfo.ShowWindow;
|
||||
GuiData->GuiInfo.AutoPosition = TermInfo.AutoPosition;
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
COLORREF PaletteRGBFromAttrib(PCONSOLE Console, WORD Attribute)
|
||||
static COLORREF
|
||||
PaletteRGBFromAttrib(PCONSOLE Console, WORD Attribute)
|
||||
{
|
||||
HPALETTE hPalette = Console->ActiveBuffer->PaletteHandle;
|
||||
PALETTEENTRY pe;
|
||||
|
@ -35,6 +36,44 @@ COLORREF PaletteRGBFromAttrib(PCONSOLE Console, WORD Attribute)
|
|||
return PALETTERGB(pe.peRed, pe.peGreen, pe.peBlue);
|
||||
}
|
||||
|
||||
static HFONT
|
||||
ChangeFontAttributes(PGUI_CONSOLE_DATA GuiData,
|
||||
// COORD FontSize,
|
||||
ULONG FontWeight,
|
||||
BOOLEAN bItalic,
|
||||
BOOLEAN bUnderline,
|
||||
BOOLEAN bStrikeOut)
|
||||
{
|
||||
HFONT NewFont;
|
||||
LOGFONT lf;
|
||||
|
||||
/* Initialize the LOGFONT structure */
|
||||
RtlZeroMemory(&lf, sizeof(lf));
|
||||
|
||||
/* Retrieve the details of the current font */
|
||||
if (GetObject(GuiData->Font, sizeof(lf), &lf) == 0)
|
||||
return NULL; // GuiData->Font;
|
||||
|
||||
/* Change the font attributes */
|
||||
// lf.lfHeight = FontSize.Y;
|
||||
// lf.lfWidth = FontSize.X;
|
||||
lf.lfWeight = FontWeight;
|
||||
lf.lfItalic = bItalic;
|
||||
lf.lfUnderline = bUnderline;
|
||||
lf.lfStrikeOut = bStrikeOut;
|
||||
|
||||
/* Build a new font */
|
||||
NewFont = CreateFontIndirect(&lf);
|
||||
if (NewFont == NULL)
|
||||
return NULL; // GuiData->Font;
|
||||
|
||||
// FIXME: Do we need to update GuiData->CharWidth and GuiData->CharHeight ??
|
||||
|
||||
/* Select it (return the old font) */
|
||||
// return SelectObject(GuiData->hMemDC, NewFont);
|
||||
return NewFont;
|
||||
}
|
||||
|
||||
static VOID
|
||||
CopyBlock(PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||
PSMALL_RECT Selection)
|
||||
|
@ -348,7 +387,8 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
|
|||
WORD LastAttribute, Attribute;
|
||||
ULONG CursorX, CursorY, CursorHeight;
|
||||
HBRUSH CursorBrush, OldBrush;
|
||||
HFONT OldFont;
|
||||
HFONT OldFont, NewFont;
|
||||
BOOLEAN IsUnderscore;
|
||||
|
||||
if (Buffer->Buffer == NULL) return;
|
||||
|
||||
|
@ -372,7 +412,18 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
|
|||
SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute)));
|
||||
SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute)));
|
||||
|
||||
OldFont = SelectObject(GuiData->hMemDC, GuiData->Font);
|
||||
// OldFont = ChangeFontAttributes(GuiData, /* {0}, */ GuiData->GuiInfo.FontWeight, FALSE, FALSE, FALSE);
|
||||
IsUnderscore = !!(LastAttribute & COMMON_LVB_UNDERSCORE);
|
||||
NewFont = ChangeFontAttributes(GuiData, /* {0}, */ GuiData->GuiInfo.FontWeight,
|
||||
FALSE,
|
||||
IsUnderscore,
|
||||
FALSE);
|
||||
if (NewFont == NULL)
|
||||
{
|
||||
DPRINT1("ChangeFontAttributes failed, use the original font\n");
|
||||
NewFont = GuiData->Font;
|
||||
}
|
||||
OldFont = SelectObject(GuiData->hMemDC, NewFont);
|
||||
|
||||
for (Line = TopLine; Line <= BottomLine; Line++)
|
||||
{
|
||||
|
@ -399,9 +450,31 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
|
|||
Attribute = From->Attributes;
|
||||
if (Attribute != LastAttribute)
|
||||
{
|
||||
SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(Attribute)));
|
||||
SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute)));
|
||||
LastAttribute = Attribute;
|
||||
SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute)));
|
||||
SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute)));
|
||||
|
||||
/* Change underscore state if needed */
|
||||
if (!!(LastAttribute & COMMON_LVB_UNDERSCORE) != IsUnderscore)
|
||||
{
|
||||
IsUnderscore = !!(LastAttribute & COMMON_LVB_UNDERSCORE);
|
||||
|
||||
/* Delete the font we used up to now */
|
||||
// SelectObject(GuiData->hMemDC, OldFont);
|
||||
if (NewFont != GuiData->Font) DeleteObject(NewFont);
|
||||
/* Recreate it */
|
||||
NewFont = ChangeFontAttributes(GuiData, /* {0}, */ GuiData->GuiInfo.FontWeight,
|
||||
FALSE,
|
||||
IsUnderscore,
|
||||
FALSE);
|
||||
if (NewFont == NULL)
|
||||
{
|
||||
DPRINT1("ChangeFontAttributes failed, use the original font\n");
|
||||
NewFont = GuiData->Font;
|
||||
}
|
||||
/* Select it */
|
||||
/* OldFont = */ SelectObject(GuiData->hMemDC, NewFont);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -441,12 +514,15 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
|
|||
GuiData->CharWidth,
|
||||
CursorHeight,
|
||||
PATCOPY);
|
||||
|
||||
SelectObject(GuiData->hMemDC, OldBrush);
|
||||
DeleteObject(CursorBrush);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the old font and delete the font we used up to now */
|
||||
SelectObject(GuiData->hMemDC, OldFont);
|
||||
if (NewFont != GuiData->Font) DeleteObject(NewFont);
|
||||
|
||||
LeaveCriticalSection(&Console->Lock);
|
||||
}
|
||||
|
|
|
@ -19,53 +19,45 @@
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
/* Console handle */
|
||||
typedef struct _CONSOLE_IO_HANDLE
|
||||
{
|
||||
PCONSOLE_IO_OBJECT Object; /* The object on which the handle points to */
|
||||
DWORD Access;
|
||||
BOOL Inheritable;
|
||||
DWORD ShareMode;
|
||||
ULONG Access;
|
||||
ULONG ShareMode;
|
||||
BOOLEAN Inheritable;
|
||||
} CONSOLE_IO_HANDLE, *PCONSOLE_IO_HANDLE;
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static INT
|
||||
AdjustHandleCounts(PCONSOLE_IO_HANDLE Entry, INT Change)
|
||||
static LONG
|
||||
AdjustHandleCounts(IN PCONSOLE_IO_HANDLE Handle,
|
||||
IN LONG Change)
|
||||
{
|
||||
PCONSOLE_IO_OBJECT Object = Entry->Object;
|
||||
PCONSOLE_IO_OBJECT Object = Handle->Object;
|
||||
|
||||
DPRINT("AdjustHandleCounts(0x%p, %d), Object = 0x%p\n", Entry, Change, Object);
|
||||
DPRINT("\tAdjustHandleCounts(0x%p, %d), Object = 0x%p, Object->HandleCount = %d, Object->Type = %lu\n", Entry, Change, Object, Object->HandleCount, Object->Type);
|
||||
DPRINT("AdjustHandleCounts(0x%p, %d), Object = 0x%p\n",
|
||||
Handle, Change, Object);
|
||||
DPRINT("\tAdjustHandleCounts(0x%p, %d), Object = 0x%p, Object->ReferenceCount = %d, Object->Type = %lu\n",
|
||||
Handle, Change, Object, Object->ReferenceCount, Object->Type);
|
||||
|
||||
if (Entry->Access & GENERIC_READ) Object->AccessRead += Change;
|
||||
if (Entry->Access & GENERIC_WRITE) Object->AccessWrite += Change;
|
||||
if (!(Entry->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change;
|
||||
if (!(Entry->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change;
|
||||
if (Handle->Access & GENERIC_READ) Object->AccessRead += Change;
|
||||
if (Handle->Access & GENERIC_WRITE) Object->AccessWrite += Change;
|
||||
if (!(Handle->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change;
|
||||
if (!(Handle->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change;
|
||||
|
||||
Object->HandleCount += Change;
|
||||
Object->ReferenceCount += Change;
|
||||
|
||||
return Object->HandleCount;
|
||||
return Object->ReferenceCount;
|
||||
}
|
||||
|
||||
static VOID
|
||||
ConSrvCreateHandleEntry(PCONSOLE_IO_HANDLE Entry)
|
||||
ConSrvCloseHandle(IN PCONSOLE_IO_HANDLE Handle)
|
||||
{
|
||||
/// LOCK /// PCONSOLE_IO_OBJECT Object = Entry->Object;
|
||||
/// LOCK /// EnterCriticalSection(&Object->Console->Lock);
|
||||
AdjustHandleCounts(Entry, +1);
|
||||
/// LOCK /// LeaveCriticalSection(&Object->Console->Lock);
|
||||
}
|
||||
|
||||
static VOID
|
||||
ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
|
||||
{
|
||||
PCONSOLE_IO_OBJECT Object = Entry->Object;
|
||||
PCONSOLE_IO_OBJECT Object = Handle->Object;
|
||||
if (Object != NULL)
|
||||
{
|
||||
/// LOCK /// PCONSOLE Console = Object->Console;
|
||||
/// LOCK /// EnterCriticalSection(&Console->Lock);
|
||||
|
||||
/*
|
||||
* If this is a input handle, notify and dereference
|
||||
* all the waits related to this handle.
|
||||
|
@ -87,7 +79,7 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
|
|||
CsrNotifyWait(&Console->ReadWaitQueue,
|
||||
TRUE,
|
||||
NULL,
|
||||
(PVOID)Entry);
|
||||
(PVOID)Handle);
|
||||
if (!IsListEmpty(&Console->ReadWaitQueue))
|
||||
{
|
||||
CsrDereferenceWait(&Console->ReadWaitQueue);
|
||||
|
@ -95,7 +87,7 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
|
|||
}
|
||||
|
||||
/* If the last handle to a screen buffer is closed, delete it... */
|
||||
if (AdjustHandleCounts(Entry, -1) == 0)
|
||||
if (AdjustHandleCounts(Handle, -1) == 0)
|
||||
{
|
||||
if (Object->Type == TEXTMODE_BUFFER || Object->Type == GRAPHICS_BUFFER)
|
||||
{
|
||||
|
@ -116,16 +108,18 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
|
|||
}
|
||||
}
|
||||
|
||||
/// LOCK /// LeaveCriticalSection(&Console->Lock);
|
||||
|
||||
/* Invalidate (zero-out) this handle entry */
|
||||
// Entry->Object = NULL;
|
||||
// RtlZeroMemory(Entry, sizeof(*Entry));
|
||||
// Handle->Object = NULL;
|
||||
// RtlZeroMemory(Handle, sizeof(*Handle));
|
||||
}
|
||||
RtlZeroMemory(Entry, sizeof(*Entry)); // Be sure the whole entry is invalidated.
|
||||
RtlZeroMemory(Handle, sizeof(*Handle)); // Be sure the whole entry is invalidated.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Forward declaration, used in ConSrvInitHandlesTable */
|
||||
static VOID ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData);
|
||||
|
||||
|
@ -244,10 +238,10 @@ ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
|
|||
{
|
||||
/*
|
||||
* Copy the handle data and increment the reference count of the
|
||||
* pointed object (via the call to ConSrvCreateHandleEntry).
|
||||
* pointed object (via the call to ConSrvCreateHandleEntry == AdjustHandleCounts).
|
||||
*/
|
||||
TargetProcessData->HandleTable[j] = SourceProcessData->HandleTable[i];
|
||||
ConSrvCreateHandleEntry(&TargetProcessData->HandleTable[j]);
|
||||
AdjustHandleCounts(&TargetProcessData->HandleTable[j], +1);
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +252,7 @@ Quit:
|
|||
}
|
||||
|
||||
static VOID
|
||||
ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
|
||||
ConSrvFreeHandlesTable(IN PCONSOLE_PROCESS_DATA ProcessData)
|
||||
{
|
||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
|
@ -277,7 +271,7 @@ ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
|
|||
/* Close all the console handles */
|
||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
||||
{
|
||||
ConSrvCloseHandleEntry(&ProcessData->HandleTable[i]);
|
||||
ConSrvCloseHandle(&ProcessData->HandleTable[i]);
|
||||
}
|
||||
}
|
||||
/* Free the handles table memory */
|
||||
|
@ -290,6 +284,12 @@ ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
|
|||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ConSrvCreateObject
|
||||
VOID
|
||||
ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object,
|
||||
IN CONSOLE_IO_OBJECT_TYPE Type,
|
||||
|
@ -300,18 +300,19 @@ ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object,
|
|||
|
||||
Object->Type = Type;
|
||||
Object->Console = Console;
|
||||
Object->ReferenceCount = 0;
|
||||
|
||||
Object->AccessRead = Object->AccessWrite = 0;
|
||||
Object->ExclusiveRead = Object->ExclusiveWrite = 0;
|
||||
Object->HandleCount = 0;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
PHANDLE Handle,
|
||||
PCONSOLE_IO_OBJECT Object,
|
||||
DWORD Access,
|
||||
BOOL Inheritable,
|
||||
DWORD ShareMode)
|
||||
ConSrvInsertObject(IN PCONSOLE_PROCESS_DATA ProcessData,
|
||||
OUT PHANDLE Handle,
|
||||
IN PCONSOLE_IO_OBJECT Object,
|
||||
IN ULONG Access,
|
||||
IN BOOLEAN Inheritable,
|
||||
IN ULONG ShareMode)
|
||||
{
|
||||
#define IO_HANDLES_INCREMENT 2 * 3
|
||||
|
||||
|
@ -362,7 +363,7 @@ ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
ProcessData->HandleTable[i].Access = Access;
|
||||
ProcessData->HandleTable[i].Inheritable = Inheritable;
|
||||
ProcessData->HandleTable[i].ShareMode = ShareMode;
|
||||
ConSrvCreateHandleEntry(&ProcessData->HandleTable[i]);
|
||||
AdjustHandleCounts(&ProcessData->HandleTable[i], +1);
|
||||
*Handle = ULongToHandle((i << 2) | 0x3);
|
||||
|
||||
// RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
@ -371,8 +372,8 @@ ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
HANDLE Handle)
|
||||
ConSrvRemoveObject(IN PCONSOLE_PROCESS_DATA ProcessData,
|
||||
IN HANDLE Handle)
|
||||
{
|
||||
ULONG Index = HandleToULong(Handle) >> 2;
|
||||
|
||||
|
@ -390,20 +391,20 @@ ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
}
|
||||
|
||||
ASSERT(ProcessData->ConsoleHandle);
|
||||
ConSrvCloseHandleEntry(&ProcessData->HandleTable[Index]);
|
||||
ConSrvCloseHandle(&ProcessData->HandleTable[Index]);
|
||||
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
HANDLE Handle,
|
||||
PCONSOLE_IO_OBJECT* Object,
|
||||
PVOID* Entry OPTIONAL,
|
||||
DWORD Access,
|
||||
BOOL LockConsole,
|
||||
CONSOLE_IO_OBJECT_TYPE Type)
|
||||
ConSrvGetObject(IN PCONSOLE_PROCESS_DATA ProcessData,
|
||||
IN HANDLE Handle,
|
||||
OUT PCONSOLE_IO_OBJECT* Object,
|
||||
OUT PVOID* Entry OPTIONAL,
|
||||
IN ULONG Access,
|
||||
IN BOOLEAN LockConsole,
|
||||
IN CONSOLE_IO_OBJECT_TYPE Type)
|
||||
{
|
||||
// NTSTATUS Status;
|
||||
ULONG Index = HandleToULong(Handle) >> 2;
|
||||
|
@ -461,12 +462,17 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
}
|
||||
|
||||
VOID
|
||||
ConSrvReleaseObject(PCONSOLE_IO_OBJECT Object,
|
||||
BOOL IsConsoleLocked)
|
||||
ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object,
|
||||
IN BOOLEAN IsConsoleLocked)
|
||||
{
|
||||
ConSrvReleaseConsole(Object->Console, IsConsoleLocked);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
PHANDLE pInputHandle,
|
||||
|
@ -548,7 +554,7 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
NTSTATUS
|
||||
ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
HANDLE ConsoleHandle,
|
||||
BOOL CreateNewHandlesTable,
|
||||
BOOLEAN CreateNewHandlesTable,
|
||||
PHANDLE pInputHandle,
|
||||
PHANDLE pOutputHandle,
|
||||
PHANDLE pErrorHandle)
|
||||
|
@ -826,7 +832,7 @@ CSR_API(SrvDuplicateHandle)
|
|||
(DuplicateHandleRequest->Options & DUPLICATE_CLOSE_SOURCE))
|
||||
{
|
||||
/* Close the original handle if needed */
|
||||
ConSrvCloseHandleEntry(Entry);
|
||||
ConSrvCloseHandle(Entry);
|
||||
}
|
||||
|
||||
Quit:
|
||||
|
|
|
@ -10,23 +10,28 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
VOID ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object,
|
||||
IN CONSOLE_IO_OBJECT_TYPE Type,
|
||||
IN PCONSOLE Console);
|
||||
NTSTATUS ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
PHANDLE Handle,
|
||||
PCONSOLE_IO_OBJECT Object,
|
||||
DWORD Access,
|
||||
BOOL Inheritable,
|
||||
DWORD ShareMode);
|
||||
NTSTATUS ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
HANDLE Handle);
|
||||
NTSTATUS ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
HANDLE Handle,
|
||||
PCONSOLE_IO_OBJECT* Object,
|
||||
PVOID* Entry OPTIONAL,
|
||||
DWORD Access,
|
||||
BOOL LockConsole,
|
||||
CONSOLE_IO_OBJECT_TYPE Type);
|
||||
VOID ConSrvReleaseObject(PCONSOLE_IO_OBJECT Object,
|
||||
BOOL IsConsoleLocked);
|
||||
VOID
|
||||
ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object,
|
||||
IN CONSOLE_IO_OBJECT_TYPE Type,
|
||||
IN PCONSOLE Console);
|
||||
NTSTATUS
|
||||
ConSrvInsertObject(IN PCONSOLE_PROCESS_DATA ProcessData,
|
||||
OUT PHANDLE Handle,
|
||||
IN PCONSOLE_IO_OBJECT Object,
|
||||
IN ULONG Access,
|
||||
IN BOOLEAN Inheritable,
|
||||
IN ULONG ShareMode);
|
||||
NTSTATUS
|
||||
ConSrvRemoveObject(IN PCONSOLE_PROCESS_DATA ProcessData,
|
||||
IN HANDLE Handle);
|
||||
NTSTATUS
|
||||
ConSrvGetObject(IN PCONSOLE_PROCESS_DATA ProcessData,
|
||||
IN HANDLE Handle,
|
||||
OUT PCONSOLE_IO_OBJECT* Object,
|
||||
OUT PVOID* Entry OPTIONAL,
|
||||
IN ULONG Access,
|
||||
IN BOOLEAN LockConsole,
|
||||
IN CONSOLE_IO_OBJECT_TYPE Type);
|
||||
VOID
|
||||
ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object,
|
||||
IN BOOLEAN IsConsoleLocked);
|
||||
|
|
|
@ -19,23 +19,35 @@
|
|||
#define DEFAULT_POPUP_ATTRIB (FOREGROUND_BLUE | FOREGROUND_RED | \
|
||||
BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
|
||||
|
||||
/* VGA character cell */
|
||||
typedef struct _CHAR_CELL
|
||||
{
|
||||
CHAR Char;
|
||||
BYTE Attributes;
|
||||
} CHAR_CELL, *PCHAR_CELL;
|
||||
C_ASSERT(sizeof(CHAR_CELL) == 2);
|
||||
|
||||
|
||||
/* Object type magic numbers */
|
||||
typedef enum _CONSOLE_IO_OBJECT_TYPE
|
||||
{
|
||||
// ANY_TYPE_BUFFER = 0x00, // --> Match any types of IO handles
|
||||
TEXTMODE_BUFFER = 0x01, // --> Output-type handles for text SBs
|
||||
GRAPHICS_BUFFER = 0x02, // --> Output-type handles for graphics SBs
|
||||
UNKNOWN = 0x00, // --> Unknown object
|
||||
TEXTMODE_BUFFER = 0x01, // --> Output-type object for text SBs
|
||||
GRAPHICS_BUFFER = 0x02, // --> Output-type object for graphics SBs
|
||||
SCREEN_BUFFER = 0x03, // --> Any SB type
|
||||
INPUT_BUFFER = 0x04 // --> Input-type handles
|
||||
INPUT_BUFFER = 0x04, // --> Input-type object
|
||||
ANY_TYPE_BUFFER = 0x07, // --> Any IO object
|
||||
} CONSOLE_IO_OBJECT_TYPE;
|
||||
|
||||
typedef struct _CONSOLE_IO_OBJECT
|
||||
{
|
||||
CONSOLE_IO_OBJECT_TYPE Type;
|
||||
|
||||
struct _CONSOLE* /* PCONSOLE */ Console;
|
||||
LONG ReferenceCount; /* Is incremented each time a console object gets referenced */
|
||||
|
||||
LONG AccessRead, AccessWrite;
|
||||
LONG ExclusiveRead, ExclusiveWrite;
|
||||
LONG HandleCount;
|
||||
} CONSOLE_IO_OBJECT, *PCONSOLE_IO_OBJECT;
|
||||
|
||||
|
||||
|
@ -300,6 +312,17 @@ typedef struct _CONSOLE
|
|||
PCONSOLE_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */
|
||||
UINT OutputCodePage;
|
||||
|
||||
/**** Per-console Virtual DOS Machine Text-mode Buffer ****/
|
||||
COORD VDMBufferSize; /* Real size of the VDM buffer, in units of ??? */
|
||||
HANDLE VDMBufferSection; /* Handle to the memory shared section for the VDM buffer */
|
||||
PVOID VDMBuffer; /* Our VDM buffer */
|
||||
PVOID ClientVDMBuffer; /* A copy of the client view of our VDM buffer */
|
||||
HANDLE VDMClientProcess; /* Handle to the client process who opened the buffer, to unmap the view */
|
||||
|
||||
HANDLE StartHardwareEvent;
|
||||
HANDLE EndHardwareEvent;
|
||||
HANDLE ErrorHardwareEvent;
|
||||
|
||||
/****************************** Other properties ******************************/
|
||||
UNICODE_STRING OriginalTitle; /* Original title of console, the one defined when the console leader is launched; it never changes. Always NULL-terminated */
|
||||
UNICODE_STRING Title; /* Title of console. Always NULL-terminated */
|
||||
|
|
|
@ -83,6 +83,7 @@ struct _FRONTEND
|
|||
PFRONTEND_VTBL Vtbl; /* Virtual table */
|
||||
NTSTATUS (NTAPI *UnloadFrontEnd)(IN OUT PFRONTEND This);
|
||||
|
||||
// struct _WINSRV_CONSOLE*
|
||||
struct _CONSOLE* Console; /* Console to which the frontend is attached to */
|
||||
PVOID Data; /* Private data */
|
||||
PVOID OldData; /* Reserved */
|
||||
|
|
|
@ -51,10 +51,14 @@ typedef struct _CONSOLE_INFO
|
|||
WCHAR ConsoleTitle[MAX_PATH + 1];
|
||||
} CONSOLE_INFO, *PCONSOLE_INFO;
|
||||
|
||||
/*
|
||||
* BYTE Foreground = LOBYTE(Attributes) & 0x0F;
|
||||
* BYTE Background = (LOBYTE(Attributes) & 0xF0) >> 4;
|
||||
*/
|
||||
#define RGBFromAttrib(Console, Attribute) ((Console)->Colors[(Attribute) & 0xF])
|
||||
#define TextAttribFromAttrib(Attribute) ((Attribute) & 0xF)
|
||||
#define BkgdAttribFromAttrib(Attribute) (((Attribute) >> 4) & 0xF)
|
||||
#define MakeAttrib(TextAttrib, BkgdAttrib) (DWORD)((((BkgdAttrib) & 0xF) << 4) | ((TextAttrib) & 0xF))
|
||||
#define TextAttribFromAttrib(Attribute) ( !((Attribute) & COMMON_LVB_REVERSE_VIDEO) ? (Attribute) & 0xF : ((Attribute) >> 4) & 0xF )
|
||||
#define BkgdAttribFromAttrib(Attribute) ( !((Attribute) & COMMON_LVB_REVERSE_VIDEO) ? ((Attribute) >> 4) & 0xF : (Attribute) & 0xF )
|
||||
#define MakeAttrib(TextAttrib, BkgdAttrib) (USHORT)((((BkgdAttrib) & 0xF) << 4) | ((TextAttrib) & 0xF))
|
||||
|
||||
/*
|
||||
* Structure used to communicate with console.dll
|
||||
|
|
|
@ -15,7 +15,7 @@ NTSTATUS ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
PCONSOLE_START_INFO ConsoleStartInfo);
|
||||
NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
HANDLE ConsoleHandle,
|
||||
BOOL CreateNewHandlesTable,
|
||||
BOOLEAN CreateNewHandlesTable,
|
||||
PHANDLE pInputHandle,
|
||||
PHANDLE pOutputHandle,
|
||||
PHANDLE pErrorHandle);
|
||||
|
|
|
@ -21,8 +21,132 @@
|
|||
|
||||
CSR_API(SrvRegisterConsoleVDM)
|
||||
{
|
||||
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_REGISTERVDM RegisterVDMRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.RegisterVDMRequest;
|
||||
PCONSOLE Console;
|
||||
|
||||
DPRINT1("SrvRegisterConsoleVDM(%d)\n", RegisterVDMRequest->RegisterFlags);
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Can't get console\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RegisterVDMRequest->RegisterFlags != 0)
|
||||
{
|
||||
LARGE_INTEGER SectionSize;
|
||||
ULONG Size, ViewSize = 0;
|
||||
HANDLE ProcessHandle;
|
||||
|
||||
/*
|
||||
* Remember the handle to the process so that we can close or unmap
|
||||
* correctly the allocated resources when the client releases the
|
||||
* screen buffer.
|
||||
*/
|
||||
ProcessHandle = CsrGetClientThread()->Process->ProcessHandle;
|
||||
Console->VDMClientProcess = ProcessHandle;
|
||||
|
||||
Console->VDMBufferSize = RegisterVDMRequest->VDMBufferSize;
|
||||
|
||||
Size = Console->VDMBufferSize.X * Console->VDMBufferSize.Y
|
||||
* sizeof(CHAR_CELL);
|
||||
|
||||
/*
|
||||
* Create a memory section for the VDM buffer, to share with the client.
|
||||
*/
|
||||
SectionSize.QuadPart = Size;
|
||||
Status = NtCreateSection(&Console->VDMBufferSection,
|
||||
SECTION_ALL_ACCESS,
|
||||
NULL,
|
||||
&SectionSize,
|
||||
PAGE_READWRITE,
|
||||
SEC_COMMIT,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status);
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a view for our needs.
|
||||
*/
|
||||
ViewSize = 0;
|
||||
Console->VDMBuffer = NULL;
|
||||
Status = NtMapViewOfSection(Console->VDMBufferSection,
|
||||
NtCurrentProcess(),
|
||||
(PVOID*)&Console->VDMBuffer,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&ViewSize,
|
||||
ViewUnmap,
|
||||
0,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
|
||||
NtClose(Console->VDMBufferSection);
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a view for the client. We must keep a trace of it so that
|
||||
* we can unmap it when the client releases the VDM buffer.
|
||||
*/
|
||||
ViewSize = 0;
|
||||
Console->ClientVDMBuffer = NULL;
|
||||
Status = NtMapViewOfSection(Console->VDMBufferSection,
|
||||
ProcessHandle,
|
||||
(PVOID*)&Console->ClientVDMBuffer,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&ViewSize,
|
||||
ViewUnmap,
|
||||
0,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), Console->VDMBuffer);
|
||||
NtClose(Console->VDMBufferSection);
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
// TODO: Duplicate the event handles.
|
||||
|
||||
RegisterVDMRequest->VDMBuffer = Console->ClientVDMBuffer;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RegisterFlags == 0 means we are unregistering the VDM */
|
||||
|
||||
// TODO: Close the duplicated handles.
|
||||
|
||||
if (Console->VDMBuffer)
|
||||
{
|
||||
/*
|
||||
* Uninitialize the graphics screen buffer
|
||||
* in the reverse way we initialized it.
|
||||
*/
|
||||
NtUnmapViewOfSection(Console->VDMClientProcess, Console->ClientVDMBuffer);
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), Console->VDMBuffer);
|
||||
NtClose(Console->VDMBufferSection);
|
||||
}
|
||||
Console->VDMBuffer = Console->ClientVDMBuffer = NULL;
|
||||
|
||||
Console->VDMBufferSize.X = Console->VDMBufferSize.Y = 0;
|
||||
}
|
||||
|
||||
Quit:
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvVDMConsoleOperation)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue