2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c
5 * PURPOSE: TUI Terminal Front-End - Virtual Consoles...
6 * PROGRAMMERS: David Welch
9 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
12 #ifdef TUITERM_COMPILE
15 #include "include/conio.h"
16 #include "include/console.h"
17 #include "include/settings.h"
19 #include <drivers/blue/ntddblue.h>
25 /* GLOBALS ********************************************************************/
27 /* TUI Console Window Class name */
28 #define TUI_CONSOLE_WINDOW_CLASS L"TuiConsoleWindowClass"
30 typedef struct _TUI_CONSOLE_DATA
32 CRITICAL_SECTION Lock
;
33 LIST_ENTRY Entry
; /* Entry in the list of virtual consoles */
34 // HANDLE hTuiInitEvent;
36 HWND hWindow
; /* Handle to the console's window (used for the window's procedure */
38 PCONSOLE Console
; /* Pointer to the owned console */
39 // TUI_CONSOLE_INFO TuiInfo; /* TUI terminal settings */
40 } TUI_CONSOLE_DATA
, *PTUI_CONSOLE_DATA
;
42 #define GetNextConsole(Console) \
43 CONTAINING_RECORD(Console->Entry.Flink, TUI_CONSOLE_DATA, Entry)
45 #define GetPrevConsole(Console) \
46 CONTAINING_RECORD(Console->Entry.Blink, TUI_CONSOLE_DATA, Entry)
49 /* List of the maintained virtual consoles and its lock */
50 static LIST_ENTRY VirtConsList
;
51 static PTUI_CONSOLE_DATA ActiveConsole
; /* The active console on screen */
52 static CRITICAL_SECTION ActiveVirtConsLock
;
54 static COORD PhysicalConsoleSize
;
55 static HANDLE ConsoleDeviceHandle
;
57 static BOOL ConsInitialized
= FALSE
;
59 /******************************************************************************\
60 |** BlueScreen Driver management **|
62 /* Code taken and adapted from base/system/services/driver.c */
64 ScmLoadDriver(LPCWSTR lpServiceName
)
66 NTSTATUS Status
= STATUS_SUCCESS
;
67 BOOLEAN WasPrivilegeEnabled
= FALSE
;
69 UNICODE_STRING DriverPath
;
71 /* Build the driver path */
72 /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
73 pszDriverPath
= ConsoleAllocHeap(HEAP_ZERO_MEMORY
,
74 (52 + wcslen(lpServiceName
) + 1) * sizeof(WCHAR
));
75 if (pszDriverPath
== NULL
)
76 return ERROR_NOT_ENOUGH_MEMORY
;
79 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
83 RtlInitUnicodeString(&DriverPath
,
86 DPRINT(" Path: %wZ\n", &DriverPath
);
88 /* Acquire driver-loading privilege */
89 Status
= RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
92 &WasPrivilegeEnabled
);
93 if (!NT_SUCCESS(Status
))
95 /* We encountered a failure, exit properly */
96 DPRINT1("CONSRV: Cannot acquire driver-loading privilege, Status = 0x%08lx\n", Status
);
100 Status
= NtLoadDriver(&DriverPath
);
102 /* Release driver-loading privilege */
103 RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
106 &WasPrivilegeEnabled
);
109 ConsoleFreeHeap(pszDriverPath
);
110 return RtlNtStatusToDosError(Status
);
113 #ifdef BLUESCREEN_DRIVER_UNLOADING
115 ScmUnloadDriver(LPCWSTR lpServiceName
)
117 NTSTATUS Status
= STATUS_SUCCESS
;
118 BOOLEAN WasPrivilegeEnabled
= FALSE
;
120 UNICODE_STRING DriverPath
;
122 /* Build the driver path */
123 /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
124 pszDriverPath
= ConsoleAllocHeap(HEAP_ZERO_MEMORY
,
125 (52 + wcslen(lpServiceName
) + 1) * sizeof(WCHAR
));
126 if (pszDriverPath
== NULL
)
127 return ERROR_NOT_ENOUGH_MEMORY
;
129 wcscpy(pszDriverPath
,
130 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
131 wcscat(pszDriverPath
,
134 RtlInitUnicodeString(&DriverPath
,
137 DPRINT(" Path: %wZ\n", &DriverPath
);
139 /* Acquire driver-unloading privilege */
140 Status
= RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
143 &WasPrivilegeEnabled
);
144 if (!NT_SUCCESS(Status
))
146 /* We encountered a failure, exit properly */
147 DPRINT1("CONSRV: Cannot acquire driver-unloading privilege, Status = 0x%08lx\n", Status
);
151 Status
= NtUnloadDriver(&DriverPath
);
153 /* Release driver-unloading privilege */
154 RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
157 &WasPrivilegeEnabled
);
160 ConsoleFreeHeap(pszDriverPath
);
161 return RtlNtStatusToDosError(Status
);
165 \******************************************************************************/
168 TuiSwapConsole(INT Next
)
170 static PTUI_CONSOLE_DATA SwapConsole
= NULL
; /* Console we are thinking about swapping with */
179 * Alt-Tab, swap consoles.
180 * move SwapConsole to next console, and print its title.
182 EnterCriticalSection(&ActiveVirtConsLock
);
183 if (!SwapConsole
) SwapConsole
= ActiveConsole
;
185 SwapConsole
= (0 < Next
? GetNextConsole(SwapConsole
) : GetPrevConsole(SwapConsole
));
186 Title
.MaximumLength
= RtlUnicodeStringToAnsiSize(&SwapConsole
->Console
->Title
);
188 Buffer
= ConsoleAllocHeap(0, sizeof(COORD
) + Title
.MaximumLength
);
189 pos
= (PCOORD
)Buffer
;
190 Title
.Buffer
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(COORD
));
192 RtlUnicodeStringToAnsiString(&Title
, &SwapConsole
->Console
->Title
, FALSE
);
193 pos
->X
= (PhysicalConsoleSize
.X
- Title
.Length
) / 2;
194 pos
->Y
= PhysicalConsoleSize
.Y
/ 2;
195 /* Redraw the console to clear off old title */
196 ConioDrawConsole(ActiveConsole
->Console
);
197 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
,
198 NULL
, 0, Buffer
, sizeof(COORD
) + Title
.Length
,
199 &BytesReturned
, NULL
))
201 DPRINT1( "Error writing to console\n" );
203 ConsoleFreeHeap(Buffer
);
204 LeaveCriticalSection(&ActiveVirtConsLock
);
208 else if (NULL
!= SwapConsole
)
210 EnterCriticalSection(&ActiveVirtConsLock
);
211 if (SwapConsole
!= ActiveConsole
)
213 /* First remove swapconsole from the list */
214 SwapConsole
->Entry
.Blink
->Flink
= SwapConsole
->Entry
.Flink
;
215 SwapConsole
->Entry
.Flink
->Blink
= SwapConsole
->Entry
.Blink
;
216 /* Now insert before activeconsole */
217 SwapConsole
->Entry
.Flink
= &ActiveConsole
->Entry
;
218 SwapConsole
->Entry
.Blink
= ActiveConsole
->Entry
.Blink
;
219 ActiveConsole
->Entry
.Blink
->Flink
= &SwapConsole
->Entry
;
220 ActiveConsole
->Entry
.Blink
= &SwapConsole
->Entry
;
222 ActiveConsole
= SwapConsole
;
224 ConioDrawConsole(ActiveConsole
->Console
);
225 LeaveCriticalSection(&ActiveVirtConsLock
);
235 TuiCopyRect(PCHAR Dest
, PTEXTMODE_SCREEN_BUFFER Buff
, SMALL_RECT
* Region
)
237 UINT SrcDelta
, DestDelta
;
239 PCHAR_INFO Src
, SrcEnd
;
241 Src
= ConioCoordToPointer(Buff
, Region
->Left
, Region
->Top
);
242 SrcDelta
= Buff
->ScreenBufferSize
.X
* sizeof(CHAR_INFO
);
243 SrcEnd
= Buff
->Buffer
+ Buff
->ScreenBufferSize
.Y
* Buff
->ScreenBufferSize
.X
* sizeof(CHAR_INFO
);
244 DestDelta
= ConioRectWidth(Region
) * 2 /* 2 == sizeof(CHAR) + sizeof(BYTE) */;
245 for (i
= Region
->Top
; i
<= Region
->Bottom
; i
++)
247 ConsoleUnicodeCharToAnsiChar(Buff
->Header
.Console
, (PCHAR
)Dest
, &Src
->Char
.UnicodeChar
);
248 *(PBYTE
)(Dest
+ 1) = (BYTE
)Src
->Attributes
;
253 Src
-= Buff
->ScreenBufferSize
.Y
* Buff
->ScreenBufferSize
.X
* sizeof(CHAR_INFO
);
259 static LRESULT CALLBACK
260 TuiConsoleWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
263 PTUI_CONSOLE_DATA TuiData = NULL;
264 PCONSOLE Console = NULL;
266 TuiData = TuiGetGuiData(hWnd);
267 if (TuiData == NULL) return 0;
280 if ((HIWORD(lParam
) & KF_ALTDOWN
) && wParam
== VK_TAB
)
282 // if ((HIWORD(lParam) & (KF_UP | KF_REPEAT)) != KF_REPEAT)
283 TuiSwapConsole(ShiftState
& SHIFT_PRESSED
? -1 : 1);
287 else if (wParam
== VK_MENU
/* && !Down */)
294 if (ConDrvValidateConsoleUnsafe(ActiveConsole
->Console
, CONSOLE_RUNNING
, TRUE
))
298 Message
.message
= msg
;
299 Message
.wParam
= wParam
;
300 Message
.lParam
= lParam
;
302 ConioProcessKey(ActiveConsole
->Console
, &Message
);
303 LeaveCriticalSection(&ActiveConsole
->Console
->Lock
);
310 if (ConDrvValidateConsoleUnsafe(ActiveConsole
->Console
, CONSOLE_RUNNING
, TRUE
))
312 if (LOWORD(wParam
) != WA_INACTIVE
)
315 ConioDrawConsole(ActiveConsole
->Console
);
317 LeaveCriticalSection(&ActiveConsole
->Console
->Lock
);
326 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
330 TuiConsoleThread(PVOID Data
)
332 PTUI_CONSOLE_DATA TuiData
= (PTUI_CONSOLE_DATA
)Data
;
333 PCONSOLE Console
= TuiData
->Console
;
337 NewWindow
= CreateWindowW(TUI_CONSOLE_WINDOW_CLASS
,
338 Console
->Title
.Buffer
,
340 -32000, -32000, 0, 0,
344 if (NULL
== NewWindow
)
346 DPRINT1("CONSRV: Unable to create console window\n");
349 TuiData
->hWindow
= NewWindow
;
351 SetForegroundWindow(TuiData
->hWindow
);
352 NtUserConsoleControl(ConsoleAcquireDisplayOwnership
, NULL
, 0);
354 while (GetMessageW(&msg
, NULL
, 0, 0))
356 TranslateMessage(&msg
);
357 DispatchMessageW(&msg
);
367 CONSOLE_SCREEN_BUFFER_INFO ScrInfo
;
370 ATOM ConsoleClassAtom
;
371 USHORT TextAttribute
= FOREGROUND_BLUE
| FOREGROUND_GREEN
| FOREGROUND_RED
;
373 /* Exit if we were already initialized */
374 if (ConsInitialized
) return TRUE
;
377 * Initialize the TUI front-end:
378 * - load the console driver,
379 * - set default screen attributes,
380 * - grab the console size.
382 ScmLoadDriver(L
"Blue");
384 ConsoleDeviceHandle
= CreateFileW(L
"\\\\.\\BlueScreen",
389 if (INVALID_HANDLE_VALUE
== ConsoleDeviceHandle
)
391 DPRINT1("Failed to open BlueScreen.\n");
395 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_LOADFONT
,
396 &OemCP
, sizeof(OemCP
), NULL
, 0,
397 &BytesReturned
, NULL
))
399 DPRINT1("Failed to load the font for codepage %d\n", OemCP
);
400 /* Let's suppose the font is good enough to continue */
403 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
,
404 &TextAttribute
, sizeof(TextAttribute
), NULL
, 0,
405 &BytesReturned
, NULL
))
407 DPRINT1("Failed to set text attribute\n");
410 ActiveConsole
= NULL
;
411 InitializeListHead(&VirtConsList
);
412 InitializeCriticalSection(&ActiveVirtConsLock
);
414 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
,
415 NULL
, 0, &ScrInfo
, sizeof(ScrInfo
), &BytesReturned
, NULL
))
417 DPRINT1("Failed to get console info\n");
421 PhysicalConsoleSize
= ScrInfo
.dwSize
;
423 /* Register the TUI notification window class */
424 RtlZeroMemory(&wc
, sizeof(WNDCLASSEXW
));
425 wc
.cbSize
= sizeof(WNDCLASSEXW
);
426 wc
.lpszClassName
= TUI_CONSOLE_WINDOW_CLASS
;
427 wc
.lpfnWndProc
= TuiConsoleWndProc
;
429 wc
.hInstance
= ConSrvDllInstance
;
431 ConsoleClassAtom
= RegisterClassExW(&wc
);
432 if (ConsoleClassAtom
== 0)
434 DPRINT1("Failed to register TUI console wndproc\n");
445 DeleteCriticalSection(&ActiveVirtConsLock
);
446 CloseHandle(ConsoleDeviceHandle
);
449 ConsInitialized
= Ret
;
455 /******************************************************************************
456 * TUI Console Driver *
457 ******************************************************************************/
460 TuiDeinitFrontEnd(IN OUT PFRONTEND This
/*,
461 IN PCONSOLE Console */);
464 TuiInitFrontEnd(IN OUT PFRONTEND This
,
467 PTUI_CONSOLE_DATA TuiData
;
470 if (This
== NULL
|| Console
== NULL
)
471 return STATUS_INVALID_PARAMETER
;
473 // if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER)
474 // return STATUS_INVALID_PARAMETER;
476 // /* Initialize the console */
477 // Console->FrontEndIFace.Vtbl = &TuiVtbl;
479 TuiData
= ConsoleAllocHeap(HEAP_ZERO_MEMORY
, sizeof(TUI_CONSOLE_DATA
));
482 DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n");
483 return STATUS_UNSUCCESSFUL
;
485 // Console->FrontEndIFace.Data = (PVOID)TuiData;
486 TuiData
->Console
= Console
;
487 TuiData
->hWindow
= NULL
;
489 InitializeCriticalSection(&TuiData
->Lock
);
492 * HACK: Resize the console since we don't support for now changing
493 * the console size when we display it with the hardware.
495 // Console->ConsoleSize = PhysicalConsoleSize;
496 // ConioResizeBuffer(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), PhysicalConsoleSize);
498 // /* The console cannot be resized anymore */
499 // Console->FixedSize = TRUE; // MUST be placed AFTER the call to ConioResizeBuffer !!
500 // // TermResizeTerminal(Console);
503 * Contrary to what we do in the GUI front-end, here we create
504 * an input thread for each console. It will dispatch all the
505 * input messages to the proper console (on the GUI it is done
506 * via the default GUI dispatch thread).
508 ThreadHandle
= CreateThread(NULL
,
514 if (NULL
== ThreadHandle
)
516 DPRINT1("CONSRV: Unable to create console thread\n");
517 // TuiDeinitFrontEnd(Console);
518 TuiDeinitFrontEnd(This
);
519 return STATUS_UNSUCCESSFUL
;
521 CloseHandle(ThreadHandle
);
524 * Insert the newly created console in the list of virtual consoles
525 * and activate it (give it the focus).
527 EnterCriticalSection(&ActiveVirtConsLock
);
528 InsertTailList(&VirtConsList
, &TuiData
->Entry
);
529 ActiveConsole
= TuiData
;
530 LeaveCriticalSection(&ActiveVirtConsLock
);
532 /* Finally, initialize the frontend structure */
533 This
->Data
= TuiData
;
534 This
->OldData
= NULL
;
536 return STATUS_SUCCESS
;
540 TuiDeinitFrontEnd(IN OUT PFRONTEND This
)
542 // PCONSOLE Console = This->Console;
543 PTUI_CONSOLE_DATA TuiData
= This
->Data
; // Console->FrontEndIFace.Data;
545 /* Close the notification window */
546 DestroyWindow(TuiData
->hWindow
);
549 * Set the active console to the next one
550 * and remove the console from the list.
552 EnterCriticalSection(&ActiveVirtConsLock
);
553 ActiveConsole
= GetNextConsole(TuiData
);
554 RemoveEntryList(&TuiData
->Entry
);
556 // /* Switch to next console */
557 // if (ActiveConsole == TuiData)
558 // if (ActiveConsole->Console == Console)
560 // ActiveConsole = (TuiData->Entry.Flink != TuiData->Entry ? GetNextConsole(TuiData) : NULL);
563 // if (GetNextConsole(TuiData) != TuiData)
565 // TuiData->Entry.Blink->Flink = TuiData->Entry.Flink;
566 // TuiData->Entry.Flink->Blink = TuiData->Entry.Blink;
569 LeaveCriticalSection(&ActiveVirtConsLock
);
571 /* Switch to the next console */
572 if (NULL
!= ActiveConsole
) ConioDrawConsole(ActiveConsole
->Console
);
574 // Console->FrontEndIFace.Data = NULL;
576 DeleteCriticalSection(&TuiData
->Lock
);
577 ConsoleFreeHeap(TuiData
);
581 TuiDrawRegion(IN OUT PFRONTEND This
,
585 PCONSOLE_SCREEN_BUFFER Buff
= Console
->ActiveBuffer
;
586 PCONSOLE_DRAW ConsoleDraw
;
587 UINT ConsoleDrawSize
;
589 if (ActiveConsole
->Console
!= Console
|| GetType(Buff
) != TEXTMODE_BUFFER
) return;
591 ConsoleDrawSize
= sizeof(CONSOLE_DRAW
) +
592 (ConioRectWidth(Region
) * ConioRectHeight(Region
)) * 2;
593 ConsoleDraw
= ConsoleAllocHeap(0, ConsoleDrawSize
);
594 if (NULL
== ConsoleDraw
)
596 DPRINT1("ConsoleAllocHeap failed\n");
599 ConsoleDraw
->X
= Region
->Left
;
600 ConsoleDraw
->Y
= Region
->Top
;
601 ConsoleDraw
->SizeX
= ConioRectWidth(Region
);
602 ConsoleDraw
->SizeY
= ConioRectHeight(Region
);
603 ConsoleDraw
->CursorX
= Buff
->CursorPosition
.X
;
604 ConsoleDraw
->CursorY
= Buff
->CursorPosition
.Y
;
606 TuiCopyRect((PCHAR
)(ConsoleDraw
+ 1), (PTEXTMODE_SCREEN_BUFFER
)Buff
, Region
);
608 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_DRAW
,
609 NULL
, 0, ConsoleDraw
, ConsoleDrawSize
, &BytesReturned
, NULL
))
611 DPRINT1("Failed to draw console\n");
612 ConsoleFreeHeap(ConsoleDraw
);
616 ConsoleFreeHeap(ConsoleDraw
);
620 TuiWriteStream(IN OUT PFRONTEND This
,
628 PCONSOLE_SCREEN_BUFFER Buff
= Console
->ActiveBuffer
;
633 if (ActiveConsole
->Console
->ActiveBuffer
!= Buff
) return;
635 NewLength
= WideCharToMultiByte(Console
->OutputCodePage
, 0,
637 NULL
, 0, NULL
, NULL
);
638 NewBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, NewLength
* sizeof(CHAR
));
639 if (!NewBuffer
) return;
641 WideCharToMultiByte(Console
->OutputCodePage
, 0,
643 NewBuffer
, NewLength
, NULL
, NULL
);
645 if (!WriteFile(ConsoleDeviceHandle
, NewBuffer
, NewLength
* sizeof(CHAR
), &BytesWritten
, NULL
))
647 DPRINT1("Error writing to BlueScreen\n");
650 RtlFreeHeap(RtlGetProcessHeap(), 0, NewBuffer
);
654 TuiSetCursorInfo(IN OUT PFRONTEND This
,
655 PCONSOLE_SCREEN_BUFFER Buff
)
657 CONSOLE_CURSOR_INFO Info
;
660 if (ActiveConsole
->Console
->ActiveBuffer
!= Buff
) return TRUE
;
662 Info
.dwSize
= ConioEffectiveCursorSize(Console
, 100);
663 Info
.bVisible
= Buff
->CursorInfo
.bVisible
;
665 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_SET_CURSOR_INFO
,
666 &Info
, sizeof(Info
), NULL
, 0, &BytesReturned
, NULL
))
668 DPRINT1( "Failed to set cursor info\n" );
676 TuiSetScreenInfo(IN OUT PFRONTEND This
,
677 PCONSOLE_SCREEN_BUFFER Buff
,
681 CONSOLE_SCREEN_BUFFER_INFO Info
;
684 if (ActiveConsole
->Console
->ActiveBuffer
!= Buff
) return TRUE
;
685 if (GetType(Buff
) != TEXTMODE_BUFFER
) return FALSE
;
687 Info
.dwCursorPosition
= Buff
->CursorPosition
;
688 Info
.wAttributes
= ((PTEXTMODE_SCREEN_BUFFER
)Buff
)->ScreenDefaultAttrib
;
690 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
,
691 &Info
, sizeof(CONSOLE_SCREEN_BUFFER_INFO
), NULL
, 0,
692 &BytesReturned
, NULL
))
694 DPRINT1( "Failed to set cursor position\n" );
702 TuiResizeTerminal(IN OUT PFRONTEND This
)
707 TuiRefreshInternalInfo(IN OUT PFRONTEND This
)
712 TuiChangeTitle(IN OUT PFRONTEND This
)
717 TuiChangeIcon(IN OUT PFRONTEND This
,
724 TuiGetConsoleWindowHandle(IN OUT PFRONTEND This
)
726 PTUI_CONSOLE_DATA TuiData
= This
->Data
;
727 return TuiData
->hWindow
;
731 TuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This
,
735 *pSize
= PhysicalConsoleSize
;
739 TuiGetSelectionInfo(IN OUT PFRONTEND This
,
740 PCONSOLE_SELECTION_INFO pSelectionInfo
)
746 TuiSetPalette(IN OUT PFRONTEND This
,
747 HPALETTE PaletteHandle
,
754 TuiGetDisplayMode(IN OUT PFRONTEND This
)
756 return CONSOLE_FULLSCREEN_HARDWARE
; // CONSOLE_FULLSCREEN;
760 TuiSetDisplayMode(IN OUT PFRONTEND This
,
763 // if (NewMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE))
769 TuiShowMouseCursor(IN OUT PFRONTEND This
,
776 TuiSetMouseCursor(IN OUT PFRONTEND This
,
777 HCURSOR CursorHandle
)
783 TuiMenuControl(IN OUT PFRONTEND This
,
791 TuiSetMenuClose(IN OUT PFRONTEND This
,
797 static FRONTEND_VTBL TuiVtbl
=
806 TuiRefreshInternalInfo
,
809 TuiGetConsoleWindowHandle
,
810 TuiGetLargestConsoleWindowSize
,
822 // DtbgIsDesktopVisible(VOID)
824 // return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
829 return (BOOLEAN
)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE
);
833 TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd
,
834 IN OUT PCONSOLE_INFO ConsoleInfo
,
835 IN OUT PVOID ExtraConsoleInfo
,
838 if (FrontEnd
== NULL
|| ConsoleInfo
== NULL
)
839 return STATUS_INVALID_PARAMETER
;
841 /* We must be in console mode already */
842 if (!IsConsoleMode()) return STATUS_UNSUCCESSFUL
;
844 /* Initialize the TUI terminal emulator */
845 if (!TuiInit(ConsoleInfo
->CodePage
)) return STATUS_UNSUCCESSFUL
;
847 /* Finally, initialize the frontend structure */
848 FrontEnd
->Vtbl
= &TuiVtbl
;
849 FrontEnd
->Data
= NULL
;
850 FrontEnd
->OldData
= NULL
;
852 return STATUS_SUCCESS
;
856 TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd
)
858 if (FrontEnd
== NULL
) return STATUS_INVALID_PARAMETER
;
859 if (FrontEnd
->Data
) TuiDeinitFrontEnd(FrontEnd
);
861 return STATUS_SUCCESS
;