2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: 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
16 // #include "include/conio.h"
17 #include "include/console.h"
18 #include "include/settings.h"
21 #include <ndk/iofuncs.h>
22 #include <ndk/setypes.h>
23 #include <drivers/blue/ntddblue.h>
29 /* GLOBALS ********************************************************************/
31 #define ConsoleOutputUnicodeToAnsiChar(Console, dChar, sWChar) \
32 ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
33 WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
35 /* TUI Console Window Class name */
36 #define TUI_CONSOLE_WINDOW_CLASS L"TuiConsoleWindowClass"
38 typedef struct _TUI_CONSOLE_DATA
40 CRITICAL_SECTION Lock
;
41 LIST_ENTRY Entry
; /* Entry in the list of virtual consoles */
42 // HANDLE hTuiInitEvent;
43 // HANDLE hTuiTermEvent;
45 HWND hWindow
; /* Handle to the console's window (used for the window's procedure) */
47 PCONSRV_CONSOLE Console
; /* Pointer to the owned console */
48 PCONSOLE_SCREEN_BUFFER ActiveBuffer
; /* Pointer to the active screen buffer (then maybe the previous Console member is redundant?? Or not...) */
49 // TUI_CONSOLE_INFO TuiInfo; /* TUI terminal settings */
50 } TUI_CONSOLE_DATA
, *PTUI_CONSOLE_DATA
;
52 #define GetNextConsole(Console) \
53 CONTAINING_RECORD(Console->Entry.Flink, TUI_CONSOLE_DATA, Entry)
55 #define GetPrevConsole(Console) \
56 CONTAINING_RECORD(Console->Entry.Blink, TUI_CONSOLE_DATA, Entry)
59 /* List of the maintained virtual consoles and its lock */
60 static LIST_ENTRY VirtConsList
;
61 static PTUI_CONSOLE_DATA ActiveConsole
; /* The active console on screen */
62 static CRITICAL_SECTION ActiveVirtConsLock
;
64 static COORD PhysicalConsoleSize
;
65 static HANDLE ConsoleDeviceHandle
;
67 static BOOL ConsInitialized
= FALSE
;
69 /******************************************************************************\
70 |** BlueScreen Driver management **|
72 /* Code taken and adapted from base/system/services/driver.c */
74 ScmLoadDriver(LPCWSTR lpServiceName
)
76 NTSTATUS Status
= STATUS_SUCCESS
;
77 BOOLEAN WasPrivilegeEnabled
= FALSE
;
79 UNICODE_STRING DriverPath
;
81 /* Build the driver path */
82 /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
83 pszDriverPath
= ConsoleAllocHeap(HEAP_ZERO_MEMORY
,
84 (52 + wcslen(lpServiceName
) + 1) * sizeof(WCHAR
));
85 if (pszDriverPath
== NULL
)
86 return ERROR_NOT_ENOUGH_MEMORY
;
89 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
93 RtlInitUnicodeString(&DriverPath
,
96 DPRINT(" Path: %wZ\n", &DriverPath
);
98 /* Acquire driver-loading privilege */
99 Status
= RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
102 &WasPrivilegeEnabled
);
103 if (!NT_SUCCESS(Status
))
105 /* We encountered a failure, exit properly */
106 DPRINT1("CONSRV: Cannot acquire driver-loading privilege, Status = 0x%08lx\n", Status
);
110 Status
= NtLoadDriver(&DriverPath
);
112 /* Release driver-loading privilege */
113 RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
116 &WasPrivilegeEnabled
);
119 ConsoleFreeHeap(pszDriverPath
);
120 return RtlNtStatusToDosError(Status
);
123 #ifdef BLUESCREEN_DRIVER_UNLOADING
125 ScmUnloadDriver(LPCWSTR lpServiceName
)
127 NTSTATUS Status
= STATUS_SUCCESS
;
128 BOOLEAN WasPrivilegeEnabled
= FALSE
;
130 UNICODE_STRING DriverPath
;
132 /* Build the driver path */
133 /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
134 pszDriverPath
= ConsoleAllocHeap(HEAP_ZERO_MEMORY
,
135 (52 + wcslen(lpServiceName
) + 1) * sizeof(WCHAR
));
136 if (pszDriverPath
== NULL
)
137 return ERROR_NOT_ENOUGH_MEMORY
;
139 wcscpy(pszDriverPath
,
140 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
141 wcscat(pszDriverPath
,
144 RtlInitUnicodeString(&DriverPath
,
147 DPRINT(" Path: %wZ\n", &DriverPath
);
149 /* Acquire driver-unloading privilege */
150 Status
= RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
153 &WasPrivilegeEnabled
);
154 if (!NT_SUCCESS(Status
))
156 /* We encountered a failure, exit properly */
157 DPRINT1("CONSRV: Cannot acquire driver-unloading privilege, Status = 0x%08lx\n", Status
);
161 Status
= NtUnloadDriver(&DriverPath
);
163 /* Release driver-unloading privilege */
164 RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE
,
167 &WasPrivilegeEnabled
);
170 ConsoleFreeHeap(pszDriverPath
);
171 return RtlNtStatusToDosError(Status
);
175 \******************************************************************************/
179 TuiSwapConsole(INT Next
)
181 static PTUI_CONSOLE_DATA SwapConsole
= NULL
; /* Console we are thinking about swapping with */
190 * Alt-Tab, swap consoles.
191 * move SwapConsole to next console, and print its title.
193 EnterCriticalSection(&ActiveVirtConsLock
);
194 if (!SwapConsole
) SwapConsole
= ActiveConsole
;
196 SwapConsole
= (0 < Next
? GetNextConsole(SwapConsole
) : GetPrevConsole(SwapConsole
));
197 Title
.MaximumLength
= RtlUnicodeStringToAnsiSize(&SwapConsole
->Console
->Title
);
199 Buffer
= ConsoleAllocHeap(0, sizeof(COORD
) + Title
.MaximumLength
);
200 pos
= (PCOORD
)Buffer
;
201 Title
.Buffer
= (PVOID
)((ULONG_PTR
)Buffer
+ sizeof(COORD
));
203 RtlUnicodeStringToAnsiString(&Title
, &SwapConsole
->Console
->Title
, FALSE
);
204 pos
->X
= (PhysicalConsoleSize
.X
- Title
.Length
) / 2;
205 pos
->Y
= PhysicalConsoleSize
.Y
/ 2;
206 /* Redraw the console to clear off old title */
207 ConioDrawConsole(ActiveConsole
->Console
);
208 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
,
209 NULL
, 0, Buffer
, sizeof(COORD
) + Title
.Length
,
210 &BytesReturned
, NULL
))
212 DPRINT1( "Error writing to console\n" );
214 ConsoleFreeHeap(Buffer
);
215 LeaveCriticalSection(&ActiveVirtConsLock
);
219 else if (NULL
!= SwapConsole
)
221 EnterCriticalSection(&ActiveVirtConsLock
);
222 if (SwapConsole
!= ActiveConsole
)
224 /* First remove swapconsole from the list */
225 SwapConsole
->Entry
.Blink
->Flink
= SwapConsole
->Entry
.Flink
;
226 SwapConsole
->Entry
.Flink
->Blink
= SwapConsole
->Entry
.Blink
;
227 /* Now insert before activeconsole */
228 SwapConsole
->Entry
.Flink
= &ActiveConsole
->Entry
;
229 SwapConsole
->Entry
.Blink
= ActiveConsole
->Entry
.Blink
;
230 ActiveConsole
->Entry
.Blink
->Flink
= &SwapConsole
->Entry
;
231 ActiveConsole
->Entry
.Blink
= &SwapConsole
->Entry
;
233 ActiveConsole
= SwapConsole
;
235 ConioDrawConsole(ActiveConsole
->Console
);
236 LeaveCriticalSection(&ActiveVirtConsLock
);
247 TuiCopyRect(PCHAR Dest
, PTEXTMODE_SCREEN_BUFFER Buff
, SMALL_RECT
* Region
)
249 UINT SrcDelta
, DestDelta
;
251 PCHAR_INFO Src
, SrcEnd
;
253 Src
= ConioCoordToPointer(Buff
, Region
->Left
, Region
->Top
);
254 SrcDelta
= Buff
->ScreenBufferSize
.X
* sizeof(CHAR_INFO
);
255 SrcEnd
= Buff
->Buffer
+ Buff
->ScreenBufferSize
.Y
* Buff
->ScreenBufferSize
.X
* sizeof(CHAR_INFO
);
256 DestDelta
= ConioRectWidth(Region
) * 2 /* 2 == sizeof(CHAR) + sizeof(BYTE) */;
257 for (i
= Region
->Top
; i
<= Region
->Bottom
; i
++)
259 ConsoleOutputUnicodeToAnsiChar(Buff
->Header
.Console
, (PCHAR
)Dest
, &Src
->Char
.UnicodeChar
);
260 *(PBYTE
)(Dest
+ 1) = (BYTE
)Src
->Attributes
;
265 Src
-= Buff
->ScreenBufferSize
.Y
* Buff
->ScreenBufferSize
.X
* sizeof(CHAR_INFO
);
271 static LRESULT CALLBACK
272 TuiConsoleWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
275 PTUI_CONSOLE_DATA TuiData = NULL;
276 PCONSRV_CONSOLE Console = NULL;
278 TuiData = TuiGetGuiData(hWnd);
279 if (TuiData == NULL) return 0;
292 if ((HIWORD(lParam
) & KF_ALTDOWN
) && wParam
== VK_TAB
)
294 // if ((HIWORD(lParam) & (KF_UP | KF_REPEAT)) != KF_REPEAT)
295 TuiSwapConsole(ShiftState
& SHIFT_PRESSED
? -1 : 1);
299 else if (wParam
== VK_MENU
/* && !Down */)
306 if (ConDrvValidateConsoleUnsafe((PCONSOLE
)ActiveConsole
->Console
, CONSOLE_RUNNING
, TRUE
))
310 Message
.message
= msg
;
311 Message
.wParam
= wParam
;
312 Message
.lParam
= lParam
;
314 ConioProcessKey(ActiveConsole
->Console
, &Message
);
315 LeaveCriticalSection(&ActiveConsole
->Console
->Lock
);
322 if (ConDrvValidateConsoleUnsafe((PCONSOLE
)ActiveConsole
->Console
, CONSOLE_RUNNING
, TRUE
))
324 if (LOWORD(wParam
) != WA_INACTIVE
)
327 ConioDrawConsole(ActiveConsole
->Console
);
329 LeaveCriticalSection(&ActiveConsole
->Console
->Lock
);
338 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
342 TuiConsoleThread(PVOID Param
)
344 PTUI_CONSOLE_DATA TuiData
= (PTUI_CONSOLE_DATA
)Param
;
345 PCONSRV_CONSOLE Console
= TuiData
->Console
;
349 NewWindow
= CreateWindowW(TUI_CONSOLE_WINDOW_CLASS
,
350 Console
->Title
.Buffer
,
352 -32000, -32000, 0, 0,
356 if (NULL
== NewWindow
)
358 DPRINT1("CONSRV: Unable to create console window\n");
361 TuiData
->hWindow
= NewWindow
;
363 SetForegroundWindow(TuiData
->hWindow
);
364 NtUserConsoleControl(ConsoleAcquireDisplayOwnership
, NULL
, 0);
366 while (GetMessageW(&msg
, NULL
, 0, 0))
368 TranslateMessage(&msg
);
369 DispatchMessageW(&msg
);
379 CONSOLE_SCREEN_BUFFER_INFO ScrInfo
;
382 ATOM ConsoleClassAtom
;
383 USHORT TextAttribute
= FOREGROUND_BLUE
| FOREGROUND_GREEN
| FOREGROUND_RED
;
385 /* Exit if we were already initialized */
386 if (ConsInitialized
) return TRUE
;
389 * Initialize the TUI front-end:
390 * - load the console driver,
391 * - set default screen attributes,
392 * - grab the console size.
394 ScmLoadDriver(L
"Blue");
396 ConsoleDeviceHandle
= CreateFileW(L
"\\\\.\\BlueScreen",
401 if (ConsoleDeviceHandle
== INVALID_HANDLE_VALUE
)
403 DPRINT1("Failed to open BlueScreen.\n");
407 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_LOADFONT
,
408 &OemCP
, sizeof(OemCP
), NULL
, 0,
409 &BytesReturned
, NULL
))
411 DPRINT1("Failed to load the font for codepage %d\n", OemCP
);
412 /* Let's suppose the font is good enough to continue */
415 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
,
416 &TextAttribute
, sizeof(TextAttribute
), NULL
, 0,
417 &BytesReturned
, NULL
))
419 DPRINT1("Failed to set text attribute\n");
422 ActiveConsole
= NULL
;
423 InitializeListHead(&VirtConsList
);
424 InitializeCriticalSection(&ActiveVirtConsLock
);
426 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
,
427 NULL
, 0, &ScrInfo
, sizeof(ScrInfo
), &BytesReturned
, NULL
))
429 DPRINT1("Failed to get console info\n");
433 PhysicalConsoleSize
= ScrInfo
.dwSize
;
435 /* Register the TUI notification window class */
436 RtlZeroMemory(&wc
, sizeof(WNDCLASSEXW
));
437 wc
.cbSize
= sizeof(WNDCLASSEXW
);
438 wc
.lpszClassName
= TUI_CONSOLE_WINDOW_CLASS
;
439 wc
.lpfnWndProc
= TuiConsoleWndProc
;
441 wc
.hInstance
= ConSrvDllInstance
;
443 ConsoleClassAtom
= RegisterClassExW(&wc
);
444 if (ConsoleClassAtom
== 0)
446 DPRINT1("Failed to register TUI console wndproc\n");
457 DeleteCriticalSection(&ActiveVirtConsLock
);
458 CloseHandle(ConsoleDeviceHandle
);
461 ConsInitialized
= Ret
;
467 /******************************************************************************
468 * TUI Console Driver *
469 ******************************************************************************/
472 TuiDeinitFrontEnd(IN OUT PFRONTEND This
/*,
473 IN PCONSRV_CONSOLE Console */);
475 static NTSTATUS NTAPI
476 TuiInitFrontEnd(IN OUT PFRONTEND This
,
477 IN PCONSRV_CONSOLE Console
)
479 PTUI_CONSOLE_DATA TuiData
;
482 if (This
== NULL
|| Console
== NULL
)
483 return STATUS_INVALID_PARAMETER
;
485 if (GetType(Console
->ActiveBuffer
) != TEXTMODE_BUFFER
)
486 return STATUS_INVALID_PARAMETER
;
488 TuiData
= ConsoleAllocHeap(HEAP_ZERO_MEMORY
, sizeof(TUI_CONSOLE_DATA
));
491 DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n");
492 return STATUS_UNSUCCESSFUL
;
494 // Console->FrontEndIFace.Context = (PVOID)TuiData;
495 TuiData
->Console
= Console
;
496 TuiData
->ActiveBuffer
= Console
->ActiveBuffer
;
497 TuiData
->hWindow
= NULL
;
499 InitializeCriticalSection(&TuiData
->Lock
);
502 * HACK: Resize the console since we don't support for now changing
503 * the console size when we display it with the hardware.
505 // Console->ConsoleSize = PhysicalConsoleSize;
506 // ConioResizeBuffer(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), PhysicalConsoleSize);
508 // /* The console cannot be resized anymore */
509 // Console->FixedSize = TRUE; // MUST be placed AFTER the call to ConioResizeBuffer !!
510 // // TermResizeTerminal(Console);
513 * Contrary to what we do in the GUI front-end, here we create
514 * an input thread for each console. It will dispatch all the
515 * input messages to the proper console (on the GUI it is done
516 * via the default GUI dispatch thread).
518 ThreadHandle
= CreateThread(NULL
,
524 if (NULL
== ThreadHandle
)
526 DPRINT1("CONSRV: Unable to create console thread\n");
527 // TuiDeinitFrontEnd(Console);
528 TuiDeinitFrontEnd(This
);
529 return STATUS_UNSUCCESSFUL
;
531 CloseHandle(ThreadHandle
);
534 * Insert the newly created console in the list of virtual consoles
535 * and activate it (give it the focus).
537 EnterCriticalSection(&ActiveVirtConsLock
);
538 InsertTailList(&VirtConsList
, &TuiData
->Entry
);
539 ActiveConsole
= TuiData
;
540 LeaveCriticalSection(&ActiveVirtConsLock
);
542 /* Finally, initialize the frontend structure */
543 This
->Context
= TuiData
;
544 This
->Context2
= NULL
;
546 return STATUS_SUCCESS
;
550 TuiDeinitFrontEnd(IN OUT PFRONTEND This
)
552 // PCONSRV_CONSOLE Console = This->Console;
553 PTUI_CONSOLE_DATA TuiData
= This
->Context
;
555 /* Close the notification window */
556 DestroyWindow(TuiData
->hWindow
);
559 * Set the active console to the next one
560 * and remove the console from the list.
562 EnterCriticalSection(&ActiveVirtConsLock
);
563 ActiveConsole
= GetNextConsole(TuiData
);
564 RemoveEntryList(&TuiData
->Entry
);
566 // /* Switch to next console */
567 // if (ActiveConsole == TuiData)
568 // if (ActiveConsole->Console == Console)
570 // ActiveConsole = (TuiData->Entry.Flink != TuiData->Entry ? GetNextConsole(TuiData) : NULL);
573 // if (GetNextConsole(TuiData) != TuiData)
575 // TuiData->Entry.Blink->Flink = TuiData->Entry.Flink;
576 // TuiData->Entry.Flink->Blink = TuiData->Entry.Blink;
579 LeaveCriticalSection(&ActiveVirtConsLock
);
581 /* Switch to the next console */
582 if (NULL
!= ActiveConsole
) ConioDrawConsole(ActiveConsole
->Console
);
584 This
->Context
= NULL
;
585 DeleteCriticalSection(&TuiData
->Lock
);
586 ConsoleFreeHeap(TuiData
);
590 TuiDrawRegion(IN OUT PFRONTEND This
,
593 PTUI_CONSOLE_DATA TuiData
= This
->Context
;
594 PCONSOLE_SCREEN_BUFFER Buff
= TuiData
->Console
->ActiveBuffer
;
595 PCONSOLE_DRAW ConsoleDraw
;
597 UINT ConsoleDrawSize
;
599 if (TuiData
!= ActiveConsole
) return;
600 if (GetType(Buff
) != TEXTMODE_BUFFER
) return;
602 ConsoleDrawSize
= sizeof(CONSOLE_DRAW
) +
603 (ConioRectWidth(Region
) * ConioRectHeight(Region
)) * 2;
604 ConsoleDraw
= ConsoleAllocHeap(0, ConsoleDrawSize
);
605 if (NULL
== ConsoleDraw
)
607 DPRINT1("ConsoleAllocHeap failed\n");
610 ConsoleDraw
->X
= Region
->Left
;
611 ConsoleDraw
->Y
= Region
->Top
;
612 ConsoleDraw
->SizeX
= ConioRectWidth(Region
);
613 ConsoleDraw
->SizeY
= ConioRectHeight(Region
);
614 ConsoleDraw
->CursorX
= Buff
->CursorPosition
.X
;
615 ConsoleDraw
->CursorY
= Buff
->CursorPosition
.Y
;
617 TuiCopyRect((PCHAR
)(ConsoleDraw
+ 1), (PTEXTMODE_SCREEN_BUFFER
)Buff
, Region
);
619 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_DRAW
,
620 NULL
, 0, ConsoleDraw
, ConsoleDrawSize
, &BytesReturned
, NULL
))
622 DPRINT1("Failed to draw console\n");
623 ConsoleFreeHeap(ConsoleDraw
);
627 ConsoleFreeHeap(ConsoleDraw
);
631 TuiWriteStream(IN OUT PFRONTEND This
,
639 PTUI_CONSOLE_DATA TuiData
= This
->Context
;
640 PCONSOLE_SCREEN_BUFFER Buff
= TuiData
->Console
->ActiveBuffer
;
645 if (TuiData
!= ActiveConsole
) return;
646 if (GetType(Buff
) != TEXTMODE_BUFFER
) return;
648 NewLength
= WideCharToMultiByte(TuiData
->Console
->OutputCodePage
, 0,
650 NULL
, 0, NULL
, NULL
);
651 NewBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, NewLength
* sizeof(CHAR
));
652 if (!NewBuffer
) return;
654 WideCharToMultiByte(TuiData
->Console
->OutputCodePage
, 0,
656 NewBuffer
, NewLength
, NULL
, NULL
);
658 if (!WriteFile(ConsoleDeviceHandle
, NewBuffer
, NewLength
* sizeof(CHAR
), &BytesWritten
, NULL
))
660 DPRINT1("Error writing to BlueScreen\n");
663 RtlFreeHeap(RtlGetProcessHeap(), 0, NewBuffer
);
667 TuiRingBell(IN OUT PFRONTEND This
)
673 TuiSetCursorInfo(IN OUT PFRONTEND This
,
674 PCONSOLE_SCREEN_BUFFER Buff
)
676 PTUI_CONSOLE_DATA TuiData
= This
->Context
;
677 CONSOLE_CURSOR_INFO Info
;
680 if (TuiData
!= ActiveConsole
) return TRUE
;
681 if (TuiData
->Console
->ActiveBuffer
!= Buff
) return TRUE
;
682 if (GetType(Buff
) != TEXTMODE_BUFFER
) return FALSE
;
684 Info
.dwSize
= ConioEffectiveCursorSize(TuiData
->Console
, 100);
685 Info
.bVisible
= Buff
->CursorInfo
.bVisible
;
687 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_SET_CURSOR_INFO
,
688 &Info
, sizeof(Info
), NULL
, 0, &BytesReturned
, NULL
))
690 DPRINT1( "Failed to set cursor info\n" );
698 TuiSetScreenInfo(IN OUT PFRONTEND This
,
699 PCONSOLE_SCREEN_BUFFER Buff
,
703 PTUI_CONSOLE_DATA TuiData
= This
->Context
;
704 CONSOLE_SCREEN_BUFFER_INFO Info
;
707 if (TuiData
!= ActiveConsole
) return TRUE
;
708 if (TuiData
->Console
->ActiveBuffer
!= Buff
) return TRUE
;
709 if (GetType(Buff
) != TEXTMODE_BUFFER
) return FALSE
;
711 Info
.dwCursorPosition
= Buff
->CursorPosition
;
712 Info
.wAttributes
= ((PTEXTMODE_SCREEN_BUFFER
)Buff
)->ScreenDefaultAttrib
;
714 if (!DeviceIoControl(ConsoleDeviceHandle
, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
,
715 &Info
, sizeof(CONSOLE_SCREEN_BUFFER_INFO
), NULL
, 0,
716 &BytesReturned
, NULL
))
718 DPRINT1( "Failed to set cursor position\n" );
726 TuiResizeTerminal(IN OUT PFRONTEND This
)
731 TuiSetActiveScreenBuffer(IN OUT PFRONTEND This
)
733 // PGUI_CONSOLE_DATA GuiData = This->Context;
734 // PCONSOLE_SCREEN_BUFFER ActiveBuffer;
735 // HPALETTE hPalette;
737 // EnterCriticalSection(&GuiData->Lock);
738 // GuiData->WindowSizeLock = TRUE;
740 // InterlockedExchangePointer(&GuiData->ActiveBuffer,
741 // ConDrvGetActiveScreenBuffer(GuiData->Console));
743 // GuiData->WindowSizeLock = FALSE;
744 // LeaveCriticalSection(&GuiData->Lock);
746 // ActiveBuffer = GuiData->ActiveBuffer;
748 // /* Change the current palette */
749 // if (ActiveBuffer->PaletteHandle == NULL)
751 // hPalette = GuiData->hSysPalette;
755 // hPalette = ActiveBuffer->PaletteHandle;
758 // DPRINT("GuiSetActiveScreenBuffer using palette 0x%p\n", hPalette);
760 // /* Set the new palette for the framebuffer */
761 // SelectPalette(GuiData->hMemDC, hPalette, FALSE);
763 // /* Specify the use of the system palette for the framebuffer */
764 // SetSystemPaletteUse(GuiData->hMemDC, ActiveBuffer->PaletteUsage);
766 // /* Realize the (logical) palette */
767 // RealizePalette(GuiData->hMemDC);
769 // GuiResizeTerminal(This);
770 // // ConioDrawConsole(Console);
774 TuiReleaseScreenBuffer(IN OUT PFRONTEND This
,
775 IN PCONSOLE_SCREEN_BUFFER ScreenBuffer
)
777 // PGUI_CONSOLE_DATA GuiData = This->Context;
780 // * If we were notified to release a screen buffer that is not actually
781 // * ours, then just ignore the notification...
783 // if (ScreenBuffer != GuiData->ActiveBuffer) return;
786 // * ... else, we must release our active buffer. Two cases are present:
787 // * - If ScreenBuffer (== GuiData->ActiveBuffer) IS NOT the console
788 // * active screen buffer, then we can safely switch to it.
789 // * - If ScreenBuffer IS the console active screen buffer, we must release
793 // /* Release the old active palette and set the default one */
794 // if (GetCurrentObject(GuiData->hMemDC, OBJ_PAL) == ScreenBuffer->PaletteHandle)
796 // /* Set the new palette */
797 // SelectPalette(GuiData->hMemDC, GuiData->hSysPalette, FALSE);
800 // /* Set the adequate active screen buffer */
801 // if (ScreenBuffer != GuiData->Console->ActiveBuffer)
803 // GuiSetActiveScreenBuffer(This);
807 // EnterCriticalSection(&GuiData->Lock);
808 // GuiData->WindowSizeLock = TRUE;
810 // InterlockedExchangePointer(&GuiData->ActiveBuffer, NULL);
812 // GuiData->WindowSizeLock = FALSE;
813 // LeaveCriticalSection(&GuiData->Lock);
818 TuiRefreshInternalInfo(IN OUT PFRONTEND This
)
823 TuiChangeTitle(IN OUT PFRONTEND This
)
828 TuiChangeIcon(IN OUT PFRONTEND This
,
835 TuiGetConsoleWindowHandle(IN OUT PFRONTEND This
)
837 PTUI_CONSOLE_DATA TuiData
= This
->Context
;
838 return TuiData
->hWindow
;
842 TuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This
,
846 *pSize
= PhysicalConsoleSize
;
850 TuiGetSelectionInfo(IN OUT PFRONTEND This
,
851 PCONSOLE_SELECTION_INFO pSelectionInfo
)
857 TuiSetPalette(IN OUT PFRONTEND This
,
858 HPALETTE PaletteHandle
,
865 TuiGetDisplayMode(IN OUT PFRONTEND This
)
867 return CONSOLE_FULLSCREEN_HARDWARE
; // CONSOLE_FULLSCREEN;
871 TuiSetDisplayMode(IN OUT PFRONTEND This
,
874 // if (NewMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE))
880 TuiShowMouseCursor(IN OUT PFRONTEND This
,
887 TuiSetMouseCursor(IN OUT PFRONTEND This
,
888 HCURSOR CursorHandle
)
894 TuiMenuControl(IN OUT PFRONTEND This
,
902 TuiSetMenuClose(IN OUT PFRONTEND This
,
908 static FRONTEND_VTBL TuiVtbl
=
918 TuiSetActiveScreenBuffer
,
919 TuiReleaseScreenBuffer
,
920 TuiRefreshInternalInfo
,
923 TuiGetConsoleWindowHandle
,
924 TuiGetLargestConsoleWindowSize
,
938 return (BOOLEAN
)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE
);
942 TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd
,
943 IN OUT PCONSOLE_INFO ConsoleInfo
,
944 IN OUT PVOID ExtraConsoleInfo
,
947 if (FrontEnd
== NULL
|| ConsoleInfo
== NULL
)
948 return STATUS_INVALID_PARAMETER
;
950 /* We must be in console mode already */
951 if (!IsConsoleMode()) return STATUS_UNSUCCESSFUL
;
953 /* Initialize the TUI terminal emulator */
954 if (!TuiInit(ConsoleInfo
->CodePage
)) return STATUS_UNSUCCESSFUL
;
956 /* Finally, initialize the frontend structure */
957 FrontEnd
->Vtbl
= &TuiVtbl
;
958 FrontEnd
->Context
= NULL
;
959 FrontEnd
->Context2
= NULL
;
961 return STATUS_SUCCESS
;
965 TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd
)
967 if (FrontEnd
== NULL
) return STATUS_INVALID_PARAMETER
;
968 if (FrontEnd
->Context
) TuiDeinitFrontEnd(FrontEnd
);
970 return STATUS_SUCCESS
;