Improve the WNDOBJ implementation a bit... There are still some problems with the visible area when a window is overlapped by another one...

svn path=/trunk/; revision=14111
This commit is contained in:
Gregor Anich 2005-03-15 22:26:12 +00:00
parent d24e173122
commit d001f75197
10 changed files with 415 additions and 81 deletions

View file

@ -130,6 +130,8 @@ typedef BOOL STDCALL (*PFN_GradientFill)(SURFOBJ*, CLIPOBJ*, XLATEOBJ*, TRIVERTE
typedef struct _WNDGDI {
WNDOBJ WndObj;
LIST_ENTRY ListEntry;
HWND Hwnd;
CLIPOBJ *ClientClipObj;
WNDOBJCHANGEPROC ChangeProc;
FLONG Flags;

View file

@ -26,6 +26,9 @@
* REVISION HISTORY:
* 16/11/2004: Created
*/
/* TODO: Check how the WNDOBJ implementation should behave with a driver on windows. */
#include <w32k.h>
/*
@ -33,9 +36,9 @@
*/
VOID
FASTCALL
IntEngWndChanged(
IN WNDOBJ *pwo,
IN FLONG flChanged)
IntEngWndCallChangeProc(
IN WNDOBJ *pwo,
IN FLONG flChanged)
{
WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
@ -62,23 +65,145 @@ IntEngWndChanged(
WndObjInt->ChangeProc(pwo, flChanged);
}
/*
* Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WINDOW_OBJECT
*/
BOOLEAN
FASTCALL
IntEngWndUpdateClipObj(
WNDGDI *WndObjInt,
PWINDOW_OBJECT Window)
{
HRGN hVisRgn;
PROSRGNDATA visRgn;
CLIPOBJ *ClipObj = NULL;
CLIPOBJ *OldClipObj;
hVisRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE);
if (hVisRgn != NULL)
{
NtGdiOffsetRgn(hVisRgn, Window->ClientRect.left, Window->ClientRect.top);
visRgn = RGNDATA_LockRgn(hVisRgn);
if (visRgn != NULL)
{
if (visRgn->rdh.nCount > 0)
{
ClipObj = IntEngCreateClipRegion(visRgn->rdh.nCount, (PRECTL)visRgn->Buffer,
(PRECTL)&visRgn->rdh.rcBound);
DPRINT("Created visible region with %d rects\n", visRgn->rdh.nCount);
DPRINT(" BoundingRect: %d, %d %d, %d\n",
visRgn->rdh.rcBound.left, visRgn->rdh.rcBound.top,
visRgn->rdh.rcBound.right, visRgn->rdh.rcBound.bottom);
{
INT i;
for (i = 0; i < visRgn->rdh.nCount; i++)
{
DPRINT(" Rect #%d: %d,%d %d,%d\n", i+1,
visRgn->Buffer[i].left, visRgn->Buffer[i].top,
visRgn->Buffer[i].right, visRgn->Buffer[i].bottom);
}
}
}
RGNDATA_UnlockRgn(hVisRgn);
}
else
{
DPRINT1("Warning: Couldn't lock visible region of window DC\n");
}
}
else
{
DPRINT1("Warning: VIS_ComputeVisibleRegion failed!\n");
}
if (ClipObj == NULL)
{
/* Fall back to client rect */
ClipObj = IntEngCreateClipRegion(1, (PRECTL)&Window->ClientRect,
(PRECTL)&Window->ClientRect);
}
if (ClipObj == NULL)
{
DPRINT1("Warning: IntEngCreateClipRegion() failed!\n");
return FALSE;
}
RtlCopyMemory(&WndObjInt->WndObj.coClient, ClipObj, sizeof (CLIPOBJ));
RtlCopyMemory(&WndObjInt->WndObj.rclClient, &Window->ClientRect, sizeof (RECT));
OldClipObj = InterlockedExchangePointer(&WndObjInt->ClientClipObj, ClipObj);
if (OldClipObj != NULL)
IntEngDeleteClipRegion(OldClipObj);
return TRUE;
}
/*
* Updates all WNDOBJs of the given WINDOW_OBJECT and calls the change-procs.
*/
VOID
FASTCALL
IntEngWindowChanged(
PWINDOW_OBJECT Window,
FLONG flChanged)
{
PLIST_ENTRY CurrentEntry;
WNDGDI *Current;
ASSERT_IRQL(PASSIVE_LEVEL);
ExAcquireFastMutex(&Window->WndObjListLock);
CurrentEntry = Window->WndObjListHead.Flink;
while (CurrentEntry != &Window->WndObjListHead)
{
Current = CONTAINING_RECORD(CurrentEntry, WNDGDI, ListEntry);
if (Current->WndObj.pvConsumer != NULL)
{
/* Update the WNDOBJ */
switch (flChanged)
{
case WOC_RGN_CLIENT:
/* Update the clipobj and client rect of the WNDOBJ */
IntEngWndUpdateClipObj(Current, Window);
break;
case WOC_DELETE:
/* FIXME: Should the WNDOBJs be deleted by win32k or by the driver? */
break;
}
/* Call the change proc */
IntEngWndCallChangeProc(&Current->WndObj, flChanged);
/* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */
if (flChanged == WOC_RGN_CLIENT)
{
IntEngWndCallChangeProc(&Current->WndObj, WOC_CHANGED);
}
CurrentEntry = CurrentEntry->Flink;
}
}
ExReleaseFastMutex(&Window->WndObjListLock);
}
/*
* @implemented
*/
WNDOBJ*
STDCALL
EngCreateWnd(
SURFOBJ *pso,
HWND hwnd,
WNDOBJCHANGEPROC pfn,
FLONG fl,
int iPixelFormat
)
SURFOBJ *pso,
HWND hwnd,
WNDOBJCHANGEPROC pfn,
FLONG fl,
int iPixelFormat)
{
WNDGDI *WndObjInt = NULL;
WNDOBJ *WndObjUser = NULL;
PWINDOW_OBJECT Window;
CLIPOBJ *ClientClipObj;
DPRINT("EngCreateWnd: pso = 0x%x, hwnd = 0x%x, pfn = 0x%x, fl = 0x%x, pixfmt = %d\n",
pso, hwnd, pfn, fl, iPixelFormat);
@ -99,27 +224,30 @@ EngCreateWnd(
return NULL;
}
ClientClipObj = IntEngCreateClipRegion(1, (PRECTL)&Window->ClientRect,
(PRECTL)&Window->ClientRect);
if (ClientClipObj == NULL)
/* Fill the clipobj */
WndObjInt->ClientClipObj = NULL;
if (!IntEngWndUpdateClipObj(WndObjInt, Window))
{
IntReleaseWindowObject(Window);
EngFreeMem(WndObjInt);
return NULL;
}
/* fill user object */
/* Fill user object */
WndObjUser = GDIToObj(WndObjInt, WND);
WndObjUser->psoOwner = pso;
WndObjUser->pvConsumer = NULL;
RtlCopyMemory(&WndObjUser->rclClient, &Window->ClientRect, sizeof (RECT));
RtlCopyMemory(&WndObjUser->coClient, ClientClipObj, sizeof (CLIPOBJ));
/* fill internal object */
/* Fill internal object */
WndObjInt->Hwnd = hwnd;
WndObjInt->ChangeProc = pfn;
WndObjInt->Flags = fl;
WndObjInt->PixelFormat = iPixelFormat;
WndObjInt->ClientClipObj = ClientClipObj;
/* associate object with window */
ExAcquireFastMutex(&Window->WndObjListLock);
InsertTailList(&Window->WndObjListHead, &WndObjInt->ListEntry);
ExReleaseFastMutex(&Window->WndObjListLock);
/* release resources */
IntReleaseWindowObject(Window);
@ -135,12 +263,31 @@ EngCreateWnd(
*/
VOID
STDCALL
EngDeleteWnd ( IN WNDOBJ *pwo )
EngDeleteWnd(
IN WNDOBJ *pwo)
{
WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
PWINDOW_OBJECT Window;
DPRINT("EngDeleteWnd: pwo = 0x%x\n", pwo);
/* Get window object */
Window = IntGetWindowObject(WndObjInt->Hwnd);
if (Window == NULL)
{
DPRINT1("Warning: Couldnt get window object for WndObjInt->Hwnd!!!\n");
RemoveEntryList(&WndObjInt->ListEntry);
}
else
{
/* Remove object from window */
ExAcquireFastMutex(&Window->WndObjListLock);
RemoveEntryList(&WndObjInt->ListEntry);
ExReleaseFastMutex(&Window->WndObjListLock);
IntReleaseWindowObject(Window);
}
/* Free resources */
IntEngDeleteClipRegion(WndObjInt->ClientClipObj);
EngFreeMem(WndObjInt);
}
@ -152,10 +299,9 @@ EngDeleteWnd ( IN WNDOBJ *pwo )
BOOL
STDCALL
WNDOBJ_bEnum(
IN WNDOBJ *pwo,
IN ULONG cj,
OUT ULONG *pul
)
IN WNDOBJ *pwo,
IN ULONG cj,
OUT ULONG *pul)
{
WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
BOOL Ret;
@ -174,11 +320,10 @@ WNDOBJ_bEnum(
ULONG
STDCALL
WNDOBJ_cEnumStart(
IN WNDOBJ *pwo,
IN ULONG iType,
IN ULONG iDirection,
IN ULONG cLimit
)
IN WNDOBJ *pwo,
IN ULONG iType,
IN ULONG iDirection,
IN ULONG cLimit)
{
WNDGDI *WndObjInt = ObjToGDI(pwo, WND);
ULONG Ret;
@ -200,9 +345,8 @@ WNDOBJ_cEnumStart(
VOID
STDCALL
WNDOBJ_vSetConsumer(
IN WNDOBJ *pwo,
IN PVOID pvConsumer
)
IN WNDOBJ *pwo,
IN PVOID pvConsumer)
{
BOOL Hack;
@ -211,12 +355,19 @@ WNDOBJ_vSetConsumer(
Hack = (pwo->pvConsumer == NULL);
pwo->pvConsumer = pvConsumer;
/* HACKHACKHACK */
/* HACKHACKHACK
*
* MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state
* when a WNDOBJ is created - we do it here because most drivers will need pvConsumer
* in the callback to identify the WNDOBJ I think.
*
* - blight
*/
if (Hack)
{
IntEngWndChanged(pwo, WOC_RGN_CLIENT);
IntEngWndChanged(pwo, WOC_CHANGED);
IntEngWndChanged(pwo, WOC_DRAWN);
IntEngWndCallChangeProc(pwo, WOC_RGN_CLIENT);
IntEngWndCallChangeProc(pwo, WOC_CHANGED);
IntEngWndCallChangeProc(pwo, WOC_DRAWN);
}
}

View file

@ -15,4 +15,9 @@ IntEngMaskBlt(SURFOBJ *DestObj,
BRUSHOBJ *Brush,
POINTL *BrushOrigin);
VOID FASTCALL
IntEngWindowChanged(
PWINDOW_OBJECT Window,
FLONG flChanged);
#endif /* _WIN32K_ENG_H */

View file

@ -193,5 +193,21 @@ IntGdiEscape(PDC dc,
LPCSTR InData,
LPVOID OutData);
BOOL
FASTCALL
IntEnumDisplaySettings(
IN PUNICODE_STRING pDeviceName OPTIONAL,
IN DWORD iModeNum,
IN OUT LPDEVMODEW pDevMode,
IN DWORD dwFlags);
LONG
FASTCALL
IntChangeDisplaySettings(
IN PUNICODE_STRING pDeviceName OPTIONAL,
IN LPDEVMODEW pDevMode,
IN DWORD dwflags,
IN PVOID lParam OPTIONAL);
#endif /* _WIN32K_INTGDI_H */

View file

@ -99,6 +99,9 @@ typedef struct _WINDOW_OBJECT
ULONG Status;
/* counter for tiled child windows */
ULONG TiledCounter;
/* WNDOBJ list */
LIST_ENTRY WndObjListHead;
FAST_MUTEX WndObjListLock;
} WINDOW_OBJECT; /* PWINDOW_OBJECT already declared at top of file */
/* Window flags. */

View file

@ -110,20 +110,6 @@ NtUserCallMsgFilter(
return 0;
}
LONG
STDCALL
NtUserChangeDisplaySettings(
PUNICODE_STRING lpszDeviceName,
LPDEVMODEW lpDevMode,
HWND hwnd,
DWORD dwflags,
LPVOID lParam)
{
// UNIMPLEMENTED
DbgPrint("(%s:%i) WIN32K: %s UNIMPLEMENTED\n", __FILE__, __LINE__, __FUNCTION__ );
return DISP_CHANGE_BADMODE;
}
DWORD
STDCALL
NtUserConvertMemHandle(

View file

@ -354,6 +354,11 @@ noparent:
Dce->DCXFlags &= ~DCX_DCEDIRTY;
NtGdiSelectVisRgn(Dce->hDC, hRgnVisible);
if (Window != NULL)
{
IntEngWindowChanged(Window, WOC_RGN_CLIENT);
}
if (hRgnVisible != NULL)
{
NtGdiDeleteObject(hRgnVisible);
@ -856,6 +861,7 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
if (Window->Self != pDCE->hwndCurrent)
{
// IntEngWindowChanged(CurrentWindow, WOC_RGN_CLIENT);
IntReleaseWindowObject(CurrentWindow);
}
}
@ -866,13 +872,6 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
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)); \
@ -893,15 +892,18 @@ NtUserEnumDisplaySettings(
{
NTSTATUS Status;
LPDEVMODEW pSafeDevMode;
DWORD Size = 0, ExtraSize = 0;
PUNICODE_STRING pSafeDeviceName = NULL;
UNICODE_STRING SafeDeviceName;
USHORT Size = 0, ExtraSize = 0;
Status = MmCopyFromCaller(&Size, &lpDevMode->dmSize, sizeof (lpDevMode->dmSize));
/* Copy the devmode */
Status = MmCopyFromCaller(&Size, &lpDevMode->dmSize, sizeof (Size));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
Status = MmCopyFromCaller(&ExtraSize, &lpDevMode->dmDriverExtra, sizeof (lpDevMode->dmDriverExtra));
Status = MmCopyFromCaller(&ExtraSize, &lpDevMode->dmDriverExtra, sizeof (ExtraSize));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
@ -911,17 +913,36 @@ NtUserEnumDisplaySettings(
if (pSafeDevMode == NULL)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return DISP_CHANGE_FAILED;
return FALSE;
}
pSafeDevMode->dmSize = Size;
pSafeDevMode->dmDriverExtra = ExtraSize;
if (!IntEnumDisplaySettings(lpszDeviceName, iModeNum, pSafeDevMode, dwFlags))
/* Copy the device name */
if (lpszDeviceName != NULL)
{
Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
if (!NT_SUCCESS(Status))
{
ExFreePool(pSafeDevMode);
SetLastNtError(Status);
return FALSE;
}
pSafeDeviceName = &SafeDeviceName;
}
/* Call internal function */
if (!IntEnumDisplaySettings(pSafeDeviceName, iModeNum, pSafeDevMode, dwFlags))
{
if (pSafeDeviceName != NULL)
RtlFreeUnicodeString(pSafeDeviceName);
ExFreePool(pSafeDevMode);
return FALSE;
}
if (pSafeDeviceName != NULL)
RtlFreeUnicodeString(pSafeDeviceName);
/* Copy some information back */
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsWidth);
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsHeight);
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmBitsPerPel);
@ -940,9 +961,84 @@ NtUserEnumDisplaySettings(
}
}
ExFreePool(pSafeDevMode);
return TRUE;
}
#undef COPY_DEVMODE_VALUE_TO_CALLER
LONG
STDCALL
NtUserChangeDisplaySettings(
PUNICODE_STRING lpszDeviceName,
LPDEVMODEW lpDevMode,
HWND hwnd,
DWORD dwflags,
LPVOID lParam)
{
NTSTATUS Status;
DEVMODEW DevMode;
PUNICODE_STRING pSafeDeviceName = NULL;
UNICODE_STRING SafeDeviceName;
LONG Ret;
/* Check arguments */
#ifdef CDS_VIDEOPARAMETERS
if (dwflags != CDS_VIDEOPARAMETERS && lParam != NULL)
#else
if (lParam != NULL)
#endif
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return DISP_CHANGE_BADPARAM;
}
if (hwnd != NULL)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return DISP_CHANGE_BADPARAM;
}
/* Copy devmode */
Status = MmCopyFromCaller(&DevMode.dmSize, &lpDevMode->dmSize, sizeof (DevMode.dmSize));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return DISP_CHANGE_BADPARAM;
}
DevMode.dmSize = min(sizeof (DevMode), DevMode.dmSize);
Status = MmCopyFromCaller(&DevMode, lpDevMode, DevMode.dmSize);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return DISP_CHANGE_BADPARAM;
}
if (DevMode.dmDriverExtra > 0)
{
DbgPrint("(%s:%i) WIN32K: %s lpDevMode->dmDriverExtra is IGNORED!\n", __FILE__, __LINE__, __FUNCTION__);
DevMode.dmDriverExtra = 0;
}
/* Copy the device name */
if (lpszDeviceName != NULL)
{
Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return DISP_CHANGE_BADPARAM;
}
pSafeDeviceName = &SafeDeviceName;
}
/* Call internal function */
Ret = IntChangeDisplaySettings(pSafeDeviceName, &DevMode, dwflags, lParam);
if (pSafeDeviceName != NULL)
RtlFreeUnicodeString(pSafeDeviceName);
return Ret;
}
/* EOF */

View file

@ -1618,6 +1618,8 @@ IntCreateWindowEx(DWORD dwExStyle,
ExInitializeFastMutex(&WindowObject->PropListLock);
ExInitializeFastMutex(&WindowObject->RelativesLock);
ExInitializeFastMutex(&WindowObject->UpdateLock);
InitializeListHead(&WindowObject->WndObjListHead);
ExInitializeFastMutex(&WindowObject->WndObjListLock);
if (NULL != WindowName->Buffer)
{
@ -1975,6 +1977,9 @@ IntCreateWindowEx(DWORD dwExStyle,
WindowObject->ClientRect.top);
}
IntSendMessage(WindowObject->Self, WM_MOVE, 0, lParam);
/* Call WNDOBJ change procs */
IntEngWindowChanged(WindowObject, WOC_RGN_CLIENT);
}
/* Show or maybe minimize or maximize the window. */
@ -2180,6 +2185,7 @@ NtUserDestroyWindow(HWND Wnd)
}
#endif
IntEngWindowChanged(Window, WOC_DELETE);
isChild = (0 != (Window->Style & WS_CHILD));
#if 0 /* FIXME */

View file

@ -1341,6 +1341,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
IntSendMessage(Wnd, WM_MOVE, 0,
MAKELONG(Window->ClientRect.left,
Window->ClientRect.top));
IntEngWindowChanged(Window, WOC_RGN_CLIENT);
}
/* Activate the window if activation is not requested and the window is not minimized */

View file

@ -2296,26 +2296,28 @@ IntSetDCColor(HDC hDC, ULONG Object, COLORREF Color)
/*! \brief Enumerate possible display settings for the given display...
*
* \todo Make thread safe!?
* \todo Don't ignore lpszDeviceName
* \todo Don't ignore pDeviceName
* \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)
IN PUNICODE_STRING pDeviceName OPTIONAL,
IN DWORD iModeNum,
IN OUT LPDEVMODEW pDevMode,
IN DWORD dwFlags)
{
static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
static DWORD SizeOfCachedDevModes = 0;
LPDEVMODEW CachedMode = NULL;
PDEVMODEW 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)
DPRINT1("DevMode->dmSize = %d\n", pDevMode->dmSize);
DPRINT1("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra);
if (pDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
pDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
pDevMode->dmSize != SIZEOF_DEVMODEW_500)
{
SetLastWin32Error(STATUS_INVALID_PARAMETER);
return FALSE;
@ -2324,7 +2326,7 @@ IntEnumDisplaySettings(
if (iModeNum == ENUM_CURRENT_SETTINGS)
{
CachedMode = &PrimarySurface.DMW;
assert(CachedMode->dmSize > 0);
ASSERT(CachedMode->dmSize > 0);
}
else if (iModeNum == ENUM_REGISTRY_SETTINGS)
{
@ -2488,24 +2490,90 @@ IntEnumDisplaySettings(
}
}
assert(CachedMode != NULL);
ASSERT(CachedMode != NULL);
Size = OldSize = lpDevMode->dmSize;
Size = OldSize = pDevMode->dmSize;
if (Size > CachedMode->dmSize)
Size = CachedMode->dmSize;
RtlCopyMemory(lpDevMode, CachedMode, Size);
RtlZeroMemory((PCHAR)lpDevMode + Size, OldSize - Size);
lpDevMode->dmSize = OldSize;
RtlCopyMemory(pDevMode, CachedMode, Size);
RtlZeroMemory((PCHAR)pDevMode + Size, OldSize - Size);
pDevMode->dmSize = OldSize;
Size = OldSize = lpDevMode->dmDriverExtra;
Size = OldSize = pDevMode->dmDriverExtra;
if (Size > CachedMode->dmDriverExtra)
Size = CachedMode->dmDriverExtra;
RtlCopyMemory((PCHAR)lpDevMode + lpDevMode->dmSize,
RtlCopyMemory((PCHAR)pDevMode + pDevMode->dmSize,
(PCHAR)CachedMode + CachedMode->dmSize, Size);
RtlZeroMemory((PCHAR)lpDevMode + lpDevMode->dmSize + Size, OldSize - Size);
lpDevMode->dmDriverExtra = OldSize;
RtlZeroMemory((PCHAR)pDevMode + pDevMode->dmSize + Size, OldSize - Size);
pDevMode->dmDriverExtra = OldSize;
return TRUE;
}
LONG
FASTCALL
IntChangeDisplaySettings(
IN PUNICODE_STRING pDeviceName OPTIONAL,
IN LPDEVMODEW DevMode,
IN DWORD dwflags,
IN PVOID lParam OPTIONAL)
{
BOOLEAN Global = FALSE;
BOOLEAN NoReset = FALSE;
BOOLEAN Reset = FALSE;
BOOLEAN SetPrimary = FALSE;
LONG Ret;
if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
{
/* Check global, reset and noreset flags */
if ((dwflags & CDS_GLOBAL) == CDS_GLOBAL)
Global = TRUE;
if ((dwflags & CDS_NORESET) == CDS_NORESET)
NoReset = TRUE;
dwflags &= ~(CDS_GLOBAL | CDS_NORESET);
}
if ((dwflags & CDS_RESET) == CDS_RESET)
Reset = TRUE;
if ((dwflags & CDS_SET_PRIMARY) == CDS_SET_PRIMARY)
SetPrimary = TRUE;
dwflags &= ~(CDS_RESET | CDS_SET_PRIMARY);
if (Reset && NoReset)
return DISP_CHANGE_BADFLAGS;
switch (dwflags)
{
case 0: /* Dynamically change graphics mode */
Ret = DISP_CHANGE_FAILED;
break;
case CDS_FULLSCREEN: /* Given mode is temporary */
Ret = DISP_CHANGE_FAILED;
break;
case CDS_UPDATEREGISTRY:
Ret = DISP_CHANGE_FAILED;
break;
case CDS_TEST: /* Test if the mode could be set */
Ret = DISP_CHANGE_FAILED;
break;
#ifdef CDS_VIDEOPARAMETERS
case CDS_VIDEOPARAMETERS:
if (lParam == NULL)
return DISP_CHANGE_BADPARAM;
Ret = DISP_CHANGE_FAILED;
break;
#endif
default:
Ret = DISP_CHANGE_BADFLAGS;
break;
}
return Ret;
}
/* EOF */