X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=win32ss%2Fuser%2Fwinsrv%2Fconsrv%2Ffrontends%2Ftui%2Ftuiterm.c;h=e66203ad7b84622f9b302a22fa75bcde993c899e;hp=4586f7db0e785474633e08a9da0ea53570977a74;hb=HEAD;hpb=25445ea35f5286c9367faa6bcac147ff4d371d2e diff --git a/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c index 4586f7db0e7..e0ecef01d38 100644 --- a/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c +++ b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c @@ -4,32 +4,69 @@ * FILE: win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c * PURPOSE: TUI Terminal Front-End - Virtual Consoles... * PROGRAMMERS: David Welch - * Gé van Geldorp + * Gé van Geldorp * Jeffrey Morlan * Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ #ifdef TUITERM_COMPILE -#include "consrv.h" -#include "include/conio.h" +#include + +// #include "include/conio.h" #include "include/console.h" #include "include/settings.h" #include "tuiterm.h" + +#include +#include #include #define NDEBUG #include -/* GLOBALS ********************************************************************/ +/* CAB FILE STRUCTURES ******************************************************/ -#define GetNextConsole(Console) \ - CONTAINING_RECORD(Console->Entry.Flink, TUI_CONSOLE_DATA, Entry) +typedef struct _CFHEADER +{ + ULONG Signature; // File signature 'MSCF' (CAB_SIGNATURE) + ULONG Reserved1; // Reserved field + ULONG CabinetSize; // Cabinet file size + ULONG Reserved2; // Reserved field + ULONG FileTableOffset; // Offset of first CFFILE + ULONG Reserved3; // Reserved field + USHORT Version; // Cabinet version (CAB_VERSION) + USHORT FolderCount; // Number of folders + USHORT FileCount; // Number of files + USHORT Flags; // Cabinet flags (CAB_FLAG_*) + USHORT SetID; // Cabinet set id + USHORT CabinetNumber; // Zero-based cabinet number +} CFHEADER, *PCFHEADER; + +typedef struct _CFFILE +{ + ULONG FileSize; // Uncompressed file size in bytes + ULONG FileOffset; // Uncompressed offset of file in the folder + USHORT FileControlID; // File control ID (CAB_FILE_*) + USHORT FileDate; // File date stamp, as used by DOS + USHORT FileTime; // File time stamp, as used by DOS + USHORT Attributes; // File attributes (CAB_ATTRIB_*) + /* After this is the NULL terminated filename */ + // CHAR FileName[ANYSIZE_ARRAY]; +} CFFILE, *PCFFILE; + +#define CAB_SIGNATURE 0x4643534D // "MSCF" +#define CAB_VERSION 0x0103 -#define GetPrevConsole(Console) \ - CONTAINING_RECORD(Console->Entry.Blink, TUI_CONSOLE_DATA, Entry) +/* GLOBALS ******************************************************************/ + +#define ConsoleOutputUnicodeToAnsiChar(Console, dChar, sWChar) \ +do { \ + ASSERT((ULONG_PTR)(dChar) != (ULONG_PTR)(sWChar)); \ + WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL); \ +} while (0) /* TUI Console Window Class name */ #define TUI_CONSOLE_WINDOW_CLASS L"TuiConsoleWindowClass" @@ -39,13 +76,22 @@ typedef struct _TUI_CONSOLE_DATA CRITICAL_SECTION Lock; LIST_ENTRY Entry; /* Entry in the list of virtual consoles */ // HANDLE hTuiInitEvent; + // HANDLE hTuiTermEvent; - HWND hWindow; /* Handle to the console's window (used for the window's procedure */ + HWND hWindow; /* Handle to the console's window (used for the window's procedure) */ - PCONSOLE Console; /* Pointer to the owned console */ + PCONSRV_CONSOLE Console; /* Pointer to the owned console */ + PCONSOLE_SCREEN_BUFFER ActiveBuffer; /* Pointer to the active screen buffer (then maybe the previous Console member is redundant?? Or not...) */ // TUI_CONSOLE_INFO TuiInfo; /* TUI terminal settings */ } TUI_CONSOLE_DATA, *PTUI_CONSOLE_DATA; +#define GetNextConsole(Console) \ + CONTAINING_RECORD(Console->Entry.Flink, TUI_CONSOLE_DATA, Entry) + +#define GetPrevConsole(Console) \ + CONTAINING_RECORD(Console->Entry.Blink, TUI_CONSOLE_DATA, Entry) + + /* List of the maintained virtual consoles and its lock */ static LIST_ENTRY VirtConsList; static PTUI_CONSOLE_DATA ActiveConsole; /* The active console on screen */ @@ -164,7 +210,8 @@ done: /**\ \******************************************************************************/ -static BOOL FASTCALL +#if 0 +static BOOL TuiSwapConsole(INT Next) { static PTUI_CONSOLE_DATA SwapConsole = NULL; /* Console we are thinking about swapping with */ @@ -230,8 +277,9 @@ TuiSwapConsole(INT Next) return FALSE; } } +#endif -static VOID FASTCALL +static VOID TuiCopyRect(PCHAR Dest, PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* Region) { UINT SrcDelta, DestDelta; @@ -244,7 +292,7 @@ TuiCopyRect(PCHAR Dest, PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* Region) DestDelta = ConioRectWidth(Region) * 2 /* 2 == sizeof(CHAR) + sizeof(BYTE) */; for (i = Region->Top; i <= Region->Bottom; i++) { - ConsoleUnicodeCharToAnsiChar(Buff->Header.Console, (PCHAR)Dest, &Src->Char.UnicodeChar); + ConsoleOutputUnicodeToAnsiChar(Buff->Header.Console, (PCHAR)Dest, &Src->Char.UnicodeChar); *(PBYTE)(Dest + 1) = (BYTE)Src->Attributes; Src += SrcDelta; @@ -261,7 +309,7 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { /* PTUI_CONSOLE_DATA TuiData = NULL; - PCONSOLE Console = NULL; + PCONSRV_CONSOLE Console = NULL; TuiData = TuiGetGuiData(hWnd); if (TuiData == NULL) return 0; @@ -276,7 +324,22 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_KEYUP: case WM_SYSKEYUP: { - if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE)) +#if 0 + if ((HIWORD(lParam) & KF_ALTDOWN) && wParam == VK_TAB) + { + // if ((HIWORD(lParam) & (KF_UP | KF_REPEAT)) != KF_REPEAT) + TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); + + break; + } + else if (wParam == VK_MENU /* && !Down */) + { + TuiSwapConsole(0); + break; + } +#endif + + if (ConDrvValidateConsoleUnsafe((PCONSOLE)ActiveConsole->Console, CONSOLE_RUNNING, TRUE)) { MSG Message; Message.hwnd = hWnd; @@ -292,7 +355,7 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_ACTIVATE: { - if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE)) + if (ConDrvValidateConsoleUnsafe((PCONSOLE)ActiveConsole->Console, CONSOLE_RUNNING, TRUE)) { if (LOWORD(wParam) != WA_INACTIVE) { @@ -312,10 +375,10 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } static DWORD NTAPI -TuiConsoleThread(PVOID Data) +TuiConsoleThread(PVOID Param) { - PTUI_CONSOLE_DATA TuiData = (PTUI_CONSOLE_DATA)Data; - PCONSOLE Console = TuiData->Console; + PTUI_CONSOLE_DATA TuiData = (PTUI_CONSOLE_DATA)Param; + PCONSRV_CONSOLE Console = TuiData->Console; HWND NewWindow; MSG msg; @@ -345,10 +408,224 @@ TuiConsoleThread(PVOID Data) return 0; } +static BOOLEAN +TuiSetConsoleOutputCP( + IN HANDLE hNtConddHandle, + IN UINT CodePage) +{ + static UINT LastLoadedCodepage = 0; + UNICODE_STRING FontFile = RTL_CONSTANT_STRING(L"\\SystemRoot\\vgafonts.cab"); + CHAR FontName[20]; + + NTSTATUS Status; + HANDLE FileHandle; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + // ULONG ReadCP; + PUCHAR FontBitField = NULL; + + /* CAB-specific data */ + HANDLE FileSectionHandle; + PUCHAR FileBuffer = NULL; + SIZE_T FileSize = 0; + PCFHEADER CabFileHeader; + union + { + PCFFILE CabFile; + PVOID Buffer; + } Data; + PCFFILE FoundFile = NULL; + PSTR FileName; + USHORT Index; + + if (CodePage == LastLoadedCodepage) + return TRUE; + + /* + * Open the *uncompressed* fonts archive file. + */ + InitializeObjectAttributes(&ObjectAttributes, + &FontFile, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_READ | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error: Cannot open '%wZ' (0x%lx)\n", &FontFile, Status); + return FALSE; + } + + /* + * Load it. + */ + Status = NtCreateSection(&FileSectionHandle, + SECTION_ALL_ACCESS, + 0, 0, + PAGE_READONLY, + SEC_COMMIT, + FileHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateSection failed (0x%lx)\n", Status); + goto Exit; + } + + Status = NtMapViewOfSection(FileSectionHandle, + NtCurrentProcess(), + (PVOID*)&FileBuffer, + 0, 0, NULL, + &FileSize, + ViewUnmap, + 0, + PAGE_READONLY); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtMapViewOfSection failed (0x%lx)\n", Status); + goto Exit; + } + + /* Wrap in SEH to protect against ill-formed file */ + _SEH2_TRY + { + DPRINT("Cabinet file '%wZ' opened and mapped to 0x%p\n", + &FontFile, FileBuffer); + + CabFileHeader = (PCFHEADER)FileBuffer; + + /* Validate the CAB file */ + if (FileSize <= sizeof(CFHEADER) || + CabFileHeader->Signature != CAB_SIGNATURE || + CabFileHeader->Version != CAB_VERSION || + CabFileHeader->FolderCount == 0 || + CabFileHeader->FileCount == 0 || + CabFileHeader->FileTableOffset < sizeof(CFHEADER)) + { + DPRINT1("Cabinet file '%wZ' has an invalid header\n", &FontFile); + Status = STATUS_UNSUCCESSFUL; + _SEH2_YIELD(goto Exit); + } + + /* + * Find the font file within the archive. + */ + RtlStringCbPrintfA(FontName, sizeof(FontName), + "%u-8x8.bin", CodePage); + + /* Read the file table, find the file of interest and the end of the table */ + Data.CabFile = (PCFFILE)(FileBuffer + CabFileHeader->FileTableOffset); + for (Index = 0; Index < CabFileHeader->FileCount; ++Index) + { + FileName = (PSTR)(Data.CabFile + 1); + + if (!FoundFile) + { + // Status = RtlCharToInteger(FileName, 0, &ReadCP); + // if (NT_SUCCESS(Status) && (ReadCP == CodePage)) + if (_stricmp(FontName, FileName) == 0) + { + /* We've got the correct file. Save the offset and + * loop through the rest of the file table to find + * the position, where the actual data starts. */ + FoundFile = Data.CabFile; + } + } + + /* Move to the next file (go past the filename NULL terminator) */ + Data.CabFile = (PCFFILE)(strchr(FileName, 0) + 1); + } + + if (!FoundFile) + { + DPRINT("File '%S' not found in cabinet '%wZ'\n", + FontName, &FontFile); + Status = STATUS_OBJECT_NAME_NOT_FOUND; + _SEH2_YIELD(goto Exit); + } + + /* + * Extract the font file. + */ + /* Verify the font file size; we only support a fixed 256-char 8-bit font */ + if (FoundFile->FileSize != 256 * 8) + { + DPRINT1("File of size %lu is not of the expected size %lu\n", + FoundFile->FileSize, 256 * 8); + Status = STATUS_INVALID_BUFFER_SIZE; + _SEH2_YIELD(goto Exit); + } + + FontBitField = RtlAllocateHeap(RtlGetProcessHeap(), 0, FoundFile->FileSize); + if (!FontBitField) + { + DPRINT1("ExAllocatePoolWithTag(%lu) failed\n", FoundFile->FileSize); + Status = STATUS_NO_MEMORY; + _SEH2_YIELD(goto Exit); + } + + /* 8 = Size of a CFFOLDER structure (see cabman). As we don't need + * the values of that structure, just increase the offset here. */ + Data.Buffer = (PVOID)((ULONG_PTR)Data.Buffer + 8); // sizeof(CFFOLDER); + Data.Buffer = (PVOID)((ULONG_PTR)Data.Buffer + FoundFile->FileOffset); + + /* Data.Buffer now points to the actual data of the RAW font */ + RtlCopyMemory(FontBitField, Data.Buffer, FoundFile->FileSize); + Status = STATUS_SUCCESS; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + DPRINT1("TuiSetConsoleOutputCP - Caught an exception, Status = 0x%08lx\n", Status); + } + _SEH2_END; + + /* + * Load the font. + */ + if (NT_SUCCESS(Status)) + { + ASSERT(FoundFile); + ASSERT(FontBitField); + Status = NtDeviceIoControlFile(hNtConddHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + IOCTL_CONSOLE_LOADFONT, + FontBitField, + FoundFile->FileSize, + NULL, + 0); + } + + if (FontBitField) + RtlFreeHeap(RtlGetProcessHeap(), 0, FontBitField); + +Exit: + if (FileBuffer) + NtUnmapViewOfSection(NtCurrentProcess(), FileBuffer); + + if (FileSectionHandle) + NtClose(FileSectionHandle); + + NtClose(FileHandle); + + if (NT_SUCCESS(Status)) + LastLoadedCodepage = CodePage; + + return NT_SUCCESS(Status); +} + static BOOL -TuiInit(DWORD OemCP) +TuiInit(IN UINT OemCP) { - BOOL Ret = FALSE; + BOOL Success; CONSOLE_SCREEN_BUFFER_INFO ScrInfo; DWORD BytesReturned; WNDCLASSEXW wc; @@ -361,6 +638,7 @@ TuiInit(DWORD OemCP) /* * Initialize the TUI front-end: * - load the console driver, + * - open BlueScreen device and enable it, * - set default screen attributes, * - grab the console size. */ @@ -371,15 +649,23 @@ TuiInit(DWORD OemCP) 0, NULL, OPEN_EXISTING, 0, NULL); - if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle) + if (ConsoleDeviceHandle == INVALID_HANDLE_VALUE) { DPRINT1("Failed to open BlueScreen.\n"); return FALSE; } - if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT, - &OemCP, sizeof(OemCP), NULL, 0, + Success = TRUE; + if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_RESET_SCREEN, + &Success, sizeof(Success), NULL, 0, &BytesReturned, NULL)) + { + DPRINT1("Failed to enable the screen.\n"); + CloseHandle(ConsoleDeviceHandle); + return FALSE; + } + + if (!TuiSetConsoleOutputCP(ConsoleDeviceHandle, OemCP)) { DPRINT1("Failed to load the font for codepage %d\n", OemCP); /* Let's suppose the font is good enough to continue */ @@ -389,7 +675,7 @@ TuiInit(DWORD OemCP) &TextAttribute, sizeof(TextAttribute), NULL, 0, &BytesReturned, NULL)) { - DPRINT1("Failed to set text attribute\n"); + DPRINT1("Failed to set text attribute.\n"); } ActiveConsole = NULL; @@ -399,8 +685,8 @@ TuiInit(DWORD OemCP) 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; + DPRINT1("Failed to get console info.\n"); + Success = FALSE; goto Quit; } PhysicalConsoleSize = ScrInfo.dwSize; @@ -416,23 +702,23 @@ TuiInit(DWORD OemCP) ConsoleClassAtom = RegisterClassExW(&wc); if (ConsoleClassAtom == 0) { - DPRINT1("Failed to register TUI console wndproc\n"); - Ret = FALSE; + DPRINT1("Failed to register TUI console wndproc.\n"); + Success = FALSE; } else { - Ret = TRUE; + Success = TRUE; } Quit: - if (Ret == FALSE) + if (!Success) { DeleteCriticalSection(&ActiveVirtConsLock); CloseHandle(ConsoleDeviceHandle); } - ConsInitialized = Ret; - return Ret; + ConsInitialized = Success; + return Success; } @@ -443,11 +729,11 @@ Quit: static VOID NTAPI TuiDeinitFrontEnd(IN OUT PFRONTEND This /*, - IN PCONSOLE Console */); + IN PCONSRV_CONSOLE Console */); -NTSTATUS NTAPI +static NTSTATUS NTAPI TuiInitFrontEnd(IN OUT PFRONTEND This, - IN PCONSOLE Console) + IN PCONSRV_CONSOLE Console) { PTUI_CONSOLE_DATA TuiData; HANDLE ThreadHandle; @@ -455,11 +741,8 @@ TuiInitFrontEnd(IN OUT PFRONTEND This, if (This == NULL || Console == NULL) return STATUS_INVALID_PARAMETER; - // if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER) - // return STATUS_INVALID_PARAMETER; - - // /* Initialize the console */ - // Console->TermIFace.Vtbl = &TuiVtbl; + if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER) + return STATUS_INVALID_PARAMETER; TuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(TUI_CONSOLE_DATA)); if (!TuiData) @@ -467,8 +750,9 @@ TuiInitFrontEnd(IN OUT PFRONTEND This, DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n"); return STATUS_UNSUCCESSFUL; } - // Console->TermIFace.Data = (PVOID)TuiData; - TuiData->Console = Console; + // Console->FrontEndIFace.Context = (PVOID)TuiData; + TuiData->Console = Console; + TuiData->ActiveBuffer = Console->ActiveBuffer; TuiData->hWindow = NULL; InitializeCriticalSection(&TuiData->Lock); @@ -515,8 +799,8 @@ TuiInitFrontEnd(IN OUT PFRONTEND This, LeaveCriticalSection(&ActiveVirtConsLock); /* Finally, initialize the frontend structure */ - This->Data = TuiData; - This->OldData = NULL; + This->Context = TuiData; + This->Context2 = NULL; return STATUS_SUCCESS; } @@ -524,8 +808,8 @@ TuiInitFrontEnd(IN OUT PFRONTEND This, static VOID NTAPI TuiDeinitFrontEnd(IN OUT PFRONTEND This) { - // PCONSOLE Console = This->Console; - PTUI_CONSOLE_DATA TuiData = This->Data; // Console->TermIFace.Data; + // PCONSRV_CONSOLE Console = This->Console; + PTUI_CONSOLE_DATA TuiData = This->Context; /* Close the notification window */ DestroyWindow(TuiData->hWindow); @@ -556,8 +840,7 @@ TuiDeinitFrontEnd(IN OUT PFRONTEND This) /* Switch to the next console */ if (NULL != ActiveConsole) ConioDrawConsole(ActiveConsole->Console); - // Console->TermIFace.Data = NULL; - This->Data = NULL; + This->Context = NULL; DeleteCriticalSection(&TuiData->Lock); ConsoleFreeHeap(TuiData); } @@ -566,12 +849,14 @@ static VOID NTAPI TuiDrawRegion(IN OUT PFRONTEND This, SMALL_RECT* Region) { - DWORD BytesReturned; - PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; + PTUI_CONSOLE_DATA TuiData = This->Context; + PCONSOLE_SCREEN_BUFFER Buff = TuiData->Console->ActiveBuffer; PCONSOLE_DRAW ConsoleDraw; + DWORD BytesReturned; UINT ConsoleDrawSize; - if (ActiveConsole->Console != Console || GetType(Buff) != TEXTMODE_BUFFER) return; + if (TuiData != ActiveConsole) return; + if (GetType(Buff) != TEXTMODE_BUFFER) return; ConsoleDrawSize = sizeof(CONSOLE_DRAW) + (ConioRectWidth(Region) * ConioRectHeight(Region)) * 2; @@ -610,20 +895,22 @@ TuiWriteStream(IN OUT PFRONTEND This, PWCHAR Buffer, UINT Length) { - PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; + PTUI_CONSOLE_DATA TuiData = This->Context; + PCONSOLE_SCREEN_BUFFER Buff = TuiData->Console->ActiveBuffer; PCHAR NewBuffer; ULONG NewLength; DWORD BytesWritten; - if (ActiveConsole->Console->ActiveBuffer != Buff) return; + if (TuiData != ActiveConsole) return; + if (GetType(Buff) != TEXTMODE_BUFFER) return; - NewLength = WideCharToMultiByte(Console->OutputCodePage, 0, + NewLength = WideCharToMultiByte(TuiData->Console->OutputCodePage, 0, Buffer, Length, NULL, 0, NULL, NULL); NewBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewLength * sizeof(CHAR)); if (!NewBuffer) return; - WideCharToMultiByte(Console->OutputCodePage, 0, + WideCharToMultiByte(TuiData->Console->OutputCodePage, 0, Buffer, Length, NewBuffer, NewLength, NULL, NULL); @@ -635,16 +922,25 @@ TuiWriteStream(IN OUT PFRONTEND This, RtlFreeHeap(RtlGetProcessHeap(), 0, NewBuffer); } +static VOID NTAPI +TuiRingBell(IN OUT PFRONTEND This) +{ + Beep(800, 200); +} + static BOOL NTAPI TuiSetCursorInfo(IN OUT PFRONTEND This, PCONSOLE_SCREEN_BUFFER Buff) { + PTUI_CONSOLE_DATA TuiData = This->Context; CONSOLE_CURSOR_INFO Info; DWORD BytesReturned; - if (ActiveConsole->Console->ActiveBuffer != Buff) return TRUE; + if (TuiData != ActiveConsole) return TRUE; + if (TuiData->Console->ActiveBuffer != Buff) return TRUE; + if (GetType(Buff) != TEXTMODE_BUFFER) return FALSE; - Info.dwSize = ConioEffectiveCursorSize(Console, 100); + Info.dwSize = ConioEffectiveCursorSize(TuiData->Console, 100); Info.bVisible = Buff->CursorInfo.bVisible; if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO, @@ -663,10 +959,12 @@ TuiSetScreenInfo(IN OUT PFRONTEND This, SHORT OldCursorX, SHORT OldCursorY) { + PTUI_CONSOLE_DATA TuiData = This->Context; CONSOLE_SCREEN_BUFFER_INFO Info; DWORD BytesReturned; - if (ActiveConsole->Console->ActiveBuffer != Buff) return TRUE; + if (TuiData != ActiveConsole) return TRUE; + if (TuiData->Console->ActiveBuffer != Buff) return TRUE; if (GetType(Buff) != TEXTMODE_BUFFER) return FALSE; Info.dwCursorPosition = Buff->CursorPosition; @@ -688,30 +986,91 @@ TuiResizeTerminal(IN OUT PFRONTEND This) { } -static BOOL NTAPI -TuiProcessKeyCallback(IN OUT PFRONTEND This, - MSG* msg, - BYTE KeyStateMenu, - DWORD ShiftState, - UINT VirtualKeyCode, - BOOL Down) +static VOID NTAPI +TuiSetActiveScreenBuffer(IN OUT PFRONTEND This) { - if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) && - VK_TAB == VirtualKeyCode) - { - if (Down) - { - TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1); - } + // PGUI_CONSOLE_DATA GuiData = This->Context; + // PCONSOLE_SCREEN_BUFFER ActiveBuffer; + // HPALETTE hPalette; - return TRUE; - } - else if (VK_MENU == VirtualKeyCode && !Down) - { - return TuiSwapConsole(0); - } + // EnterCriticalSection(&GuiData->Lock); + // GuiData->WindowSizeLock = TRUE; + + // InterlockedExchangePointer(&GuiData->ActiveBuffer, + // ConDrvGetActiveScreenBuffer(GuiData->Console)); - return FALSE; + // GuiData->WindowSizeLock = FALSE; + // LeaveCriticalSection(&GuiData->Lock); + + // ActiveBuffer = GuiData->ActiveBuffer; + + // /* Change the current palette */ + // if (ActiveBuffer->PaletteHandle == NULL) + // { + // hPalette = GuiData->hSysPalette; + // } + // else + // { + // hPalette = ActiveBuffer->PaletteHandle; + // } + + // DPRINT("GuiSetActiveScreenBuffer using palette 0x%p\n", hPalette); + + // /* Set the new palette for the framebuffer */ + // SelectPalette(GuiData->hMemDC, hPalette, FALSE); + + // /* Specify the use of the system palette for the framebuffer */ + // SetSystemPaletteUse(GuiData->hMemDC, ActiveBuffer->PaletteUsage); + + // /* Realize the (logical) palette */ + // RealizePalette(GuiData->hMemDC); + + // GuiResizeTerminal(This); + // // ConioDrawConsole(Console); +} + +static VOID NTAPI +TuiReleaseScreenBuffer(IN OUT PFRONTEND This, + IN PCONSOLE_SCREEN_BUFFER ScreenBuffer) +{ + // PGUI_CONSOLE_DATA GuiData = This->Context; + + // /* + // * If we were notified to release a screen buffer that is not actually + // * ours, then just ignore the notification... + // */ + // if (ScreenBuffer != GuiData->ActiveBuffer) return; + + // /* + // * ... else, we must release our active buffer. Two cases are present: + // * - If ScreenBuffer (== GuiData->ActiveBuffer) IS NOT the console + // * active screen buffer, then we can safely switch to it. + // * - If ScreenBuffer IS the console active screen buffer, we must release + // * it ONLY. + // */ + + // /* Release the old active palette and set the default one */ + // if (GetCurrentObject(GuiData->hMemDC, OBJ_PAL) == ScreenBuffer->PaletteHandle) + // { + // /* Set the new palette */ + // SelectPalette(GuiData->hMemDC, GuiData->hSysPalette, FALSE); + // } + + // /* Set the adequate active screen buffer */ + // if (ScreenBuffer != GuiData->Console->ActiveBuffer) + // { + // GuiSetActiveScreenBuffer(This); + // } + // else + // { + // EnterCriticalSection(&GuiData->Lock); + // GuiData->WindowSizeLock = TRUE; + + // InterlockedExchangePointer(&GuiData->ActiveBuffer, NULL); + + // GuiData->WindowSizeLock = FALSE; + // LeaveCriticalSection(&GuiData->Lock); + // } } static VOID NTAPI @@ -726,15 +1085,22 @@ TuiChangeTitle(IN OUT PFRONTEND This) static BOOL NTAPI TuiChangeIcon(IN OUT PFRONTEND This, - HICON hWindowIcon) + HICON IconHandle) { return TRUE; } +static HDESK NTAPI +TuiGetThreadConsoleDesktop(IN OUT PFRONTEND This) +{ + // PTUI_CONSOLE_DATA TuiData = This->Context; + return NULL; +} + static HWND NTAPI TuiGetConsoleWindowHandle(IN OUT PFRONTEND This) { - PTUI_CONSOLE_DATA TuiData = This->Data; + PTUI_CONSOLE_DATA TuiData = This->Context; return TuiData->hWindow; } @@ -746,6 +1112,13 @@ TuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This, *pSize = PhysicalConsoleSize; } +static BOOL NTAPI +TuiGetSelectionInfo(IN OUT PFRONTEND This, + PCONSOLE_SELECTION_INFO pSelectionInfo) +{ + return TRUE; +} + static BOOL NTAPI TuiSetPalette(IN OUT PFRONTEND This, HPALETTE PaletteHandle, @@ -754,6 +1127,25 @@ TuiSetPalette(IN OUT PFRONTEND This, return TRUE; } +static BOOL NTAPI +TuiSetCodePage(IN OUT PFRONTEND This, + UINT CodePage) +{ + // PTUI_CONSOLE_DATA TuiData = This->Context; + + // TODO: Verify that the console is the visible one. + // Only then can we change the output code page font. + + if (!TuiSetConsoleOutputCP(ConsoleDeviceHandle, CodePage)) + { + DPRINT1("Failed to load the font for codepage %d\n", CodePage); + /* Let's suppose the font is good enough to continue */ + return FALSE; + } + + return TRUE; +} + static ULONG NTAPI TuiGetDisplayMode(IN OUT PFRONTEND This) { @@ -778,15 +1170,15 @@ TuiShowMouseCursor(IN OUT PFRONTEND This, static BOOL NTAPI TuiSetMouseCursor(IN OUT PFRONTEND This, - HCURSOR hCursor) + HCURSOR CursorHandle) { return TRUE; } static HMENU NTAPI TuiMenuControl(IN OUT PFRONTEND This, - UINT cmdIdLow, - UINT cmdIdHigh) + UINT CmdIdLow, + UINT CmdIdHigh) { return NULL; } @@ -804,16 +1196,21 @@ static FRONTEND_VTBL TuiVtbl = TuiDeinitFrontEnd, TuiDrawRegion, TuiWriteStream, + TuiRingBell, TuiSetCursorInfo, TuiSetScreenInfo, TuiResizeTerminal, - TuiProcessKeyCallback, + TuiSetActiveScreenBuffer, + TuiReleaseScreenBuffer, TuiRefreshInternalInfo, TuiChangeTitle, TuiChangeIcon, + TuiGetThreadConsoleDesktop, TuiGetConsoleWindowHandle, TuiGetLargestConsoleWindowSize, + TuiGetSelectionInfo, TuiSetPalette, + TuiSetCodePage, TuiGetDisplayMode, TuiSetDisplayMode, TuiShowMouseCursor, @@ -822,11 +1219,6 @@ static FRONTEND_VTBL TuiVtbl = TuiSetMenuClose, }; -// static BOOL -// DtbgIsDesktopVisible(VOID) -// { - // return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE)); -// } static BOOLEAN IsConsoleMode(VOID) { @@ -835,9 +1227,9 @@ IsConsoleMode(VOID) NTSTATUS NTAPI TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd, - IN OUT PCONSOLE_INFO ConsoleInfo, - IN OUT PVOID ExtraConsoleInfo, - IN ULONG ProcessId) + IN OUT PCONSOLE_STATE_INFO ConsoleInfo, + IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, + IN HANDLE ConsoleLeaderProcessHandle) { if (FrontEnd == NULL || ConsoleInfo == NULL) return STATUS_INVALID_PARAMETER; @@ -849,9 +1241,9 @@ TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd, if (!TuiInit(ConsoleInfo->CodePage)) return STATUS_UNSUCCESSFUL; /* Finally, initialize the frontend structure */ - FrontEnd->Vtbl = &TuiVtbl; - FrontEnd->Data = NULL; - FrontEnd->OldData = NULL; + FrontEnd->Vtbl = &TuiVtbl; + FrontEnd->Context = NULL; + FrontEnd->Context2 = NULL; return STATUS_SUCCESS; } @@ -860,7 +1252,7 @@ NTSTATUS NTAPI TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd) { if (FrontEnd == NULL) return STATUS_INVALID_PARAMETER; - if (FrontEnd->Data) TuiDeinitFrontEnd(FrontEnd); + if (FrontEnd->Context) TuiDeinitFrontEnd(FrontEnd); return STATUS_SUCCESS; }