Restore the correct screen buffer when reattaching the video to the console. WIP

svn path=/trunk/; revision=68720
This commit is contained in:
Hermès Bélusca-Maïto 2015-08-16 19:00:21 +00:00
parent ebf3ac834c
commit 87f23ca930
3 changed files with 95 additions and 73 deletions

View file

@ -3863,17 +3863,20 @@ VOID VidBiosAttachToConsole(VOID)
Attached = TRUE;
}
/* Refresh display */
VgaRefreshDisplay();
VidBiosSyncCursorPosition();
}
VOID VidBiosDetachFromConsole(VOID)
{
/* Perform another screen refresh */
if (!Attached) return;
/* Refresh display */
VgaRefreshDisplay();
/* Detach from the console */
VgaDetachFromConsole(FALSE);
VgaDetachFromConsole();
Attached = FALSE;
}

View file

@ -209,6 +209,7 @@ static const COLORREF ConsoleColors[16] =
/*
* Console interface -- VGA-mode-agnostic
*/
// WARNING! This structure *MUST BE* in sync with the one in consrv/include/conio_winsrv.h
typedef struct _CHAR_CELL
{
CHAR Char;
@ -230,6 +231,9 @@ static CONSOLE_CURSOR_INFO OrgConsoleCursorInfo;
static CONSOLE_SCREEN_BUFFER_INFO OrgConsoleBufferInfo;
static HANDLE ScreenBufferHandle = NULL;
/*
* Text mode -- we always keep a valid text mode framebuffer
* even if we are in graphics mode. This is needed in order
@ -473,7 +477,7 @@ static BOOL VgaAttachToConsoleInternal(PCOORD Resolution)
* Windows 2k3 winsrv.dll calls NtVdmControl(VdmQueryVdmProcess == 14, &ConsoleHandle);
* in the two following APIs:
* SrvRegisterConsoleVDM (corresponding Win32 API: RegisterConsoleVDM)
* SrvVDMConsoleOperation (corresponding Win32 API: )
* SrvVDMConsoleOperation (corresponding Win32 API: ??)
* to check whether the current process is a VDM process, and fails otherwise
* with the error 0xC0000022 (STATUS_ACCESS_DENIED).
*
@ -481,6 +485,7 @@ static BOOL VgaAttachToConsoleInternal(PCOORD Resolution)
* BaseSrvIsFirstVDM API...
*/
/* Register with the console server */
Success =
__RegisterConsoleVDM(1,
StartEvent,
@ -577,6 +582,28 @@ static BOOL VgaAttachToConsoleInternal(PCOORD Resolution)
return TRUE;
}
static VOID VgaDetachFromConsoleInternal(VOID)
{
ULONG dummyLength;
PVOID dummyPtr;
COORD dummySize = {0};
/* Deregister with the console server */
__RegisterConsoleVDM(0,
NULL,
NULL,
NULL,
0,
&dummyLength,
&dummyPtr,
NULL,
0,
dummySize,
&dummyPtr);
TextFramebuffer = NULL;
}
static BOOL IsConsoleHandle(HANDLE hHandle)
{
DWORD dwMode;
@ -1023,7 +1050,7 @@ static BOOL VgaEnterTextMode(PCOORD Resolution)
if (TextResolution.X != Resolution->X ||
TextResolution.Y != Resolution->Y)
{
VgaDetachFromConsole(TRUE);
VgaDetachFromConsoleInternal();
/*
* VgaAttachToConsoleInternal sets TextResolution to the
@ -1047,7 +1074,7 @@ static BOOL VgaEnterTextMode(PCOORD Resolution)
/*
* Set the text mode palette.
*
* WARNING: This call should fail on Windows (and therefore
* INFORMATION: This call should fail on Windows (and therefore
* we get the default palette and our external behaviour is
* just like Windows' one), but it should success on ReactOS
* (so that we get console palette changes even for text-mode
@ -1077,25 +1104,20 @@ static VOID VgaChangeMode(VOID)
: GRAPHICS_MODE;
/*
* No need to switch to a different screen mode + resolution
* if the new ones are the same as the old ones.
* Do not switch to a different screen mode + resolution if the new settings
* are the same as the old ones. Just repaint the full screen.
*/
if ((ScreenMode == NewScreenMode) &&
if ((ScreenMode == NewScreenMode) && // CurrResolution == NewResolution
(CurrResolution.X == NewResolution.X && CurrResolution.Y == NewResolution.Y))
{
goto Quit;
}
/* Leave the current video mode */
if (ScreenMode == GRAPHICS_MODE)
{
/* Leave the current graphics mode */
VgaLeaveGraphicsMode();
}
else
{
/* Leave the current text mode */
VgaLeaveTextMode();
}
/* Update the current resolution */
CurrResolution = NewResolution;
@ -2270,47 +2292,47 @@ VOID ScreenEventHandler(PWINDOW_BUFFER_SIZE_RECORD ScreenEvent)
BOOL VgaAttachToConsole(VOID)
{
//
// FIXME: We should go back to the saved screen state
//
if (TextResolution.X == 0 || TextResolution.Y == 0)
DPRINT1("VgaAttachToConsole -- TextResolution uninitialized\n");
if (TextResolution.X == 0) TextResolution.X = 80;
if (TextResolution.Y == 0) TextResolution.Y = 25;
return VgaAttachToConsoleInternal(&TextResolution);
// VgaDetachFromConsoleInternal();
/*
* VgaAttachToConsoleInternal sets TextResolution to the
* new resolution and updates ConsoleInfo.
*/
if (!VgaAttachToConsoleInternal(&TextResolution))
{
DisplayMessage(L"An unexpected error occurred!\n");
EmulatorTerminate();
return FALSE;
}
VOID VgaDetachFromConsole(BOOL ChangingMode)
{
ULONG dummyLength;
PVOID dummyPtr;
COORD dummySize = {0};
/* Restore the screen state */
/* Restore the original screen buffer */
ASSERT(ScreenBufferHandle);
VgaSetActiveScreenBuffer(ScreenBufferHandle);
ScreenBufferHandle = NULL;
//
// FIXME: We should save the screen state
//
return TRUE;
}
__RegisterConsoleVDM(0,
NULL,
NULL,
NULL,
0,
&dummyLength,
&dummyPtr,
NULL,
0,
dummySize,
&dummyPtr);
TextFramebuffer = NULL;
if (!ChangingMode)
VOID VgaDetachFromConsole(VOID)
{
SMALL_RECT ConRect;
/* Restore the old screen buffer */
VgaDetachFromConsoleInternal();
/* Save the screen state */
if (ScreenMode == TEXT_MODE)
ScreenBufferHandle = TextConsoleBuffer;
else
ScreenBufferHandle = GraphicsConsoleBuffer;
/* Restore the old text-mode screen buffer */
VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Restore the original console size */
@ -2328,16 +2350,9 @@ VOID VgaDetachFromConsole(BOOL ChangingMode)
/* Restore the original cursor shape */
SetConsoleCursorInfo(TextConsoleBuffer, &OrgConsoleCursorInfo);
}
}
BOOLEAN VgaInitialize(HANDLE TextHandle)
{
/* Clear the SEQ, GC, CRTC and AC registers */
RtlZeroMemory(VgaSeqRegisters, sizeof(VgaSeqRegisters));
RtlZeroMemory(VgaGcRegisters, sizeof(VgaGcRegisters));
RtlZeroMemory(VgaCrtcRegisters, sizeof(VgaCrtcRegisters));
RtlZeroMemory(VgaAcRegisters, sizeof(VgaAcRegisters));
/* Save the default text-mode console output handle */
if (!IsConsoleHandle(TextHandle)) return FALSE;
TextConsoleBuffer = TextHandle;
@ -2350,11 +2365,17 @@ BOOLEAN VgaInitialize(HANDLE TextHandle)
}
ConsoleInfo = OrgConsoleBufferInfo;
/* Clear the SEQ, GC, CRTC and AC registers */
RtlZeroMemory(VgaSeqRegisters, sizeof(VgaSeqRegisters));
RtlZeroMemory(VgaGcRegisters, sizeof(VgaGcRegisters));
RtlZeroMemory(VgaCrtcRegisters, sizeof(VgaCrtcRegisters));
RtlZeroMemory(VgaAcRegisters, sizeof(VgaAcRegisters));
/* Initialize the VGA palette and fail if it isn't successfully created */
if (!VgaInitializePalette()) return FALSE;
/***/ VgaResetPalette(); /***/
/* Switch to the text buffer */
/* Switch to the text buffer, but do not enter into a text mode */
VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Reset the sequencer */
@ -2391,21 +2412,19 @@ BOOLEAN VgaInitialize(HANDLE TextHandle)
VOID VgaCleanup(VOID)
{
/* Do a final display refresh */
VgaRefreshDisplay();
DestroyHardwareTimer(VSyncTimer);
DestroyHardwareTimer(HSyncTimer);
/* Leave the current video mode */
if (ScreenMode == GRAPHICS_MODE)
{
/* Leave the current graphics mode */
VgaLeaveGraphicsMode();
}
else
{
/* Leave the current text mode */
VgaLeaveTextMode();
}
VgaDetachFromConsole(FALSE);
VgaDetachFromConsole();
MemRemoveFastMemoryHook((PVOID)0xA0000, 0x20000);
CloseHandle(AnotherEvent);

View file

@ -372,7 +372,7 @@ typedef struct _SVGA_REGISTERS
VOID ScreenEventHandler(PWINDOW_BUFFER_SIZE_RECORD ScreenEvent);
BOOL VgaAttachToConsole(VOID);
VOID VgaDetachFromConsole(BOOL ChangeMode);
VOID VgaDetachFromConsole(VOID);
COORD VgaGetDisplayResolution(VOID);
VOID VgaRefreshDisplay(VOID);