static CONST DWORD MemoryBase[] = { 0xA0000, 0xA0000, 0xB0000, 0xB8000 };
static CONST DWORD MemoryLimit[] = { 0xAFFFF, 0xAFFFF, 0xB7FFF, 0xBFFFF };
+/*
+ * Activate this line if you want to use the real
+ * RegisterConsoleVDM API of ReactOS/Windows.
+ */
+// #define USE_REAL_REGISTERCONSOLEVDM
+
#define USE_REACTOS_COLORS
// #define USE_DOSBOX_COLORS
#endif
+/*
+ * Default 16-color palette for foreground and background
+ * (corresponding flags in comments).
+ * Taken from subsystems/win32/winsrv/consrv/frontends/gui/conwnd.c
+ */
+static const COLORREF ConsoleColors[16] =
+{
+ RGB(0, 0, 0), // (Black)
+ RGB(0, 0, 128), // BLUE
+ RGB(0, 128, 0), // GREEN
+ RGB(0, 128, 128), // BLUE | GREEN
+ RGB(128, 0, 0), // RED
+ RGB(128, 0, 128), // BLUE | RED
+ RGB(128, 128, 0), // GREEN | RED
+ RGB(192, 192, 192), // BLUE | GREEN | RED
+
+ RGB(128, 128, 128), // (Grey) INTENSITY
+ RGB(0, 0, 255), // BLUE | INTENSITY
+ RGB(0, 255, 0), // GREEN | INTENSITY
+ RGB(0, 255, 255), // BLUE | GREEN | INTENSITY
+ RGB(255, 0, 0), // RED | INTENSITY
+ RGB(255, 0, 255), // BLUE | RED | INTENSITY
+ RGB(255, 255, 0), // GREEN | RED | INTENSITY
+ RGB(255, 255, 255) // BLUE | GREEN | RED | INTENSITY
+};
+
/*
* Console interface -- VGA-mode-agnostic
*/
static LPVOID ConsoleFramebuffer = NULL; // Active framebuffer, points to
// either TextFramebuffer or a valid
// graphics framebuffer.
+static HPALETTE TextPaletteHandle = NULL;
static HPALETTE PaletteHandle = NULL;
static HANDLE StartEvent = NULL;
#include <ntddvdeo.h>
-typedef
-BOOL
-(WINAPI *pRegisterConsoleVDM)
-(
- BOOL IsDosVDM_flag,
- HANDLE EventHandle_1,
- HANDLE EventHandle_2,
- HANDLE EventHandle_3,
- int Unused1,
- PVOID returned_val_1,
- PVOID *returned_val_2,
- PVOID lpUnknownBuffer,
- DWORD theUnknownBufferLength,
- COORD theVDMBufferSize,
- PCHAR *lpVDMBuffer
-);
-
-#if 0
-BOOL
-WINAPI
-RegisterConsoleVDM
-(
- BOOL IsDosVDM_flag,
- HANDLE EventHandle_1,
- HANDLE EventHandle_2,
- HANDLE EventHandle_3,
- int Unused1,
- PVOID returned_val_1,
- PVOID *returned_val_2,
- PVOID lpUnknownBuffer,
- DWORD theUnknownBufferLength,
- COORD theVDMBufferSize,
- PVOID *lpVDMBuffer
-);
-
-HMODULE hKernel32 = NULL;
-pRegisterConsoleVDM RegisterConsoleVDM = NULL;
-#endif
+#ifdef USE_REAL_REGISTERCONSOLEVDM
+
+#define __RegisterConsoleVDM RegisterConsoleVDM
+#define __InvalidateConsoleDIBits InvalidateConsoleDIBits
+
+#else
/*
* This private buffer, per-console, is used by
BOOL
WINAPI
-__RegisterConsoleVDM(BOOL IsDosVDM_flag,
- HANDLE EventHandle_1,
- HANDLE EventHandle_2,
- HANDLE EventHandle_3,
- int Unused1,
- PVOID returned_val_1,
- PVOID *returned_val_2,
- PVOID lpUnknownBuffer,
- DWORD theUnknownBufferLength,
- COORD theVDMBufferSize,
- PCHAR *lpVDMBuffer)
+__RegisterConsoleVDM(IN DWORD dwRegisterFlags,
+ IN HANDLE hStartHardwareEvent,
+ IN HANDLE hEndHardwareEvent,
+ IN HANDLE hErrorHardwareEvent,
+ IN DWORD dwUnusedVar,
+ OUT LPDWORD lpVideoStateLength,
+ OUT PVOID* lpVideoState, // PVIDEO_HARDWARE_STATE_HEADER*
+ IN PVOID lpUnusedBuffer,
+ IN DWORD dwUnusedBufferLength,
+ IN COORD dwVDMBufferSize,
+ OUT PVOID* lpVDMBuffer)
{
- UNREFERENCED_PARAMETER(EventHandle_3);
- UNREFERENCED_PARAMETER(Unused1);
- UNREFERENCED_PARAMETER(returned_val_1);
- UNREFERENCED_PARAMETER(returned_val_2);
- UNREFERENCED_PARAMETER(lpUnknownBuffer);
- UNREFERENCED_PARAMETER(theUnknownBufferLength);
+ UNREFERENCED_PARAMETER(hErrorHardwareEvent);
+ UNREFERENCED_PARAMETER(dwUnusedVar);
+ UNREFERENCED_PARAMETER(lpVideoStateLength);
+ UNREFERENCED_PARAMETER(lpVideoState);
+ UNREFERENCED_PARAMETER(lpUnusedBuffer);
+ UNREFERENCED_PARAMETER(dwUnusedBufferLength);
SetLastError(0);
- DPRINT1("__RegisterConsoleVDM(%d)\n", IsDosVDM_flag);
+ DPRINT1("__RegisterConsoleVDM(%d)\n", dwRegisterFlags);
if (lpVDMBuffer == NULL) return FALSE;
- if (IsDosVDM_flag)
+ if (dwRegisterFlags != 0)
{
- // if (EventHandle_1 == NULL || EventHandle_2 == NULL) return FALSE;
+ // if (hStartHardwareEvent == NULL || hEndHardwareEvent == NULL) return FALSE;
if (VDMBuffer != NULL) return FALSE;
- VDMBufferSize = theVDMBufferSize;
+ VDMBufferSize = dwVDMBufferSize;
/* HACK: Cache -- to be removed in the real implementation */
CharBuff = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
- theVDMBufferSize.X * theVDMBufferSize.Y
- * sizeof(CHAR_INFO));
+ VDMBufferSize.X * VDMBufferSize.Y
+ * sizeof(CHAR_INFO));
ASSERT(CharBuff);
VDMBuffer = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
- theVDMBufferSize.X * theVDMBufferSize.Y
- * sizeof(CHAR_CELL));
- *lpVDMBuffer = (PCHAR)VDMBuffer;
+ VDMBufferSize.X * VDMBufferSize.Y
+ * sizeof(CHAR_CELL));
+ *lpVDMBuffer = VDMBuffer;
return (VDMBuffer != NULL);
}
else
return InvalidateConsoleDIBits(hConsoleOutput, lpRect);
}
+#endif
+
/* PRIVATE FUNCTIONS **********************************************************/
static inline DWORD VgaGetAddressSize(VOID);
VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_LOW_REG] = LOBYTE(Offset);
VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_HIGH_REG] = HIBYTE(Offset);
- VidBiosSyncCursorPosition();
+ // VidBiosSyncCursorPosition();
VgaUpdateTextCursor();
}
ULONG Length = 0;
PVIDEO_HARDWARE_STATE_HEADER State;
+#ifdef USE_REAL_REGISTERCONSOLEVDM
+ PCHAR_INFO CharBuff = NULL;
+#endif
SHORT i, j;
DWORD AddressSize, ScanlineSize;
DWORD Address = 0;
/*
* Windows 2k3 winsrv.dll calls NtVdmControl(VdmQueryVdmProcess == 14, &ConsoleHandle);
* in the two following APIs:
- * SrvRegisterConsoleVDM (corresponding win32 API: RegisterConsoleVDM)
+ * SrvRegisterConsoleVDM (corresponding Win32 API: RegisterConsoleVDM)
* SrvVDMConsoleOperation (corresponding Win32 API: )
* to check whether the current process is a VDM process, and fails otherwise with the
* error 0xC0000022 ().
NULL,
0,
TextResolution,
- (PCHAR*)&TextFramebuffer);
+ (PVOID*)&TextFramebuffer);
if (!Success)
{
DisplayMessage(L"RegisterConsoleVDM failed with error %d\n", GetLastError());
return FALSE;
}
+#ifdef USE_REAL_REGISTERCONSOLEVDM
+ CharBuff = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ TextResolution.X * TextResolution.Y
+ * sizeof(CHAR_INFO));
+ ASSERT(CharBuff);
+#endif
+
/*
* Resize the console
*/
Address += ScanlineSize;
}
+#ifdef USE_REAL_REGISTERCONSOLEVDM
+ if (CharBuff) HeapFree(GetProcessHeap(), 0, CharBuff);
+#endif
+
VgaUpdateCursorPosition();
return TRUE;
}
-BOOL VgaAttachToConsole(VOID)
-{
- 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);
-}
-
-VOID VgaDetachFromConsole(BOOL ChangingMode)
-{
- ULONG dummyLength;
- PVOID dummyPtr;
- COORD dummySize = {0};
-
- __RegisterConsoleVDM(0,
- NULL,
- NULL,
- NULL,
- 0,
- &dummyLength,
- &dummyPtr,
- NULL,
- 0,
- dummySize,
- (PCHAR*)&dummyPtr);
-
- TextFramebuffer = NULL;
-
- if (!ChangingMode)
- {
- SMALL_RECT ConRect;
-
- /* Restore the old screen buffer */
- SetConsoleActiveScreenBuffer(TextConsoleBuffer);
-
- /* Restore the original console size */
- ConRect.Left = 0;
- ConRect.Top = 0;
- ConRect.Right = ConRect.Left + OrgConsoleBufferInfo.srWindow.Right - OrgConsoleBufferInfo.srWindow.Left;
- ConRect.Bottom = ConRect.Top + OrgConsoleBufferInfo.srWindow.Bottom - OrgConsoleBufferInfo.srWindow.Top ;
- /*
- * See the following trick explanation in VgaAttachToConsoleInternal.
- */
- SetConsoleScreenBufferSize(TextConsoleBuffer, OrgConsoleBufferInfo.dwSize);
- SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect);
- SetConsoleScreenBufferSize(TextConsoleBuffer, OrgConsoleBufferInfo.dwSize);
-
- /* Restore the original cursor shape */
- SetConsoleCursorInfo(TextConsoleBuffer, &OrgConsoleCursorInfo);
- }
-}
-
static BOOL IsConsoleHandle(HANDLE hHandle)
{
DWORD dwMode;
static VOID VgaWriteDac(BYTE Data)
{
- INT PaletteIndex;
+ INT i, PaletteIndex;
PALETTEENTRY Entry;
/* Set the value */
Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 2]);
Entry.peFlags = 0;
- /* Update the palette entry and set the palette change flag */
+ /* Update the palette entry */
SetPaletteEntries(PaletteHandle, PaletteIndex, 1, &Entry);
+
+ /* Check which text palette entries are affected */
+ for (i = 0; i <= VGA_AC_PAL_F_REG; i++)
+ {
+ if (VgaAcRegisters[i] == PaletteIndex)
+ {
+ /* Update the text palette entry */
+ SetPaletteEntries(TextPaletteHandle, i, 1, &Entry);
+ }
+ }
+
+ /* Set the palette changed flag */
PaletteChanged = TRUE;
/* Update the index */
static VOID VgaWriteAc(BYTE Data)
{
+ PALETTEENTRY Entry;
+
ASSERT(VgaAcIndex < VGA_AC_MAX_REG);
/* Save the value */
// DbgPrint(" AC Palette Writing %d to index %d\n", Data, VgaAcIndex);
if (VgaAcRegisters[VgaAcIndex] != Data)
{
- /* Update the AC register and set the palette change flag */
+ /* Update the AC register */
VgaAcRegisters[VgaAcIndex] = Data;
+
+ /* Fill the entry structure */
+ Entry.peRed = VGA_DAC_TO_COLOR(VgaDacRegisters[Data * 3]);
+ Entry.peGreen = VGA_DAC_TO_COLOR(VgaDacRegisters[Data * 3 + 1]);
+ Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[Data * 3 + 2]);
+ Entry.peFlags = 0;
+
+ /* Update the palette entry and set the palette change flag */
+ SetPaletteEntries(TextPaletteHandle, VgaAcIndex, 1, &Entry);
PaletteChanged = TRUE;
}
}
static BOOLEAN VgaInitializePalette(VOID)
{
- LPLOGPALETTE Palette;
+ INT i;
+ BOOLEAN Result = FALSE;
+ LPLOGPALETTE Palette, TextPalette;
- /* Allocate storage space for the palette */
+ /* Allocate storage space for the palettes */
Palette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(LOGPALETTE) +
- VGA_MAX_COLORS * sizeof(PALETTEENTRY));
- if (Palette == NULL) return FALSE;
-
- /* Initialize the palette */
- Palette->palVersion = 0x0300;
+ VGA_MAX_COLORS * sizeof(PALETTEENTRY));
+ TextPalette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(LOGPALETTE) +
+ (VGA_AC_PAL_F_REG + 1) * sizeof(PALETTEENTRY));
+ if ((Palette == NULL) || (TextPalette == NULL)) goto Cleanup;
+
+ /* Initialize the palettes */
+ Palette->palVersion = TextPalette->palVersion = 0x0300;
Palette->palNumEntries = VGA_MAX_COLORS;
+ TextPalette->palNumEntries = VGA_AC_PAL_F_REG + 1;
- /* Restore the default palette */
+ /* Restore the default graphics palette */
VgaRestoreDefaultPalette(Palette->palPalEntry, Palette->palNumEntries);
- /* Create the palette */
+ /* Set the default text palette */
+ for (i = 0; i < TextPalette->palNumEntries; i++)
+ {
+ /* Set the palette entries */
+ TextPalette->palPalEntry[i].peRed = GetRValue(ConsoleColors[i]);
+ TextPalette->palPalEntry[i].peGreen = GetGValue(ConsoleColors[i]);
+ TextPalette->palPalEntry[i].peBlue = GetBValue(ConsoleColors[i]);
+ TextPalette->palPalEntry[i].peFlags = 0;
+ }
+
+ /* Create the palettes */
PaletteHandle = CreatePalette(Palette);
+ TextPaletteHandle = CreatePalette(TextPalette);
- /* Free the palette */
- HeapFree(GetProcessHeap(), 0, Palette);
+ if (PaletteHandle != NULL && TextPaletteHandle != NULL)
+ {
+ /* The palettes have been created successfully */
+ Result = TRUE;
+ }
- /* Fail if the palette wasn't successfully created... */
- if (PaletteHandle == NULL) return FALSE;
+Cleanup:
+ /* Free the palettes */
+ if (Palette) HeapFree(GetProcessHeap(), 0, Palette);
+ if (TextPalette) HeapFree(GetProcessHeap(), 0, TextPalette);
- /* ... otherwise return success */
- return TRUE;
+ if (!Result)
+ {
+ /* Something failed, delete the palettes */
+ if (PaletteHandle) DeleteObject(PaletteHandle);
+ if (TextPaletteHandle) DeleteObject(TextPaletteHandle);
+ }
+
+ return Result;
+}
+
+static VOID VgaSetActiveScreenBuffer(HANDLE ScreenBuffer)
+{
+ /* Set the active buffer */
+ SetConsoleActiveScreenBuffer(ScreenBuffer);
+
+ /* Reinitialize the VDM menu */
+ DestroyVdmMenu();
+ CreateVdmMenu(ScreenBuffer);
}
static BOOL VgaEnterGraphicsMode(PCOORD Resolution)
ZeroMemory(ConsoleFramebuffer, BitmapInfo->bmiHeader.biSizeImage);
/* Set the active buffer */
- SetConsoleActiveScreenBuffer(GraphicsConsoleBuffer);
+ VgaSetActiveScreenBuffer(GraphicsConsoleBuffer);
/* Set the graphics mode palette */
SetConsolePalette(GraphicsConsoleBuffer,
ReleaseMutex(ConsoleMutex);
/* Switch back to the default console text buffer */
- // SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+ // VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Cleanup the video data */
CloseHandle(ConsoleMutex);
DPRINT1("VgaEnterTextMode\n");
/* Switch to the text buffer */
- SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+ VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Adjust the text framebuffer if we changed the resolution */
if (TextResolution.X != Resolution->X ||
return FALSE;
}
}
- else VgaUpdateCursorPosition();
+ else
+ {
+ VgaUpdateCursorPosition();
+ }
/* The active framebuffer is now the text framebuffer */
ConsoleFramebuffer = TextFramebuffer;
* screen-buffers, which is a new feature on ReactOS).
*/
SetConsolePalette(TextConsoleBuffer,
- PaletteHandle,
+ TextPaletteHandle,
SYSPAL_NOSTATIC256);
/* Set the screen mode flag */
PaletteChanged = TRUE;
}
+
+
+
+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);
+}
+
+VOID VgaDetachFromConsole(BOOL ChangingMode)
+{
+ ULONG dummyLength;
+ PVOID dummyPtr;
+ COORD dummySize = {0};
+
+ //
+ // FIXME: We should save the screen state
+ //
+
+ __RegisterConsoleVDM(0,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ &dummyLength,
+ &dummyPtr,
+ NULL,
+ 0,
+ dummySize,
+ &dummyPtr);
+
+ TextFramebuffer = NULL;
+
+ if (!ChangingMode)
+ {
+ SMALL_RECT ConRect;
+
+ /* Restore the old screen buffer */
+ VgaSetActiveScreenBuffer(TextConsoleBuffer);
+
+ /* Restore the original console size */
+ ConRect.Left = 0;
+ ConRect.Top = 0;
+ ConRect.Right = ConRect.Left + OrgConsoleBufferInfo.srWindow.Right - OrgConsoleBufferInfo.srWindow.Left;
+ ConRect.Bottom = ConRect.Top + OrgConsoleBufferInfo.srWindow.Bottom - OrgConsoleBufferInfo.srWindow.Top ;
+ /*
+ * See the following trick explanation in VgaAttachToConsoleInternal.
+ */
+ SetConsoleScreenBufferSize(TextConsoleBuffer, OrgConsoleBufferInfo.dwSize);
+ SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect);
+ SetConsoleScreenBufferSize(TextConsoleBuffer, OrgConsoleBufferInfo.dwSize);
+
+ /* Restore the original cursor shape */
+ SetConsoleCursorInfo(TextConsoleBuffer, &OrgConsoleCursorInfo);
+ }
+}
+
BOOLEAN VgaInitialize(HANDLE TextHandle)
{
/* Save the default text-mode console output handle */
/***/ VgaResetPalette(); /***/
/* Switch to the text buffer */
- SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+ VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Clear the VGA memory */
VgaClearMemory();
CloseHandle(AnotherEvent);
CloseHandle(EndEvent);
CloseHandle(StartEvent);
-
-#if 0
- RegisterConsoleVDM = NULL;
- FreeLibrary(hKernel32);
-#endif
}
/* EOF */