mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +00:00
Implement NtUserEnumDisplaySettings/IntEnumDisplaySettings.
svn path=/trunk/; revision=10377
This commit is contained in:
parent
16904f000e
commit
57da2ced76
3 changed files with 290 additions and 19 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: stubs.c,v 1.45 2004/04/29 20:26:35 weiden Exp $
|
||||
/* $Id: stubs.c,v 1.46 2004/08/03 19:55:57 blight Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -259,19 +259,6 @@ NtUserEnumDisplayMonitors(
|
|||
return 0;
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
NtUserEnumDisplaySettings(
|
||||
PUNICODE_STRING lpszDeviceName,
|
||||
DWORD iModeNum,
|
||||
LPDEVMODEW lpDevMode, /* FIXME is this correct? */
|
||||
DWORD dwFlags )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
NtUserEvent(
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: windc.c,v 1.66 2004/05/10 17:07:18 weiden Exp $
|
||||
/* $Id: windc.c,v 1.67 2004/08/03 19:55:57 blight Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -833,4 +833,83 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window, int DeltaX, int DeltaY)
|
|||
DCE_UnlockList();
|
||||
}
|
||||
|
||||
/* FIXME: find header file for this prototype. */
|
||||
extern BOOL FASTCALL
|
||||
IntEnumDisplaySettings(
|
||||
PUNICODE_STRING lpszDeviceName,
|
||||
DWORD iModeNum,
|
||||
LPDEVMODEW lpDevMode,
|
||||
DWORD dwFlags);
|
||||
|
||||
#define COPY_DEVMODE_VALUE_TO_CALLER(dst, src, member) \
|
||||
Status = MmCopyToCaller(&(dst)->member, &(src)->member, sizeof ((src)->member)); \
|
||||
if (!NT_SUCCESS(Status)) \
|
||||
{ \
|
||||
SetLastNtError(Status); \
|
||||
ExFreePool(src); \
|
||||
return FALSE; \
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
NtUserEnumDisplaySettings(
|
||||
PUNICODE_STRING lpszDeviceName,
|
||||
DWORD iModeNum,
|
||||
LPDEVMODEW lpDevMode, /* FIXME is this correct? */
|
||||
DWORD dwFlags )
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LPDEVMODEW pSafeDevMode;
|
||||
DWORD Size = 0, ExtraSize = 0;
|
||||
|
||||
Status = MmCopyFromCaller(&Size, &lpDevMode->dmSize, sizeof (lpDevMode->dmSize));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastNtError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
Status = MmCopyFromCaller(&ExtraSize, &lpDevMode->dmDriverExtra, sizeof (lpDevMode->dmDriverExtra));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastNtError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
pSafeDevMode = ExAllocatePool(PagedPool, Size + ExtraSize);
|
||||
if (pSafeDevMode == NULL)
|
||||
{
|
||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return DISP_CHANGE_FAILED;
|
||||
}
|
||||
pSafeDevMode->dmSize = Size;
|
||||
pSafeDevMode->dmDriverExtra = ExtraSize;
|
||||
|
||||
if (!IntEnumDisplaySettings(lpszDeviceName, iModeNum, pSafeDevMode, dwFlags))
|
||||
{
|
||||
ExFreePool(pSafeDevMode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsWidth);
|
||||
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsHeight);
|
||||
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmBitsPerPel);
|
||||
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmDisplayFrequency);
|
||||
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmDisplayFlags);
|
||||
|
||||
/* output private/extra driver data */
|
||||
if (ExtraSize > 0)
|
||||
{
|
||||
Status = MmCopyToCaller((PCHAR)lpDevMode + Size, (PCHAR)pSafeDevMode + Size, ExtraSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastNtError(Status);
|
||||
ExFreePool(pSafeDevMode);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#undef COPY_DEVMODE_VALUE_TO_CALLER
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: dc.c,v 1.145 2004/07/17 21:10:25 weiden Exp $
|
||||
/* $Id: dc.c,v 1.146 2004/08/03 19:55:58 blight Exp $
|
||||
*
|
||||
* DC.C - Device context functions
|
||||
*
|
||||
|
@ -497,7 +497,7 @@ IntCreatePrimarySurface()
|
|||
CurrentName = DriverFileNames.Buffer;
|
||||
GotDriver = FALSE;
|
||||
while (!GotDriver &&
|
||||
CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
|
||||
CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
|
||||
{
|
||||
/* Get the DDI driver's entry point */
|
||||
GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
|
||||
|
@ -524,11 +524,11 @@ IntCreatePrimarySurface()
|
|||
{
|
||||
/* Skip to the next name but never get past the Unicode string */
|
||||
while (L'\0' != *CurrentName &&
|
||||
CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
|
||||
CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
|
||||
{
|
||||
CurrentName++;
|
||||
}
|
||||
if (CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
|
||||
if (CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
|
||||
{
|
||||
CurrentName++;
|
||||
}
|
||||
|
@ -558,6 +558,7 @@ IntCreatePrimarySurface()
|
|||
}
|
||||
|
||||
/* Allocate a phyical device handle from the driver */
|
||||
PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
|
||||
if (SetupDevMode(&PrimarySurface.DMW, DisplayNumber))
|
||||
{
|
||||
PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
|
||||
|
@ -586,6 +587,7 @@ IntCreatePrimarySurface()
|
|||
if (DoDefault)
|
||||
{
|
||||
RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
|
||||
PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
|
||||
PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
|
||||
&PrimarySurface.DMW,
|
||||
L"",
|
||||
|
@ -2163,4 +2165,207 @@ IntSetDCColor(HDC hDC, ULONG Object, COLORREF Color)
|
|||
return CLR_INVALID;
|
||||
}
|
||||
|
||||
#define SIZEOF_DEVMODEW_300 188
|
||||
#define SIZEOF_DEVMODEW_400 212
|
||||
#define SIZEOF_DEVMODEW_500 220
|
||||
|
||||
/*! \brief Enumerate possible display settings for the given display...
|
||||
*
|
||||
* \todo Make thread safe!?
|
||||
* \todo Don't ignore lpszDeviceName
|
||||
* \todo Implement non-raw mode (only return settings valid for driver and monitor)
|
||||
*/
|
||||
BOOL FASTCALL
|
||||
IntEnumDisplaySettings(
|
||||
PUNICODE_STRING lpszDeviceName,
|
||||
DWORD iModeNum,
|
||||
LPDEVMODEW lpDevMode,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
|
||||
static DWORD SizeOfCachedDevModes = 0;
|
||||
LPDEVMODEW CachedMode = NULL;
|
||||
DEVMODEW DevMode;
|
||||
INT Size, OldSize;
|
||||
ULONG DisplayNumber = 0; /* only default display supported */
|
||||
|
||||
if (lpDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
|
||||
lpDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
|
||||
lpDevMode->dmSize != SIZEOF_DEVMODEW_500)
|
||||
{
|
||||
SetLastWin32Error(STATUS_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (iModeNum == ENUM_CURRENT_SETTINGS)
|
||||
{
|
||||
CachedMode = &PrimarySurface.DMW;
|
||||
assert(CachedMode->dmSize > 0);
|
||||
}
|
||||
else if (iModeNum == ENUM_REGISTRY_SETTINGS)
|
||||
{
|
||||
RtlZeroMemory(&DevMode, sizeof (DevMode));
|
||||
DevMode.dmSize = sizeof (DevMode);
|
||||
DevMode.dmDriverExtra = 0;
|
||||
if (SetupDevMode(&DevMode, DisplayNumber))
|
||||
CachedMode = &DevMode;
|
||||
else
|
||||
{
|
||||
SetLastWin32Error(0); /* FIXME: use error code */
|
||||
return FALSE;
|
||||
}
|
||||
/* FIXME: Maybe look for the matching devmode supplied by the
|
||||
* driver so we can provide driver private/extra data?
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iModeNum == 0 || CachedDevModes == NULL) /* query modes from drivers */
|
||||
{
|
||||
UNICODE_STRING DriverFileNames;
|
||||
LPWSTR CurrentName;
|
||||
DRVENABLEDATA DrvEnableData;
|
||||
|
||||
/* Retrieve DDI driver names from registry */
|
||||
RtlInitUnicodeString(&DriverFileNames, NULL);
|
||||
if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
|
||||
{
|
||||
DPRINT1("FindDriverFileNames failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
|
||||
* scan all of them until a good one found.
|
||||
*/
|
||||
CurrentName = DriverFileNames.Buffer;
|
||||
for (;CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR));
|
||||
CurrentName += wcslen(CurrentName) + 1)
|
||||
{
|
||||
INT i;
|
||||
PGD_ENABLEDRIVER GDEnableDriver;
|
||||
|
||||
/* Get the DDI driver's entry point */
|
||||
GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
|
||||
if (NULL == GDEnableDriver)
|
||||
{
|
||||
DPRINT("FindDDIDriver failed for %S\n", CurrentName);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Call DDI driver's EnableDriver function */
|
||||
RtlZeroMemory(&DrvEnableData, sizeof (DrvEnableData));
|
||||
|
||||
if (!GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof (DrvEnableData), &DrvEnableData))
|
||||
{
|
||||
DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
|
||||
continue;
|
||||
}
|
||||
|
||||
CachedDevModesEnd = CachedDevModes;
|
||||
|
||||
/* find DrvGetModes function */
|
||||
for (i = 0; i < DrvEnableData.c; i++)
|
||||
{
|
||||
PDRVFN DrvFn = DrvEnableData.pdrvfn + i;
|
||||
PGD_GETMODES GetModes;
|
||||
INT SizeNeeded, SizeUsed;
|
||||
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
SizeUsed = CachedDevModesEnd - CachedDevModes;
|
||||
if (SizeOfCachedDevModes - SizeUsed < SizeNeeded)
|
||||
{
|
||||
PVOID NewBuffer;
|
||||
|
||||
SizeOfCachedDevModes += SizeNeeded;
|
||||
NewBuffer = ExAllocatePool(PagedPool, SizeOfCachedDevModes);
|
||||
if (NewBuffer == NULL)
|
||||
{
|
||||
/* clean up */
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&DriverFileNames);
|
||||
}
|
||||
|
||||
/* return cached info */
|
||||
CachedMode = CachedDevModes;
|
||||
if (CachedMode >= CachedDevModesEnd)
|
||||
{
|
||||
SetLastWin32Error(STATUS_NO_MORE_ENTRIES);
|
||||
return FALSE;
|
||||
}
|
||||
while (iModeNum-- > 0 && CachedMode < CachedDevModesEnd)
|
||||
{
|
||||
assert(CachedMode->dmSize > 0);
|
||||
CachedMode = (DEVMODEW *)((PCHAR)CachedMode + CachedMode->dmSize + CachedMode->dmDriverExtra);
|
||||
}
|
||||
if (CachedMode >= CachedDevModesEnd)
|
||||
{
|
||||
SetLastWin32Error(STATUS_NO_MORE_ENTRIES);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
assert(CachedMode != NULL);
|
||||
|
||||
Size = OldSize = lpDevMode->dmSize;
|
||||
if (Size > CachedMode->dmSize)
|
||||
Size = CachedMode->dmSize;
|
||||
RtlCopyMemory(lpDevMode, CachedMode, Size);
|
||||
RtlZeroMemory((PCHAR)lpDevMode + Size, OldSize - Size);
|
||||
lpDevMode->dmSize = OldSize;
|
||||
|
||||
Size = OldSize = lpDevMode->dmDriverExtra;
|
||||
if (Size > CachedMode->dmDriverExtra)
|
||||
Size = CachedMode->dmDriverExtra;
|
||||
RtlCopyMemory((PCHAR)lpDevMode + lpDevMode->dmSize,
|
||||
(PCHAR)CachedMode + CachedMode->dmSize, Size);
|
||||
RtlZeroMemory((PCHAR)lpDevMode + lpDevMode->dmSize + Size, OldSize - Size);
|
||||
lpDevMode->dmDriverExtra = OldSize;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue