mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 18:54:25 +00:00
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:
parent
d24e173122
commit
d001f75197
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,4 +15,9 @@ IntEngMaskBlt(SURFOBJ *DestObj,
|
|||
BRUSHOBJ *Brush,
|
||||
POINTL *BrushOrigin);
|
||||
|
||||
VOID FASTCALL
|
||||
IntEngWindowChanged(
|
||||
PWINDOW_OBJECT Window,
|
||||
FLONG flChanged);
|
||||
|
||||
#endif /* _WIN32K_ENG_H */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue