mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 05:37:44 +00:00
Bug Fix from Gregor Brunmar (gregor dot brunmar at home dot se), IRC nick ALiENiD
we getting change display working again with this bugfix. details * Added missing info from PrimarySurface.DMW when display driver defaults back to the video drivers standard mode * Fixed caching system in IntEnumDisplaySettings when run more than once * Hacked a way around the bug in FindDDIDriver svn path=/trunk/; revision=28514
This commit is contained in:
parent
c18bbbf9a7
commit
d419e5b695
|
@ -176,6 +176,7 @@ typedef struct _DRIVER_FUNCTIONS
|
||||||
} DRIVER_FUNCTIONS, *PDRIVER_FUNCTIONS;
|
} DRIVER_FUNCTIONS, *PDRIVER_FUNCTIONS;
|
||||||
|
|
||||||
BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver);
|
BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver);
|
||||||
|
PGD_ENABLEDRIVER DRIVER_FindExistingDDIDriver(LPCWSTR Name);
|
||||||
PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name);
|
PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name);
|
||||||
PFILE_OBJECT DRIVER_FindMPDriver(ULONG DisplayNumber);
|
PFILE_OBJECT DRIVER_FindMPDriver(ULONG DisplayNumber);
|
||||||
BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
|
BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
|
||||||
|
@ -186,3 +187,4 @@ INT DRIVER_UnreferenceDriver (LPCWSTR Name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,21 @@ BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PGD_ENABLEDRIVER DRIVER_FindExistingDDIDriver(LPCWSTR Name)
|
||||||
|
{
|
||||||
|
GRAPHICS_DRIVER *Driver = DriverList;
|
||||||
|
while (Driver && Name)
|
||||||
|
{
|
||||||
|
if (!_wcsicmp(Driver->Name, Name))
|
||||||
|
{
|
||||||
|
return Driver->EnableDriver;
|
||||||
|
}
|
||||||
|
Driver = Driver->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
|
PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
|
||||||
{
|
{
|
||||||
static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\";
|
static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\";
|
||||||
|
|
|
@ -600,6 +600,12 @@ IntPrepareDriver()
|
||||||
DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
|
DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the primary surface with what we really got
|
||||||
|
PrimarySurface.DMW.dmPelsWidth = PrimarySurface.GDIInfo.ulHorzRes;
|
||||||
|
PrimarySurface.DMW.dmPelsHeight = PrimarySurface.GDIInfo.ulVertRes;
|
||||||
|
PrimarySurface.DMW.dmBitsPerPel = PrimarySurface.GDIInfo.cBitsPixel;
|
||||||
|
PrimarySurface.DMW.dmDisplayFrequency = PrimarySurface.GDIInfo.ulVRefresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == PrimarySurface.GDIInfo.ulLogPixelsX)
|
if (0 == PrimarySurface.GDIInfo.ulLogPixelsX)
|
||||||
|
@ -2640,6 +2646,68 @@ IntSetDCColor(HDC hDC, ULONG Object, COLORREF Color)
|
||||||
#define SIZEOF_DEVMODEW_400 212
|
#define SIZEOF_DEVMODEW_400 212
|
||||||
#define SIZEOF_DEVMODEW_500 220
|
#define SIZEOF_DEVMODEW_500 220
|
||||||
|
|
||||||
|
static NTSTATUS FASTCALL
|
||||||
|
GetDisplayNumberFromDeviceName(
|
||||||
|
IN PUNICODE_STRING pDeviceName OPTIONAL,
|
||||||
|
OUT ULONG *DisplayNumber)
|
||||||
|
{
|
||||||
|
UNICODE_STRING DisplayString = RTL_CONSTANT_STRING(L"\\\\.\\DISPLAY");
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
ULONG Length;
|
||||||
|
ULONG Number;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
if (DisplayNumber == NULL)
|
||||||
|
return STATUS_INVALID_PARAMETER_2;
|
||||||
|
|
||||||
|
if (pDeviceName && pDeviceName->Length <= DisplayString.Length)
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
|
||||||
|
if (pDeviceName == NULL || pDeviceName->Length == 0)
|
||||||
|
{
|
||||||
|
PWINDOW_OBJECT DesktopObject;
|
||||||
|
HDC DesktopHDC;
|
||||||
|
PDC pDC;
|
||||||
|
|
||||||
|
DesktopObject = UserGetDesktopWindow();
|
||||||
|
DesktopHDC = (HDC)UserGetWindowDC(DesktopObject);
|
||||||
|
pDC = DC_LockDc(DesktopHDC);
|
||||||
|
|
||||||
|
*DisplayNumber = ((GDIDEVICE *)pDC->GDIDevice)->DisplayNumber;
|
||||||
|
|
||||||
|
DC_UnlockDc(DesktopHDC);
|
||||||
|
UserReleaseDC(DesktopObject, DesktopHDC, FALSE);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hack to check if the first parts are equal, by faking the device name length */
|
||||||
|
Length = pDeviceName->Length;
|
||||||
|
pDeviceName->Length = DisplayString.Length;
|
||||||
|
if (RtlEqualUnicodeString(&DisplayString, pDeviceName, FALSE) == FALSE)
|
||||||
|
Status = STATUS_OBJECT_NAME_INVALID;
|
||||||
|
pDeviceName->Length = Length;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Convert the last part of pDeviceName to a number */
|
||||||
|
Number = 0;
|
||||||
|
Length = pDeviceName->Length / sizeof(WCHAR);
|
||||||
|
for (i = DisplayString.Length / sizeof(WCHAR); i < Length; i++)
|
||||||
|
{
|
||||||
|
WCHAR Char = pDeviceName->Buffer[i];
|
||||||
|
if (Char >= L'0' && Char <= L'9')
|
||||||
|
Number = Number * 10 + Char - L'0';
|
||||||
|
else if (Char != L'\0')
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
*DisplayNumber = Number - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief Enumerate possible display settings for the given display...
|
/*! \brief Enumerate possible display settings for the given display...
|
||||||
*
|
*
|
||||||
* \todo Make thread safe!?
|
* \todo Make thread safe!?
|
||||||
|
@ -2655,10 +2723,17 @@ IntEnumDisplaySettings(
|
||||||
{
|
{
|
||||||
static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
|
static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
|
||||||
static DWORD SizeOfCachedDevModes = 0;
|
static DWORD SizeOfCachedDevModes = 0;
|
||||||
|
static UNICODE_STRING CachedDeviceName;
|
||||||
PDEVMODEW CachedMode = NULL;
|
PDEVMODEW CachedMode = NULL;
|
||||||
DEVMODEW DevMode;
|
DEVMODEW DevMode;
|
||||||
INT Size, OldSize;
|
INT Size, OldSize;
|
||||||
ULONG DisplayNumber = 0; /* only default display supported */
|
ULONG DisplayNumber;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(GetDisplayNumberFromDeviceName(pDeviceName, &DisplayNumber)))
|
||||||
|
{
|
||||||
|
SetLastWin32Error(STATUS_NO_SUCH_DEVICE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("DevMode->dmSize = %d\n", pDevMode->dmSize);
|
DPRINT("DevMode->dmSize = %d\n", pDevMode->dmSize);
|
||||||
DPRINT("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra);
|
DPRINT("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra);
|
||||||
|
@ -2693,12 +2768,28 @@ IntEnumDisplaySettings(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (iModeNum == 0 || CachedDevModes == NULL) /* query modes from drivers */
|
BOOL IsCachedDevice = (CachedDevModes != NULL);
|
||||||
|
|
||||||
|
if (CachedDevModes &&
|
||||||
|
((pDeviceName == NULL && CachedDeviceName.Length > 0) ||
|
||||||
|
(pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length == 0) ||
|
||||||
|
(pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length > 0 && RtlEqualUnicodeString(pDeviceName, &CachedDeviceName, TRUE) == FALSE)))
|
||||||
|
{
|
||||||
|
IsCachedDevice = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iModeNum == 0 || IsCachedDevice == FALSE) /* query modes from drivers */
|
||||||
{
|
{
|
||||||
UNICODE_STRING DriverFileNames;
|
UNICODE_STRING DriverFileNames;
|
||||||
LPWSTR CurrentName;
|
LPWSTR CurrentName;
|
||||||
DRVENABLEDATA DrvEnableData;
|
DRVENABLEDATA DrvEnableData;
|
||||||
|
|
||||||
|
/* Free resources from last driver cache */
|
||||||
|
if (IsCachedDevice == FALSE && CachedDeviceName.Buffer != NULL)
|
||||||
|
{
|
||||||
|
RtlFreeUnicodeString(&CachedDeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
/* Retrieve DDI driver names from registry */
|
/* Retrieve DDI driver names from registry */
|
||||||
RtlInitUnicodeString(&DriverFileNames, NULL);
|
RtlInitUnicodeString(&DriverFileNames, NULL);
|
||||||
if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
|
if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
|
||||||
|
@ -2719,9 +2810,12 @@ IntEnumDisplaySettings(
|
||||||
{
|
{
|
||||||
INT i;
|
INT i;
|
||||||
PGD_ENABLEDRIVER GDEnableDriver;
|
PGD_ENABLEDRIVER GDEnableDriver;
|
||||||
|
PGD_GETMODES GetModes = NULL;
|
||||||
|
INT SizeNeeded, SizeUsed;
|
||||||
|
|
||||||
/* Get the DDI driver's entry point */
|
/* Get the DDI driver's entry point */
|
||||||
GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
|
//GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
|
||||||
|
GDEnableDriver = DRIVER_FindExistingDDIDriver(L"DISPLAY");
|
||||||
if (NULL == GDEnableDriver)
|
if (NULL == GDEnableDriver)
|
||||||
{
|
{
|
||||||
DPRINT("FindDDIDriver failed for %S\n", CurrentName);
|
DPRINT("FindDDIDriver failed for %S\n", CurrentName);
|
||||||
|
@ -2743,62 +2837,81 @@ IntEnumDisplaySettings(
|
||||||
for (i = 0; i < DrvEnableData.c; i++)
|
for (i = 0; i < DrvEnableData.c; i++)
|
||||||
{
|
{
|
||||||
PDRVFN DrvFn = DrvEnableData.pdrvfn + i;
|
PDRVFN DrvFn = DrvEnableData.pdrvfn + i;
|
||||||
PGD_GETMODES GetModes;
|
|
||||||
INT SizeNeeded, SizeUsed;
|
|
||||||
|
|
||||||
if (DrvFn->iFunc != INDEX_DrvGetModes)
|
if (DrvFn->iFunc == INDEX_DrvGetModes)
|
||||||
continue;
|
|
||||||
|
|
||||||
GetModes = (PGD_GETMODES)DrvFn->pfn;
|
|
||||||
|
|
||||||
/* make sure we have enough memory to hold the modes */
|
|
||||||
SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject), 0, NULL);
|
|
||||||
if (SizeNeeded <= 0)
|
|
||||||
{
|
{
|
||||||
DPRINT("DrvGetModes failed for %S\n", CurrentName);
|
GetModes = (PGD_GETMODES)DrvFn->pfn;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SizeUsed = CachedDevModesEnd - CachedDevModes;
|
if (GetModes == NULL)
|
||||||
if (SizeOfCachedDevModes - SizeUsed < SizeNeeded)
|
{
|
||||||
{
|
DPRINT("DrvGetModes doesn't exist for %S\n", CurrentName);
|
||||||
PVOID NewBuffer;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
SizeOfCachedDevModes += SizeNeeded;
|
/* make sure we have enough memory to hold the modes */
|
||||||
NewBuffer = ExAllocatePool(PagedPool, SizeOfCachedDevModes);
|
SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject), 0, NULL);
|
||||||
if (NewBuffer == NULL)
|
if (SizeNeeded <= 0)
|
||||||
{
|
{
|
||||||
/* clean up */
|
DPRINT("DrvGetModes failed for %S\n", CurrentName);
|
||||||
ExFreePool(CachedDevModes);
|
|
||||||
SizeOfCachedDevModes = 0;
|
|
||||||
CachedDevModes = NULL;
|
|
||||||
CachedDevModesEnd = NULL;
|
|
||||||
SetLastWin32Error(STATUS_NO_MEMORY);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (CachedDevModes != NULL)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(NewBuffer, CachedDevModes, SizeUsed);
|
|
||||||
ExFreePool(CachedDevModes);
|
|
||||||
}
|
|
||||||
CachedDevModes = NewBuffer;
|
|
||||||
CachedDevModesEnd = (DEVMODEW *)((PCHAR)NewBuffer + SizeUsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* query modes */
|
|
||||||
SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject),
|
|
||||||
SizeOfCachedDevModes - SizeUsed,
|
|
||||||
CachedDevModesEnd);
|
|
||||||
if (SizeNeeded <= 0)
|
|
||||||
{
|
|
||||||
DPRINT("DrvGetModes failed for %S\n", CurrentName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CachedDevModesEnd = (DEVMODEW *)((PCHAR)CachedDevModesEnd + SizeNeeded);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SizeUsed = (PCHAR)CachedDevModesEnd - (PCHAR)CachedDevModes;
|
||||||
|
if (SizeOfCachedDevModes < SizeUsed + SizeNeeded)
|
||||||
|
{
|
||||||
|
PVOID NewBuffer;
|
||||||
|
|
||||||
|
SizeOfCachedDevModes += SizeNeeded;
|
||||||
|
NewBuffer = ExAllocatePool(PagedPool, SizeOfCachedDevModes);
|
||||||
|
if (NewBuffer == NULL)
|
||||||
|
{
|
||||||
|
/* clean up */
|
||||||
|
ExFreePool(CachedDevModes);
|
||||||
|
CachedDevModes = NULL;
|
||||||
|
CachedDevModesEnd = NULL;
|
||||||
|
SizeOfCachedDevModes = 0;
|
||||||
|
|
||||||
|
if (CachedDeviceName.Buffer != NULL)
|
||||||
|
RtlFreeUnicodeString(&CachedDeviceName);
|
||||||
|
|
||||||
|
SetLastWin32Error(STATUS_NO_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (CachedDevModes != NULL)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(NewBuffer, CachedDevModes, SizeUsed);
|
||||||
|
ExFreePool(CachedDevModes);
|
||||||
|
}
|
||||||
|
CachedDevModes = NewBuffer;
|
||||||
|
CachedDevModesEnd = (DEVMODEW *)((PCHAR)NewBuffer + SizeUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsCachedDevice)
|
||||||
|
{
|
||||||
|
if (CachedDeviceName.Buffer != NULL)
|
||||||
|
RtlFreeUnicodeString(&CachedDeviceName);
|
||||||
|
|
||||||
|
if (pDeviceName)
|
||||||
|
IntSafeCopyUnicodeString(&CachedDeviceName, pDeviceName);
|
||||||
|
|
||||||
|
IsCachedDevice = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* query modes */
|
||||||
|
SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject),
|
||||||
|
SizeNeeded,
|
||||||
|
CachedDevModesEnd);
|
||||||
|
if (SizeNeeded <= 0)
|
||||||
|
{
|
||||||
|
DPRINT("DrvGetModes failed for %S\n", CurrentName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CachedDevModesEnd = (DEVMODEW *)((PCHAR)CachedDevModesEnd + SizeNeeded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString(&DriverFileNames);
|
RtlFreeUnicodeString(&DriverFileNames);
|
||||||
|
|
Loading…
Reference in a new issue