Resolution and screen depth change via registry settings, works for at

least the VMware driver

svn path=/trunk/; revision=6430
This commit is contained in:
Gé van Geldorp 2003-10-25 10:59:19 +00:00
parent cf8011aa19
commit afb4b42206
2 changed files with 265 additions and 41 deletions

View file

@ -510,6 +510,28 @@ HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","ImagePath",0x00020000,"system
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Start",0x00010001,0x00000004 HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Start",0x00010001,0x00000004
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Type",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","InstalledDisplayDrivers",0x00010000,"vmx_fb" HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","InstalledDisplayDrivers",0x00010000,"vmx_fb"
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.0",0x00000001,36,34,30,78,34,38,30,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.1",0x00000001,38,30,30,78,36,30,30,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.2",0x00000001,31,30,32,34,78,37,36,38,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.3",0x00000001,31,31,35,32,78,38,36,34,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.4",0x00000001,31,32,38,30,78,39,36,30,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.5",0x00000001,31,32,38,30,78,31,30,32,34,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.6",0x00000001,31,34,30,30,78,31,30,35,30,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.7",0x00000001,31,36,30,30,78,31,32,30,30,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.8",0x00000001,31,37,39,32,78,31,33,34,34,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.9",0x00000001,31,38,35,36,78,31,33,39,32,00
HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","Resolution.10",0x00000001,31,39,32,30,78,31,34,34,30,00
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.Flags",0x00010001,0
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.VRefresh",0x00010001,85
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.XPanning",0x00010001,0
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.YPanning",0x00010001,0
; Select the resolution and depth below
; Available resolutions (Resolution.0 - Resolution.10 above):
; 640x480, 800x600, 1024x768, 1152x864, 1280x960, 1280x1024, 1400x1050, 1600x1200,
; 1792x1344, 1856x1392, 1920x1440, with 8, 16 or 32 bits per pixel
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.BitsPerPel",0x00010001,16
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.XResolution",0x00010001,800
HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vmx_svga\Device0","DefaultSettings.YResolution",0x00010001,600
; Kernel-mode regression test driver ; Kernel-mode regression test driver
HKLM,"SYSTEM\CurrentControlSet\Services\kmregtests","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\kmregtests","ErrorControl",0x00010001,0x00000000

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: dc.c,v 1.90 2003/10/24 08:22:29 gvg Exp $ /* $Id: dc.c,v 1.91 2003/10/25 10:59:19 gvg Exp $
* *
* DC.C - Device context functions * DC.C - Device context functions
* *
@ -51,6 +51,8 @@
#define NDEBUG #define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
#define TAG_DC TAG('D', 'C', 'D', 'C')
static GDIDEVICE PrimarySurface; static GDIDEVICE PrimarySurface;
static BOOL PrimarySurfaceCreated = FALSE; static BOOL PrimarySurfaceCreated = FALSE;
@ -247,18 +249,17 @@ NtGdiCreateCompatableDC(HDC hDC)
return hNewDC; return hNewDC;
} }
static BOOL STDCALL static BOOL FASTCALL
FindDriverFileNames(PUNICODE_STRING DriverFileNames) GetRegistryPath(PUNICODE_STRING RegistryPath)
{ {
RTL_QUERY_REGISTRY_TABLE QueryTable[2]; RTL_QUERY_REGISTRY_TABLE QueryTable[2];
UNICODE_STRING RegistryPath;
NTSTATUS Status; NTSTATUS Status;
RtlInitUnicodeString(&RegistryPath, NULL); RtlInitUnicodeString(RegistryPath, NULL);
RtlZeroMemory(QueryTable, sizeof(QueryTable)); RtlZeroMemory(QueryTable, sizeof(QueryTable));
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
QueryTable[0].Name = L"\\Device\\Video0"; QueryTable[0].Name = L"\\Device\\Video0";
QueryTable[0].EntryContext = &RegistryPath; QueryTable[0].EntryContext = RegistryPath;
Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP, Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
L"VIDEO", L"VIDEO",
@ -266,13 +267,31 @@ FindDriverFileNames(PUNICODE_STRING DriverFileNames)
NULL, NULL,
NULL); NULL);
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
{ {
DPRINT1("No \\Device\\Video0 value in DEVICEMAP\\VIDEO found\n"); DPRINT1("No \\Device\\Video0 value in DEVICEMAP\\VIDEO found\n");
return FALSE; return FALSE;
} }
DPRINT("RegistryPath %S\n", RegistryPath.Buffer); DPRINT("RegistryPath %S\n", RegistryPath.Buffer);
return TRUE;
}
static BOOL FASTCALL
FindDriverFileNames(PUNICODE_STRING DriverFileNames)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
UNICODE_STRING RegistryPath;
NTSTATUS Status;
if (! GetRegistryPath(&RegistryPath))
{
DPRINT("GetRegistryPath failed\n");
return FALSE;
}
RtlZeroMemory(QueryTable, sizeof(QueryTable));
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
QueryTable[0].Name = L"InstalledDisplayDrivers"; QueryTable[0].Name = L"InstalledDisplayDrivers";
QueryTable[0].EntryContext = DriverFileNames; QueryTable[0].EntryContext = DriverFileNames;
@ -283,10 +302,10 @@ FindDriverFileNames(PUNICODE_STRING DriverFileNames)
NULL); NULL);
RtlFreeUnicodeString(&RegistryPath); RtlFreeUnicodeString(&RegistryPath);
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
{ {
DPRINT1("No InstalledDisplayDrivers value in service entry found\n"); DPRINT1("No InstalledDisplayDrivers value in service entry found\n");
return FALSE; return FALSE;
} }
DPRINT("DriverFileNames %S\n", DriverFileNames->Buffer); DPRINT("DriverFileNames %S\n", DriverFileNames->Buffer);
@ -310,6 +329,166 @@ CloseMiniport()
} }
} }
static NTSTATUS STDCALL
DevModeCallback(IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext)
{
PDEVMODEW DevMode = (PDEVMODEW) Context;
DPRINT("Found registry value for name %S: type %d, length %d\n",
ValueName, ValueType, ValueLength);
if (REG_DWORD == ValueType && sizeof(DWORD) == ValueLength)
{
if (0 == _wcsicmp(ValueName, L"DefaultSettings.BitsPerPel"))
{
DevMode->dmBitsPerPel = *((DWORD *) ValueData);
}
else if (0 == _wcsicmp(ValueName, L"DefaultSettings.Flags"))
{
DevMode->dmDisplayFlags = *((DWORD *) ValueData);
}
else if (0 == _wcsicmp(ValueName, L"DefaultSettings.VRefresh"))
{
DevMode->dmDisplayFrequency = *((DWORD *) ValueData);
}
else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XPanning"))
{
DevMode->dmPanningWidth = *((DWORD *) ValueData);
}
else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XResolution"))
{
DevMode->dmPelsWidth = *((DWORD *) ValueData);
}
else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YPanning"))
{
DevMode->dmPanningHeight = *((DWORD *) ValueData);
}
else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YResolution"))
{
DevMode->dmPelsHeight = *((DWORD *) ValueData);
}
}
return STATUS_SUCCESS;
}
static BOOL FASTCALL
SetupDevMode(PDEVMODEW DevMode)
{
static WCHAR RegistryMachineSystem[] = L"\\REGISTRY\\MACHINE\\SYSTEM\\";
static WCHAR CurrentControlSet[] = L"CURRENTCONTROLSET\\";
static WCHAR ControlSet[] = L"CONTROLSET";
static WCHAR Insert[] = L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
UNICODE_STRING RegistryPath;
BOOL Valid;
PWCHAR AfterControlSet;
PWCHAR ProfilePath;
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
NTSTATUS Status;
if (! GetRegistryPath(&RegistryPath))
{
DPRINT("GetRegistryPath failed\n");
return FALSE;
}
Valid = (0 == _wcsnicmp(RegistryPath.Buffer, RegistryMachineSystem,
wcslen(RegistryMachineSystem)));
if (Valid)
{
AfterControlSet = RegistryPath.Buffer + wcslen(RegistryMachineSystem);
if (0 == _wcsnicmp(AfterControlSet, CurrentControlSet, wcslen(CurrentControlSet)))
{
AfterControlSet += wcslen(CurrentControlSet);
}
else if (0 == _wcsnicmp(AfterControlSet, ControlSet, wcslen(ControlSet)))
{
AfterControlSet += wcslen(ControlSet);
while (L'0' <= *AfterControlSet && L'9' <= *AfterControlSet)
{
AfterControlSet++;
}
Valid = (L'\\' == *AfterControlSet);
AfterControlSet++;
}
else
{
Valid = FALSE;
}
}
if (Valid)
{
ProfilePath = ExAllocatePoolWithTag(PagedPool,
(wcslen(RegistryPath.Buffer) +
wcslen(Insert) + 1) * sizeof(WCHAR),
TAG_DC);
if (NULL != ProfilePath)
{
wcsncpy(ProfilePath, RegistryPath.Buffer, AfterControlSet - RegistryPath.Buffer);
wcscpy(ProfilePath + (AfterControlSet - RegistryPath.Buffer), Insert);
wcscat(ProfilePath, AfterControlSet);
RtlZeroMemory(QueryTable, sizeof(QueryTable));
QueryTable[0].QueryRoutine = DevModeCallback;
QueryTable[0].Flags = 0;
QueryTable[0].Name = NULL;
QueryTable[0].EntryContext = NULL;
QueryTable[0].DefaultType = REG_NONE;
QueryTable[0].DefaultData = NULL;
QueryTable[0].DefaultLength = 0;
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
ProfilePath,
QueryTable,
DevMode,
NULL);
if (! NT_SUCCESS(Status))
{
DPRINT1("RtlQueryRegistryValues for %S failed with status 0x%08x\n",
ProfilePath, Status);
Valid = FALSE;
}
else
{
DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n",
DevMode->dmBitsPerPel, DevMode->dmDisplayFrequency,
DevMode->dmPelsWidth, DevMode->dmPelsHeight);
if (0 == DevMode->dmBitsPerPel || 0 == DevMode->dmDisplayFrequency
|| 0 == DevMode->dmPelsWidth || 0 == DevMode->dmPelsHeight)
{
DPRINT("Not all required devmode members are set\n");
Valid = FALSE;
}
}
ExFreePool(ProfilePath);
}
else
{
Valid = FALSE;
}
}
else
{
DPRINT1("Unparsable registry path %S in DEVICEMAP\\VIDEO0", RegistryPath.Buffer);
}
RtlFreeUnicodeString(&RegistryPath);
if (! Valid)
{
RtlZeroMemory(DevMode, sizeof(DEVMODEW));
}
return Valid;
}
BOOL STDCALL BOOL STDCALL
NtGdiCreatePrimarySurface(LPCWSTR Driver, NtGdiCreatePrimarySurface(LPCWSTR Driver,
LPCWSTR Device) LPCWSTR Device)
@ -321,6 +500,7 @@ NtGdiCreatePrimarySurface(LPCWSTR Driver,
UNICODE_STRING DriverFileNames; UNICODE_STRING DriverFileNames;
PWSTR CurrentName; PWSTR CurrentName;
BOOL GotDriver; BOOL GotDriver;
BOOL DoDefault;
extern void FASTCALL IntInitDesktopWindow(ULONG Width, ULONG Height); extern void FASTCALL IntInitDesktopWindow(ULONG Width, ULONG Height);
/* Open the miniport driver */ /* Open the miniport driver */
@ -400,33 +580,55 @@ NtGdiCreatePrimarySurface(LPCWSTR Driver,
} }
/* Allocate a phyical device handle from the driver */ /* Allocate a phyical device handle from the driver */
if (Device != NULL) if (SetupDevMode(&PrimarySurface.DMW))
{ {
DPRINT("Device in u: %u\n", Device); PrimarySurface.PDev =
// wcsncpy(NewDC->DMW.dmDeviceName, Device, DMMAXDEVICENAME); FIXME: this crashes everything? PrimarySurface.DriverFunctions.EnablePDev(&PrimarySurface.DMW,
} L"",
HS_DDI_MAX,
PrimarySurface.FillPatterns,
sizeof(PrimarySurface.GDIInfo),
(ULONG *) &PrimarySurface.GDIInfo,
sizeof(PrimarySurface.DevInfo),
&PrimarySurface.DevInfo,
NULL,
L"",
PrimarySurface.DisplayDevice);
DoDefault = (NULL == PrimarySurface.PDev);
if (DoDefault)
{
DPRINT1("DrvEnablePDev with registry parameters failed\n");
}
}
else
{
DoDefault = TRUE;
}
DPRINT("Enabling PDev\n"); if (DoDefault)
{
RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
PrimarySurface.PDev =
PrimarySurface.DriverFunctions.EnablePDev(&PrimarySurface.DMW,
L"",
HS_DDI_MAX,
PrimarySurface.FillPatterns,
sizeof(PrimarySurface.GDIInfo),
(ULONG *) &PrimarySurface.GDIInfo,
sizeof(PrimarySurface.DevInfo),
&PrimarySurface.DevInfo,
NULL,
L"",
PrimarySurface.DisplayDevice);
PrimarySurface.PDev = if (NULL == PrimarySurface.PDev)
PrimarySurface.DriverFunctions.EnablePDev(&PrimarySurface.DMW, {
L"", CloseMiniport();
HS_DDI_MAX, DPRINT1("DrvEnablePDEV with default parameters failed\n");
PrimarySurface.FillPatterns, DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
sizeof(PrimarySurface.GDIInfo), return FALSE;
(ULONG *) &PrimarySurface.GDIInfo, }
sizeof(PrimarySurface.DevInfo), }
&PrimarySurface.DevInfo,
NULL,
L"",
PrimarySurface.DisplayDevice);
if (PrimarySurface.PDev == NULL)
{
CloseMiniport();
DPRINT1("DrvEnablePDEV failed\n");
DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
return(FALSE);
}
if (0 == PrimarySurface.GDIInfo.ulLogPixelsX) if (0 == PrimarySurface.GDIInfo.ulLogPixelsX)
{ {
@ -1578,7 +1780,7 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj)
if(pb->dib->dsBmih.biBitCount == 4) { NumColors = 16; } else if(pb->dib->dsBmih.biBitCount == 4) { NumColors = 16; } else
if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; } if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; }
ColorMap = ExAllocatePool(PagedPool, sizeof(COLORREF) * NumColors); ColorMap = ExAllocatePoolWithTag(PagedPool, sizeof(COLORREF) * NumColors, TAG_DC);
ASSERT(ColorMap); ASSERT(ColorMap);
for (Index = 0; Index < NumColors; Index++) for (Index = 0; Index < NumColors; Index++)
{ {
@ -1680,7 +1882,7 @@ DC_AllocDC(LPCWSTR Driver)
if (Driver != NULL) if (Driver != NULL)
{ {
NewDC->DriverName = ExAllocatePool(PagedPool, (wcslen(Driver) + 1) * sizeof(WCHAR)); NewDC->DriverName = ExAllocatePoolWithTag(PagedPool, (wcslen(Driver) + 1) * sizeof(WCHAR), TAG_DC);
wcscpy(NewDC->DriverName, Driver); wcscpy(NewDC->DriverName, Driver);
} }