Modified: trunk/reactos/subsys/win32k/eng/objects.h
Modified: trunk/reactos/subsys/win32k/eng/window.c
Modified: trunk/reactos/subsys/win32k/include/eng.h
Modified: trunk/reactos/subsys/win32k/include/intgdi.h
Modified: trunk/reactos/subsys/win32k/include/window.h
Modified: trunk/reactos/subsys/win32k/ntuser/stubs.c
Modified: trunk/reactos/subsys/win32k/ntuser/windc.c
Modified: trunk/reactos/subsys/win32k/ntuser/window.c
Modified: trunk/reactos/subsys/win32k/ntuser/winpos.c
Modified: trunk/reactos/subsys/win32k/objects/dc.c
--- trunk/reactos/subsys/win32k/eng/objects.h 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/eng/objects.h 2005-03-15 22:26:12 UTC (rev 14111)
@@ -130,6 +130,8 @@
typedef struct _WNDGDI {
WNDOBJ WndObj;
+ LIST_ENTRY ListEntry;
+ HWND Hwnd;
CLIPOBJ *ClientClipObj;
WNDOBJCHANGEPROC ChangeProc;
FLONG Flags;
--- trunk/reactos/subsys/win32k/eng/window.c 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/eng/window.c 2005-03-15 22:26:12 UTC (rev 14111)
@@ -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);
@@ -63,22 +66,144 @@
}
/*
+ * 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,28 +224,31 @@
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 @@
*/
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 @@
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 @@
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 @@
VOID
STDCALL
WNDOBJ_vSetConsumer(
- IN WNDOBJ *pwo,
- IN PVOID pvConsumer
- )
+ IN WNDOBJ *pwo,
+ IN PVOID pvConsumer)
{
BOOL Hack;
@@ -211,12 +355,19 @@
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);
}
}
--- trunk/reactos/subsys/win32k/include/eng.h 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/include/eng.h 2005-03-15 22:26:12 UTC (rev 14111)
@@ -15,4 +15,9 @@
BRUSHOBJ *Brush,
POINTL *BrushOrigin);
+VOID FASTCALL
+IntEngWindowChanged(
+ PWINDOW_OBJECT Window,
+ FLONG flChanged);
+
#endif /* _WIN32K_ENG_H */
--- trunk/reactos/subsys/win32k/include/intgdi.h 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/include/intgdi.h 2005-03-15 22:26:12 UTC (rev 14111)
@@ -193,5 +193,21 @@
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 */
--- trunk/reactos/subsys/win32k/include/window.h 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/include/window.h 2005-03-15 22:26:12 UTC (rev 14111)
@@ -99,6 +99,9 @@
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. */
--- trunk/reactos/subsys/win32k/ntuser/stubs.c 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/ntuser/stubs.c 2005-03-15 22:26:12 UTC (rev 14111)
@@ -110,20 +110,6 @@
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(
--- trunk/reactos/subsys/win32k/ntuser/windc.c 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/ntuser/windc.c 2005-03-15 22:26:12 UTC (rev 14111)
@@ -354,6 +354,11 @@
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 @@
if (Window->Self != pDCE->hwndCurrent)
{
+// IntEngWindowChanged(CurrentWindow, WOC_RGN_CLIENT);
IntReleaseWindowObject(CurrentWindow);
}
}
@@ -866,13 +872,6 @@
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 @@
{
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 @@
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 @@
}
}
+ 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 */
--- trunk/reactos/subsys/win32k/ntuser/window.c 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/ntuser/window.c 2005-03-15 22:26:12 UTC (rev 14111)
@@ -1618,6 +1618,8 @@
ExInitializeFastMutex(&WindowObject->PropListLock);
ExInitializeFastMutex(&WindowObject->RelativesLock);
ExInitializeFastMutex(&WindowObject->UpdateLock);
+ InitializeListHead(&WindowObject->WndObjListHead);
+ ExInitializeFastMutex(&WindowObject->WndObjListLock);
if (NULL != WindowName->Buffer)
{
@@ -1975,6 +1977,9 @@
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 @@
}
#endif
+ IntEngWindowChanged(Window, WOC_DELETE);
isChild = (0 != (Window->Style & WS_CHILD));
#if 0 /* FIXME */
--- trunk/reactos/subsys/win32k/ntuser/winpos.c 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/ntuser/winpos.c 2005-03-15 22:26:12 UTC (rev 14111)
@@ -1341,6 +1341,7 @@
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 */
--- trunk/reactos/subsys/win32k/objects/dc.c 2005-03-15 22:14:22 UTC (rev 14110)
+++ trunk/reactos/subsys/win32k/objects/dc.c 2005-03-15 22:26:12 UTC (rev 14111)
@@ -2296,26 +2296,28 @@
/*! \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 @@
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 @@
}
}
- 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 */