mirror of
https://github.com/reactos/reactos.git
synced 2025-01-02 20:43:18 +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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -259,19 +259,6 @@ NtUserEnumDisplayMonitors(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
|
||||||
STDCALL
|
|
||||||
NtUserEnumDisplaySettings(
|
|
||||||
PUNICODE_STRING lpszDeviceName,
|
|
||||||
DWORD iModeNum,
|
|
||||||
LPDEVMODEW lpDevMode, /* FIXME is this correct? */
|
|
||||||
DWORD dwFlags )
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
NtUserEvent(
|
NtUserEvent(
|
||||||
|
|
|
@ -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: 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -833,4 +833,83 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window, int DeltaX, int DeltaY)
|
||||||
DCE_UnlockList();
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -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.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
|
* DC.C - Device context functions
|
||||||
*
|
*
|
||||||
|
@ -497,7 +497,7 @@ IntCreatePrimarySurface()
|
||||||
CurrentName = DriverFileNames.Buffer;
|
CurrentName = DriverFileNames.Buffer;
|
||||||
GotDriver = FALSE;
|
GotDriver = FALSE;
|
||||||
while (!GotDriver &&
|
while (!GotDriver &&
|
||||||
CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
|
CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
|
||||||
{
|
{
|
||||||
/* Get the DDI driver's entry point */
|
/* Get the DDI driver's entry point */
|
||||||
GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
|
GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
|
||||||
|
@ -524,11 +524,11 @@ IntCreatePrimarySurface()
|
||||||
{
|
{
|
||||||
/* Skip to the next name but never get past the Unicode string */
|
/* Skip to the next name but never get past the Unicode string */
|
||||||
while (L'\0' != *CurrentName &&
|
while (L'\0' != *CurrentName &&
|
||||||
CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
|
CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
|
||||||
{
|
{
|
||||||
CurrentName++;
|
CurrentName++;
|
||||||
}
|
}
|
||||||
if (CurrentName < DriverFileNames.Buffer + DriverFileNames.Length)
|
if (CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
|
||||||
{
|
{
|
||||||
CurrentName++;
|
CurrentName++;
|
||||||
}
|
}
|
||||||
|
@ -558,6 +558,7 @@ IntCreatePrimarySurface()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a phyical device handle from the driver */
|
/* Allocate a phyical device handle from the driver */
|
||||||
|
PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
|
||||||
if (SetupDevMode(&PrimarySurface.DMW, DisplayNumber))
|
if (SetupDevMode(&PrimarySurface.DMW, DisplayNumber))
|
||||||
{
|
{
|
||||||
PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
|
PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
|
||||||
|
@ -586,6 +587,7 @@ IntCreatePrimarySurface()
|
||||||
if (DoDefault)
|
if (DoDefault)
|
||||||
{
|
{
|
||||||
RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
|
RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
|
||||||
|
PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
|
||||||
PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
|
PrimarySurface.PDev = PrimarySurface.DriverFunctions.EnablePDEV(
|
||||||
&PrimarySurface.DMW,
|
&PrimarySurface.DMW,
|
||||||
L"",
|
L"",
|
||||||
|
@ -2163,4 +2165,207 @@ IntSetDCColor(HDC hDC, ULONG Object, COLORREF Color)
|
||||||
return CLR_INVALID;
|
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 */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue