Author: rharabien
Date: Wed Oct 19 15:40:17 2011
New Revision: 54197
URL:
http://svn.reactos.org/svn/reactos?rev=54197&view=rev
Log:
[WIN32K]
- Simplify monitors code
- fix few minor bugs (ie. not updating last error)
- Make monitor object more compatible to windows
Modified:
trunk/reactos/subsystems/win32/win32k/include/monitor.h
trunk/reactos/subsystems/win32/win32k/ntuser/monitor.c
Modified: trunk/reactos/subsystems/win32/win32k/include/monitor.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/monitor.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/monitor.h [iso-8859-1] Wed Oct 19
15:40:17 2011
@@ -4,30 +4,28 @@
typedef struct _MONITOR
{
HEAD head;
-//
- UNICODE_STRING DeviceName; /* name of the monitor */
- PDEVOBJ *GdiDevice; /* pointer to the GDI device to
- which this monitor is attached */
-// This is the structure Windows uses:
-// struct _MONITOR* pMonitorNext;
- union {
- DWORD dwMONFlags;
- struct {
- DWORD IsVisible:1;
- DWORD IsPalette:1;
- DWORD IsPrimary:1; /* wether this is the primary monitor */
- };};
+ struct _MONITOR* pMonitorNext;
+ union
+ {
+ DWORD dwMONFlags;
+ struct
+ {
+ DWORD IsVisible: 1;
+ DWORD IsPalette: 1;
+ DWORD IsPrimary: 1; /* wether this is the primary monitor */
+ };
+ };
RECT rcMonitor;
RECT rcWork;
HRGN hrgnMonitor;
SHORT cFullScreen;
SHORT cWndStack;
HDEV hDev;
- HDEV hDevReal;
-// BYTE DockTargets[4][7];
-// Use LIST_ENTRY
- struct _MONITOR* Next; //Flink;
- struct _MONITOR* Prev; //Blink;
+
+ // ReactOS specific fields:
+ UNICODE_STRING DeviceName; /* name of the monitor */
+ PDEVOBJ *GdiDevice; /* pointer to the GDI device to
+ which this monitor is attached */
} MONITOR, *PMONITOR;
NTSTATUS IntAttachMonitor(PDEVOBJ *pGdiDevice, ULONG DisplayNumber);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/monitor.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/monitor.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/monitor.c [iso-8859-1] Wed Oct 19
15:40:17 2011
@@ -1,9 +1,10 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * PURPOSE: Monitor support
+ * PURPOSE: pMonitor support
* FILE: subsys/win32k/ntuser/monitor.c
- * PROGRAMER: Anich Gregor (blight(a)blight.eu.org)
+ * PROGRAMERS: Anich Gregor (blight(a)blight.eu.org)
+ * Rafal Harabien (rafalh(a)reactos.org)
*/
#include <win32k.h>
@@ -20,7 +21,7 @@
/* GLOBALS *******************************************************************/
-/* list of monitors */
+/* List of monitors */
static PMONITOR gMonitorList = NULL;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -37,16 +38,7 @@
PMONITOR
IntCreateMonitorObject()
{
- HANDLE Handle;
- PMONITOR Monitor;
-
- Monitor = UserCreateObject(gHandleTable, NULL, &Handle, otMonitor, sizeof
(MONITOR));
- if (Monitor == NULL)
- {
- return NULL;
- }
-
- return Monitor;
+ return UserCreateObject(gHandleTable, NULL, NULL, otMonitor, sizeof(MONITOR));
}
/* IntDestroyMonitorObject
@@ -63,15 +55,34 @@
void
IntDestroyMonitorObject(IN PMONITOR pMonitor)
{
+ /* Free monitor name */
RtlFreeUnicodeString(&pMonitor->DeviceName);
+
+ /* Remove monitor region */
+ if (pMonitor->hrgnMonitor)
+ {
+ GreSetObjectOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(pMonitor->hrgnMonitor);
+ }
+
+ /* Destroy monitor object */
UserDereferenceObject(pMonitor);
-}
-
-
+ UserDeleteObject(UserHMGetHandle(pMonitor), otMonitor);
+}
+
+/* UserGetMonitorObject
+ *
+ * Returns monitor object from handle or sets last error if handle is invalid
+ *
+ * Arguments
+ *
+ * hMonitor
+ * Handle of MONITOR object
+ */
PMONITOR FASTCALL
UserGetMonitorObject(IN HMONITOR hMonitor)
{
- PMONITOR Monitor;
+ PMONITOR pMonitor;
if (!hMonitor)
{
@@ -79,16 +90,38 @@
return NULL;
}
- Monitor = (PMONITOR)UserGetObject(gHandleTable, hMonitor, otMonitor);
- if (!Monitor)
+ pMonitor = (PMONITOR)UserGetObject(gHandleTable, hMonitor, otMonitor);
+ if (!pMonitor)
{
EngSetLastError(ERROR_INVALID_MONITOR_HANDLE);
return NULL;
}
- return Monitor;
-}
-
+ return pMonitor;
+}
+
+/* IntGetPrimaryMonitor
+ *
+ * Returns a PMONITOR for the primary monitor
+ *
+ * Return value
+ * PMONITOR
+ */
+PMONITOR
+FASTCALL
+IntGetPrimaryMonitor()
+{
+ PMONITOR pMonitor;
+
+ /* Find primary monitor */
+ for (pMonitor = gMonitorList; pMonitor != NULL; pMonitor =
pMonitor->pMonitorNext)
+ {
+ if (pMonitor->IsPrimary)
+ break;
+ }
+
+ return pMonitor;
+}
/* IntAttachMonitor
*
@@ -106,46 +139,45 @@
IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
IN ULONG DisplayNumber)
{
- PMONITOR Monitor;
+ PMONITOR pMonitor;
WCHAR Buffer[CCHDEVICENAME];
TRACE("Attaching monitor...\n");
/* create new monitor object */
- Monitor = IntCreateMonitorObject();
- if (Monitor == NULL)
+ pMonitor = IntCreateMonitorObject();
+ if (pMonitor == NULL)
{
TRACE("Couldnt create monitor object\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
_snwprintf(Buffer, CCHDEVICENAME, L"\\\\.\\DISPLAY%d", DisplayNumber + 1);
- if (!RtlCreateUnicodeString(&Monitor->DeviceName, Buffer))
+ if (!RtlCreateUnicodeString(&pMonitor->DeviceName, Buffer))
{
TRACE("Couldn't duplicate monitor name!\n");
- UserDereferenceObject(Monitor);
- UserDeleteObject(UserHMGetHandle(Monitor), otMonitor);
+ UserDereferenceObject(pMonitor);
+ UserDeleteObject(UserHMGetHandle(pMonitor), otMonitor);
return STATUS_INSUFFICIENT_RESOURCES;
}
- Monitor->GdiDevice = pGdiDevice;
- Monitor->cWndStack = 0;
+ pMonitor->GdiDevice = pGdiDevice;
+ pMonitor->cWndStack = 0;
if (gMonitorList == NULL)
{
TRACE("Primary monitor is beeing attached\n");
- Monitor->IsPrimary = TRUE;
- gMonitorList = Monitor;
+ pMonitor->IsPrimary = TRUE;
+ gMonitorList = pMonitor;
}
else
{
- PMONITOR p;
+ PMONITOR pmonLast = gMonitorList;
TRACE("Additional monitor is beeing attached\n");
- for (p = gMonitorList; p->Next != NULL; p = p->Next)
- {
- p->Next = Monitor;
- }
- Monitor->Prev = p;
+ while (pmonLast->pMonitorNext != NULL)
+ pmonLast = pmonLast->pMonitorNext;
+
+ pmonLast->pMonitorNext = pMonitor;
}
IntUpdateMonitorSize(pGdiDevice);
@@ -167,44 +199,33 @@
NTSTATUS
IntDetachMonitor(IN PDEVOBJ *pGdiDevice)
{
- PMONITOR Monitor;
-
- for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
- {
- if (Monitor->GdiDevice == pGdiDevice)
+ PMONITOR pMonitor = gMonitorList, *pLink = &gMonitorList;
+
+ /* Find monitor attached to given device */
+ while (pMonitor != NULL)
+ {
+ if (pMonitor->GdiDevice == pGdiDevice)
break;
- }
-
- if (Monitor == NULL)
- {
- /* no monitor for given device found */
+
+ pLink = &pMonitor->pMonitorNext;
+ pMonitor = pMonitor->pMonitorNext;
+ }
+
+ if (pMonitor == NULL)
+ {
+ /* No monitor has been found */
return STATUS_INVALID_PARAMETER;
}
- if (Monitor->IsPrimary && (Monitor->Next != NULL || Monitor->Prev !=
NULL))
- {
- PMONITOR NewPrimaryMonitor = (Monitor->Prev != NULL) ? (Monitor->Prev) :
(Monitor->Next);
-
- NewPrimaryMonitor->IsPrimary = TRUE;
- }
-
- if (gMonitorList == Monitor)
- {
- gMonitorList = Monitor->Next;
- if (Monitor->Next != NULL)
- Monitor->Next->Prev = NULL;
- }
- else
- {
- Monitor->Prev->Next = Monitor->Next;
- if (Monitor->Next != NULL)
- Monitor->Next->Prev = Monitor->Prev;
- }
-
- if (Monitor->hrgnMonitor)
- GreDeleteObject(Monitor->hrgnMonitor);
-
- IntDestroyMonitorObject(Monitor);
+ /* We destroy primary monitor - set next as primary */
+ if (pMonitor->IsPrimary && pMonitor->pMonitorNext != NULL)
+ pMonitor->pMonitorNext->IsPrimary = TRUE;
+
+ /* Update Next ptr in previous monitor */
+ *pLink = pMonitor->pMonitorNext;
+
+ /* Finally destroy monitor */
+ IntDestroyMonitorObject(pMonitor);
return STATUS_SUCCESS;
}
@@ -224,60 +245,41 @@
NTSTATUS
IntUpdateMonitorSize(IN PDEVOBJ *pGdiDevice)
{
- PMONITOR Monitor;
-
- for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
- {
- if (Monitor->GdiDevice == pGdiDevice)
+ PMONITOR pMonitor;
+
+ /* Find monitor attached to given device */
+ for (pMonitor = gMonitorList; pMonitor != NULL; pMonitor =
pMonitor->pMonitorNext)
+ {
+ if (pMonitor->GdiDevice == pGdiDevice)
break;
}
- if (Monitor == NULL)
- {
- /* no monitor for given device found */
+ if (pMonitor == NULL)
+ {
+ /* No monitor has been found */
return STATUS_INVALID_PARAMETER;
}
- Monitor->rcMonitor.left = 0;
- Monitor->rcMonitor.top = 0;
- Monitor->rcMonitor.right = Monitor->rcMonitor.left +
Monitor->GdiDevice->gdiinfo.ulHorzRes;
- Monitor->rcMonitor.bottom = Monitor->rcMonitor.top +
Monitor->GdiDevice->gdiinfo.ulVertRes;
- Monitor->rcWork = Monitor->rcMonitor;
-
- if (Monitor->hrgnMonitor)
- {
- GreSetObjectOwner(Monitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(Monitor->hrgnMonitor);
- }
-
- Monitor->hrgnMonitor = IntSysCreateRectRgnIndirect( &Monitor->rcMonitor );
-
- IntGdiSetRegionOwner(Monitor->hrgnMonitor, GDI_OBJ_HMGR_PUBLIC);
+ /* Update monitor size */
+ pMonitor->rcMonitor.left = 0;
+ pMonitor->rcMonitor.top = 0;
+ pMonitor->rcMonitor.right = pMonitor->rcMonitor.left +
pMonitor->GdiDevice->gdiinfo.ulHorzRes;
+ pMonitor->rcMonitor.bottom = pMonitor->rcMonitor.top +
pMonitor->GdiDevice->gdiinfo.ulVertRes;
+ pMonitor->rcWork = pMonitor->rcMonitor;
+
+ /* Destroy monitor region... */
+ if (pMonitor->hrgnMonitor)
+ {
+ GreSetObjectOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(pMonitor->hrgnMonitor);
+ }
+
+ /* ...and create new one */
+ pMonitor->hrgnMonitor = IntSysCreateRectRgnIndirect(&pMonitor->rcMonitor);
+ if (pMonitor->hrgnMonitor)
+ IntGdiSetRegionOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_PUBLIC);
return STATUS_SUCCESS;
-}
-
-/* IntGetPrimaryMonitor
- *
- * Returns a PMONITOR for the primary monitor
- *
- * Return value
- * PMONITOR
- */
-PMONITOR
-FASTCALL
-IntGetPrimaryMonitor()
-{
- PMONITOR Monitor;
-
- for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
- {
- /* FIXME: I guess locking the monitor is not neccessary to read 1 int */
- if (Monitor->IsPrimary)
- break;
- }
-
- return Monitor;
}
/* IntGetMonitorsFromRect
@@ -291,21 +293,21 @@
* Rectangle in desktop coordinates. If this is NULL all monitors are
* returned and the rect list is filled with the sizes of the monitors.
*
- * hMonitorList
+ * phMonitorList
* Pointer to an array of HMONITOR which is filled with monitor handles.
* Can be NULL
*
- * monitorRectList
+ * prcMonitorList
* Pointer to an array of RECT which is filled with intersection rects in
* desktop coordinates.
* Can be NULL, will be ignored if no intersecting monitor is found and
* flags is MONITOR_DEFAULTTONEAREST
*
- * listSize
- * Size of the hMonitorList and monitorRectList arguments. If this is zero
- * hMonitorList and monitorRectList are ignored.
- *
- * flags
+ * dwListSize
+ * Size of the phMonitorList and prcMonitorList arguments. If this is zero
+ * phMonitorList and prcMonitorList are ignored.
+ *
+ * dwFlags
* Either 0 or MONITOR_DEFAULTTONEAREST (ignored if rect is NULL)
*
* Returns
@@ -314,29 +316,28 @@
static
UINT
IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
- OPTIONAL OUT HMONITOR *hMonitorList,
- OPTIONAL OUT PRECTL monitorRectList,
- OPTIONAL IN DWORD listSize,
- OPTIONAL IN DWORD flags)
-{
- PMONITOR Monitor, NearestMonitor = NULL, PrimaryMonitor = NULL;
- UINT iCount = 0;
+ OPTIONAL OUT HMONITOR *phMonitorList,
+ OPTIONAL OUT PRECTL prcMonitorList,
+ OPTIONAL IN DWORD dwListSize,
+ OPTIONAL IN DWORD dwFlags)
+{
+ PMONITOR pMonitor, pNearestMonitor = NULL, pPrimaryMonitor = NULL;
+ UINT cMonitors = 0;
ULONG iNearestDistance = 0xffffffff;
- /* Find monitors which intersect the rectangle */
- for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
+ /* Find monitors which intersects the rectangle */
+ for (pMonitor = gMonitorList; pMonitor != NULL; pMonitor =
pMonitor->pMonitorNext)
{
RECTL MonitorRect, IntersectionRect;
- MonitorRect = Monitor->rcMonitor;
+ MonitorRect = pMonitor->rcMonitor;
TRACE("MonitorRect: left = %d, top = %d, right = %d, bottom = %d\n",
MonitorRect.left, MonitorRect.top, MonitorRect.right,
MonitorRect.bottom);
- if (flags == MONITOR_DEFAULTTOPRIMARY && Monitor->IsPrimary)
- {
- PrimaryMonitor = Monitor;
- }
+ /* Save primary monitor for later usage */
+ if (dwFlags == MONITOR_DEFAULTTOPRIMARY && pMonitor->IsPrimary)
+ pPrimaryMonitor = pMonitor;
/* Check if a rect is given */
if (pRect == NULL)
@@ -344,12 +345,11 @@
/* No rect given, so use the full monitor rect */
IntersectionRect = MonitorRect;
}
-
/* We have a rect, calculate intersection */
else if (!RECTL_bIntersectRect(&IntersectionRect, &MonitorRect, pRect))
{
/* Rects did not intersect */
- if (flags == MONITOR_DEFAULTTONEAREST)
+ if (dwFlags == MONITOR_DEFAULTTONEAREST)
{
ULONG cx, cy, iDistance;
@@ -366,7 +366,7 @@
if (iDistance < iNearestDistance)
{
iNearestDistance = iDistance;
- NearestMonitor = Monitor;
+ pNearestMonitor = pMonitor;
}
}
@@ -374,38 +374,39 @@
}
/* Check if there's space in the buffer */
- if (iCount < listSize)
- {
- if (hMonitorList != NULL)
- hMonitorList[iCount] = UserHMGetHandle(Monitor);
- if (monitorRectList != NULL)
- monitorRectList[iCount] = IntersectionRect;
+ if (cMonitors < dwListSize)
+ {
+ /* Save monitor data */
+ if (phMonitorList != NULL)
+ phMonitorList[cMonitors] = UserHMGetHandle(pMonitor);
+ if (prcMonitorList != NULL)
+ prcMonitorList[cMonitors] = IntersectionRect;
}
/* Increase count of found monitors */
- iCount++;
- }
-
- /* Found nothing intersecting? */
- if (iCount == 0)
+ cMonitors++;
+ }
+
+ /* Nothing has been found? */
+ if (cMonitors == 0)
{
/* Check if we shall default to the nearest monitor */
- if (flags == MONITOR_DEFAULTTONEAREST && NearestMonitor)
- {
- if (hMonitorList && listSize > 0)
- hMonitorList[iCount] = UserHMGetHandle(NearestMonitor);
- iCount++;
+ if (dwFlags == MONITOR_DEFAULTTONEAREST && pNearestMonitor)
+ {
+ if (phMonitorList && dwListSize > 0)
+ phMonitorList[cMonitors] = UserHMGetHandle(pNearestMonitor);
+ cMonitors++;
}
/* Check if we shall default to the primary monitor */
- else if (flags == MONITOR_DEFAULTTOPRIMARY && PrimaryMonitor)
- {
- if (hMonitorList != NULL && listSize > 0)
- hMonitorList[iCount] = UserHMGetHandle(PrimaryMonitor);
- iCount++;
- }
- }
-
- return iCount;
+ else if (dwFlags == MONITOR_DEFAULTTOPRIMARY && pPrimaryMonitor)
+ {
+ if (phMonitorList != NULL && dwListSize > 0)
+ phMonitorList[cMonitors] = UserHMGetHandle(pPrimaryMonitor);
+ cMonitors++;
+ }
+ }
+
+ return cMonitors;
}
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -416,24 +417,24 @@
*
* Arguments
*
- * hDC
+ * hdc
* Handle to a DC for which to enum intersecting monitors. If this is NULL
* it returns all monitors which are part of the current virtual screen.
*
- * pRect
+ * pUnsafeRect
* Clipping rectangle with coordinate system origin at the DCs origin if the
* given HDC is not NULL or in virtual screen coordinated if it is NULL.
* Can be NULL
*
- * hMonitorList
+ * phUnsafeMonitorList
* Pointer to an array of HMONITOR which is filled with monitor handles.
* Can be NULL
*
- * monitorRectList
+ * prcUnsafeMonitorList
* Pointer to an array of RECT which is filled with intersection rectangles.
* Can be NULL
*
- * listSize
+ * dwListSize
* Size of the hMonitorList and monitorRectList arguments. If this is zero
* hMonitorList and monitorRectList are ignored.
*
@@ -443,154 +444,158 @@
INT
APIENTRY
NtUserEnumDisplayMonitors(
- OPTIONAL IN HDC hDC,
- OPTIONAL IN LPCRECTL pRect,
- OPTIONAL OUT HMONITOR *hMonitorList,
- OPTIONAL OUT PRECTL monitorRectList,
- OPTIONAL IN DWORD listSize)
-{
- INT numMonitors, i;
- HMONITOR *safeHMonitorList = NULL;
- PRECTL safeRectList = NULL;
- RECTL rect, *myRect;
- RECTL dcRect;
- NTSTATUS status;
-
- /* get rect */
- if (pRect != NULL)
- {
- status = MmCopyFromCaller(&rect, pRect, sizeof (RECT));
- if (!NT_SUCCESS(status))
+ OPTIONAL IN HDC hdc,
+ OPTIONAL IN LPCRECTL pUnsafeRect,
+ OPTIONAL OUT HMONITOR *phUnsafeMonitorList,
+ OPTIONAL OUT PRECTL prcUnsafeMonitorList,
+ OPTIONAL IN DWORD dwListSize)
+{
+ INT cMonitors, iRet = -1, i;
+ HMONITOR *phMonitorList = NULL;
+ PRECTL prcMonitorList = NULL;
+ RECTL rc, *pRect;
+ RECTL DcRect = {0};
+ NTSTATUS Status;
+
+ /* Get rectangle */
+ if (pUnsafeRect != NULL)
+ {
+ Status = MmCopyFromCaller(&rc, pUnsafeRect, sizeof(RECT));
+ if (!NT_SUCCESS(Status))
{
TRACE("MmCopyFromCaller() failed!\n");
- SetLastNtError(status);
+ SetLastNtError(Status);
return -1;
}
}
- if (hDC != NULL)
- {
- PDC dc;
- INT regionType;
-
- /* get visible region bounding rect */
- dc = DC_LockDc(hDC);
- if (dc == NULL)
+ if (hdc != NULL)
+ {
+ PDC pDc;
+ INT iRgnType;
+
+ /* Get visible region bounding rect */
+ pDc = DC_LockDc(hdc);
+ if (pDc == NULL)
{
TRACE("DC_LockDc() failed!\n");
/* FIXME: setlasterror? */
return -1;
}
- regionType = REGION_GetRgnBox(dc->prgnVis, &dcRect);
- DC_UnlockDc(dc);
-
- if (regionType == 0)
+ iRgnType = REGION_GetRgnBox(pDc->prgnVis, &DcRect);
+ DC_UnlockDc(pDc);
+
+ if (iRgnType == 0)
{
TRACE("NtGdiGetRgnBox() failed!\n");
return -1;
}
- if (regionType == NULLREGION)
+ if (iRgnType == NULLREGION)
return 0;
- if (regionType == COMPLEXREGION)
+ if (iRgnType == COMPLEXREGION)
{
/* TODO: warning */
}
- /* if hDC and pRect are given the area of interest is pRect with
+ /* if hdc and pRect are given the area of interest is pRect with
coordinate origin at the DC position */
- if (pRect != NULL)
- {
- rect.left += dcRect.left;
- rect.right += dcRect.left;
- rect.top += dcRect.top;
- rect.bottom += dcRect.top;
- }
- /* if hDC is given and pRect is not the area of interest is the
- bounding rect of hDC */
+ if (pUnsafeRect != NULL)
+ {
+ rc.left += DcRect.left;
+ rc.right += DcRect.left;
+ rc.top += DcRect.top;
+ rc.bottom += DcRect.top;
+ }
+ /* if hdc is given and pRect is not the area of interest is the
+ bounding rect of hdc */
else
{
- rect = dcRect;
- }
- }
-
- if (hDC == NULL && pRect == NULL)
- myRect = NULL;
+ rc = DcRect;
+ }
+ }
+
+ if (hdc == NULL && pUnsafeRect == NULL)
+ pRect = NULL;
else
- myRect = ▭
+ pRect = &rc;
UserEnterShared();
- /* find intersecting monitors */
- numMonitors = IntGetMonitorsFromRect(myRect, NULL, NULL, 0, 0);
- if (numMonitors == 0 || listSize == 0 ||
- (hMonitorList == NULL && monitorRectList == NULL))
- {
- TRACE("numMonitors = %d\n", numMonitors);
+ /* Find intersecting monitors */
+ cMonitors = IntGetMonitorsFromRect(pRect, NULL, NULL, 0, MONITOR_DEFAULTTONULL);
+ if (cMonitors == 0 || dwListSize == 0 ||
+ (phUnsafeMonitorList == NULL && prcUnsafeMonitorList == NULL))
+ {
+ /* Simple case - just return monitors count */
+ TRACE("cMonitors = %d\n", cMonitors);
+ iRet = cMonitors;
goto cleanup;
}
- if (hMonitorList != NULL && listSize != 0)
- {
- safeHMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * listSize,
USERTAG_MONITORRECTS);
- if (safeHMonitorList == NULL)
+ /* Allocate safe buffers */
+ if (phUnsafeMonitorList != NULL && dwListSize != 0)
+ {
+ phMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * dwListSize,
USERTAG_MONITORRECTS);
+ if (phMonitorList == NULL)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- numMonitors = -1;
goto cleanup;
}
}
- if (monitorRectList != NULL && listSize != 0)
- {
- safeRectList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * listSize,
USERTAG_MONITORRECTS);
- if (safeRectList == NULL)
- {
- ExFreePoolWithTag(safeHMonitorList, USERTAG_MONITORRECTS);
+ if (prcUnsafeMonitorList != NULL && dwListSize != 0)
+ {
+ prcMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * dwListSize,
USERTAG_MONITORRECTS);
+ if (prcMonitorList == NULL)
+ {
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- numMonitors = -1;
goto cleanup;
}
}
- /* get intersecting monitors */
- numMonitors = IntGetMonitorsFromRect(myRect, safeHMonitorList, safeRectList,
- listSize, 0 );
-
- if (hDC != NULL && pRect != NULL && safeRectList != NULL)
- for (i = 0; i < numMonitors; i++)
- {
- safeRectList[i].left -= dcRect.left;
- safeRectList[i].right -= dcRect.left;
- safeRectList[i].top -= dcRect.top;
- safeRectList[i].bottom -= dcRect.top;
- }
-
- /* output result */
- if (hMonitorList != NULL && listSize != 0)
- {
- status = MmCopyToCaller(hMonitorList, safeHMonitorList, sizeof (HMONITOR) *
listSize);
- ExFreePoolWithTag(safeHMonitorList, USERTAG_MONITORRECTS);
- if (!NT_SUCCESS(status))
- {
- ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
- SetLastNtError(status);
- numMonitors = -1;
+ /* Get intersecting monitors */
+ cMonitors = IntGetMonitorsFromRect(pRect, phMonitorList, prcMonitorList,
+ dwListSize, MONITOR_DEFAULTTONULL);
+
+ if (hdc != NULL && pRect != NULL && prcMonitorList != NULL)
+ for (i = 0; i < cMonitors; i++)
+ {
+ prcMonitorList[i].left -= DcRect.left;
+ prcMonitorList[i].right -= DcRect.left;
+ prcMonitorList[i].top -= DcRect.top;
+ prcMonitorList[i].bottom -= DcRect.top;
+ }
+
+ /* Output result */
+ if (phUnsafeMonitorList != NULL && dwListSize != 0)
+ {
+ Status = MmCopyToCaller(phUnsafeMonitorList, phMonitorList, sizeof(HMONITOR) *
dwListSize);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
goto cleanup;
}
}
- if (monitorRectList != NULL && listSize != 0)
- {
- status = MmCopyToCaller(monitorRectList, safeRectList, sizeof (RECT) *
listSize);
- ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
- if (!NT_SUCCESS(status))
- {
- SetLastNtError(status);
- numMonitors = -1;
- }
- }
+ if (prcUnsafeMonitorList != NULL && dwListSize != 0)
+ {
+ Status = MmCopyToCaller(prcUnsafeMonitorList, prcMonitorList, sizeof(RECT) *
dwListSize);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ goto cleanup;
+ }
+ }
+
+ /* Return monitors count on success */
+ iRet = cMonitors;
cleanup:
+ if (phMonitorList)
+ ExFreePoolWithTag(phMonitorList, USERTAG_MONITORRECTS);
+ if (prcMonitorList)
+ ExFreePoolWithTag(prcMonitorList, USERTAG_MONITORRECTS);
+
UserLeave();
- return numMonitors;
+ return iRet;
}
/* NtUserGetMonitorInfo
@@ -602,7 +607,7 @@
* hMonitor
* Handle to a monitor for which to get information
*
- * pMonitorInfo
+ * pMonitorInfoUnsafe
* Pointer to a MONITORINFO struct which is filled with the information.
* The cbSize member must be set to sizeof(MONITORINFO) or
* sizeof(MONITORINFOEX). Even if set to sizeof(MONITORINFOEX) only parts
@@ -621,77 +626,80 @@
APIENTRY
NtUserGetMonitorInfo(
IN HMONITOR hMonitor,
- OUT LPMONITORINFO pMonitorInfo)
-{
- PMONITOR Monitor;
+ OUT LPMONITORINFO pMonitorInfoUnsafe)
+{
+ PMONITOR pMonitor;
MONITORINFOEXW MonitorInfo;
NTSTATUS Status;
- DECLARE_RETURN(BOOL);
+ BOOL bRet = FALSE;
TRACE("Enter NtUserGetMonitorInfo\n");
UserEnterShared();
- /* get monitor object */
- if (!(Monitor = UserGetMonitorObject(hMonitor)))
+ /* Get monitor object */
+ pMonitor = UserGetMonitorObject(hMonitor);
+ if (!pMonitor)
{
TRACE("Couldnt find monitor 0x%lx\n", hMonitor);
- RETURN(FALSE);
- }
-
- if(pMonitorInfo == NULL)
+ goto cleanup;
+ }
+
+ /* Check if pMonitorInfoUnsafe is valid */
+ if(pMonitorInfoUnsafe == NULL)
{
SetLastNtError(STATUS_INVALID_PARAMETER);
- RETURN(FALSE);
- }
-
- /* get size of pMonitorInfo */
- Status = MmCopyFromCaller(&MonitorInfo.cbSize, &pMonitorInfo->cbSize,
sizeof (MonitorInfo.cbSize));
+ goto cleanup;
+ }
+
+ /* Get size of pMonitorInfoUnsafe */
+ Status = MmCopyFromCaller(&MonitorInfo.cbSize,
&pMonitorInfoUnsafe->cbSize, sizeof(MonitorInfo.cbSize));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
- RETURN(FALSE);
- }
- if ((MonitorInfo.cbSize != sizeof (MONITORINFO)) &&
- (MonitorInfo.cbSize != sizeof (MONITORINFOEXW)))
+ goto cleanup;
+ }
+
+ /* Check if size of struct is valid */
+ if (MonitorInfo.cbSize != sizeof(MONITORINFO) &&
+ MonitorInfo.cbSize != sizeof(MONITORINFOEXW))
{
SetLastNtError(STATUS_INVALID_PARAMETER);
- RETURN(FALSE);
- }
-
- /* fill monitor info */
- MonitorInfo.rcMonitor = Monitor->rcMonitor;
- MonitorInfo.rcWork = Monitor->rcWork;
+ goto cleanup;
+ }
+
+ /* Fill monitor info */
+ MonitorInfo.rcMonitor = pMonitor->rcMonitor;
+ MonitorInfo.rcWork = pMonitor->rcWork;
MonitorInfo.dwFlags = 0;
-
- if (Monitor->IsPrimary)
+ if (pMonitor->IsPrimary)
MonitorInfo.dwFlags |= MONITORINFOF_PRIMARY;
- /* fill device name */
- if (MonitorInfo.cbSize == sizeof (MONITORINFOEXW))
- {
- RtlStringCbCopyNW(MonitorInfo.szDevice,
+ /* Fill device name */
+ if (MonitorInfo.cbSize == sizeof(MONITORINFOEXW))
+ {
+ RtlStringCbCopyNExW(MonitorInfo.szDevice,
sizeof(MonitorInfo.szDevice),
- Monitor->DeviceName.Buffer,
- Monitor->DeviceName.Length);
- }
-
- /* output data */
- Status = MmCopyToCaller(pMonitorInfo, &MonitorInfo, MonitorInfo.cbSize);
+ pMonitor->DeviceName.Buffer,
+ pMonitor->DeviceName.Length,
+ NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
+ }
+
+ /* Output data */
+ Status = MmCopyToCaller(pMonitorInfoUnsafe, &MonitorInfo, MonitorInfo.cbSize);
if (!NT_SUCCESS(Status))
{
TRACE("GetMonitorInfo: MmCopyToCaller failed\n");
SetLastNtError(Status);
- RETURN(FALSE);
+ goto cleanup;
}
TRACE("GetMonitorInfo: success\n");
-
- RETURN(TRUE);
-
-CLEANUP:
- TRACE("Leave NtUserGetMonitorInfo, ret=%i\n",_ret_);
+ bRet = TRUE;
+
+cleanup:
+ TRACE("Leave NtUserGetMonitorInfo, ret=%i\n", bRet);
UserLeave();
- END_CLEANUP;
+ return bRet;
}
/* NtUserMonitorFromPoint
@@ -700,7 +708,7 @@
*
* Arguments
*
- * point
+ * pt
* Point for which to find monitor
*
* dwFlags
@@ -713,25 +721,32 @@
HMONITOR
APIENTRY
NtUserMonitorFromPoint(
- IN POINT point,
+ IN POINT pt,
IN DWORD dwFlags)
{
- INT NumMonitors;
- RECTL InRect;
+ INT cMonitors;
+ RECTL rc;
HMONITOR hMonitor = NULL;
- /* fill inRect (bottom-right exclusive) */
- InRect.left = point.x;
- InRect.right = point.x + 1;
- InRect.top = point.y;
- InRect.bottom = point.y + 1;
+ /* Check if flags are valid */
+ if (dwFlags != MONITOR_DEFAULTTONULL &&
+ dwFlags != MONITOR_DEFAULTTOPRIMARY &&
+ dwFlags != MONITOR_DEFAULTTONEAREST)
+ {
+ EngSetLastError(ERROR_INVALID_FLAGS);
+ return NULL;
+ }
+
+ /* Fill rect (bottom-right exclusive) */
+ rc.left = pt.x;
+ rc.right = pt.x + 1;
+ rc.top = pt.y;
+ rc.bottom = pt.y + 1;
UserEnterShared();
- /* find intersecting monitor */
- NumMonitors = IntGetMonitorsFromRect(&InRect, &hMonitor, NULL, 1, dwFlags);
- if (NumMonitors < 0)
- hMonitor = NULL;
+ /* Find intersecting monitor */
+ cMonitors = IntGetMonitorsFromRect(&rc, &hMonitor, NULL, 1, dwFlags);
UserLeave();
return hMonitor;
@@ -744,7 +759,7 @@
*
* Arguments
*
- * pRect
+ * pRectUnsafe
* Pointer to a RECT for which to find monitor
*
* dwFlags
@@ -757,78 +772,87 @@
HMONITOR
APIENTRY
NtUserMonitorFromRect(
- IN LPCRECTL pRect,
+ IN LPCRECTL pRectUnsafe,
IN DWORD dwFlags)
{
- ULONG numMonitors, iLargestArea = 0, i;
- PRECTL rectList = NULL;
- HMONITOR *hMonitorList = NULL;
+ ULONG cMonitors, LargestArea = 0, i;
+ PRECTL prcMonitorList = NULL;
+ HMONITOR *phMonitorList = NULL;
HMONITOR hMonitor = NULL;
- RECTL rect;
- NTSTATUS status;
-
- /* get rect */
- status = MmCopyFromCaller(&rect, pRect, sizeof (RECT));
- if (!NT_SUCCESS(status))
- {
- SetLastNtError(status);
- return (HMONITOR)NULL;
+ RECTL Rect;
+ NTSTATUS Status;
+
+ /* Check if flags are valid */
+ if (dwFlags != MONITOR_DEFAULTTONULL &&
+ dwFlags != MONITOR_DEFAULTTOPRIMARY &&
+ dwFlags != MONITOR_DEFAULTTONEAREST)
+ {
+ EngSetLastError(ERROR_INVALID_FLAGS);
+ return NULL;
+ }
+
+ /* Copy rectangle to safe buffer */
+ Status = MmCopyFromCaller(&Rect, pRectUnsafe, sizeof (RECT));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return NULL;
}
UserEnterShared();
- /* find intersecting monitors */
- numMonitors = IntGetMonitorsFromRect(&rect, &hMonitor, NULL, 1, dwFlags);
- if (numMonitors <= 1)
- {
+ /* Find intersecting monitors */
+ cMonitors = IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags);
+ if (cMonitors <= 1)
+ {
+ /* No or one monitor found. Just return handle. */
goto cleanup;
}
- hMonitorList = ExAllocatePoolWithTag(PagedPool,
- sizeof(HMONITOR) * numMonitors,
- USERTAG_MONITORRECTS);
- if (hMonitorList == NULL)
+ /* There is more than one monitor. Find monitor with largest intersection.
+ Temporary reset hMonitor */
+ hMonitor = NULL;
+
+ /* Allocate helper buffers */
+ phMonitorList = ExAllocatePoolWithTag(PagedPool,
+ sizeof(HMONITOR) * cMonitors,
+ USERTAG_MONITORRECTS);
+ if (phMonitorList == NULL)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- hMonitor = NULL;
goto cleanup;
}
- rectList = ExAllocatePoolWithTag(PagedPool,
- sizeof(RECT) * numMonitors,
- USERTAG_MONITORRECTS);
- if (rectList == NULL)
+ prcMonitorList = ExAllocatePoolWithTag(PagedPool,
+ sizeof(RECT) * cMonitors,
+ USERTAG_MONITORRECTS);
+ if (prcMonitorList == NULL)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- hMonitor = NULL;
goto cleanup;
}
- /* get intersecting monitors */
- numMonitors = IntGetMonitorsFromRect(&rect, hMonitorList, rectList,
- numMonitors, 0);
- if (numMonitors == 0)
- {
- hMonitor = NULL;
- goto cleanup;
- }
-
- /* find largest intersection */
- for (i = 0; i < numMonitors; i++)
- {
- ULONG area = (rectList[i].right - rectList[i].left) *
- (rectList[i].bottom - rectList[i].top);
- if (area >= iLargestArea)
- {
- hMonitor = hMonitorList[i];
+ /* Get intersecting monitors again but now with rectangle list */
+ cMonitors = IntGetMonitorsFromRect(&Rect, phMonitorList, prcMonitorList,
+ cMonitors, 0);
+
+ /* Find largest intersection */
+ for (i = 0; i < cMonitors; i++)
+ {
+ ULONG Area = (prcMonitorList[i].right - prcMonitorList[i].left) *
+ (prcMonitorList[i].bottom - prcMonitorList[i].top);
+ if (Area >= LargestArea)
+ {
+ hMonitor = phMonitorList[i];
+ LargestArea = Area;
}
}
cleanup:
- if (hMonitorList)
- ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
- if (rectList)
- ExFreePoolWithTag(rectList, USERTAG_MONITORRECTS);
+ if (phMonitorList)
+ ExFreePoolWithTag(phMonitorList, USERTAG_MONITORRECTS);
+ if (prcMonitorList)
+ ExFreePoolWithTag(prcMonitorList, USERTAG_MONITORRECTS);
UserLeave();
return hMonitor;
@@ -841,33 +865,41 @@
IN HWND hWnd,
IN DWORD dwFlags)
{
- PWND Window;
+ PWND pWnd;
HMONITOR hMonitor = NULL;
- RECTL Rect;
- DECLARE_RETURN(HMONITOR);
+ RECTL Rect = {0, 0, 0, 0};
TRACE("Enter NtUserMonitorFromWindow\n");
+
+ /* Check if flags are valid */
+ if (dwFlags != MONITOR_DEFAULTTONULL &&
+ dwFlags != MONITOR_DEFAULTTOPRIMARY &&
+ dwFlags != MONITOR_DEFAULTTONEAREST)
+ {
+ EngSetLastError(ERROR_INVALID_FLAGS);
+ return NULL;
+ }
+
UserEnterShared();
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- if (dwFlags == MONITOR_DEFAULTTONULL)
- {
- RETURN(hMonitor);
- }
- IntGetMonitorsFromRect(NULL, &hMonitor, NULL, 1, dwFlags);
- RETURN(hMonitor);
- }
-
- Rect.left = Rect.right = Window->rcWindow.left;
- Rect.top = Rect.bottom = Window->rcWindow.bottom;
-
+ /* If window is given, use it first */
+ if (hWnd)
+ {
+ /* Get window object */
+ pWnd = UserGetWindowObject(hWnd);
+ if (!pWnd)
+ goto cleanup;
+
+ /* Find only monitors which have intersection with given window */
+ Rect.left = Rect.right = pWnd->rcWindow.left;
+ Rect.top = Rect.bottom = pWnd->rcWindow.bottom;
+ }
+
+ /* Find monitors now */
IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags);
- RETURN(hMonitor);
-
-CLEANUP:
- TRACE("Leave NtUserMonitorFromWindow, ret=%i\n",_ret_);
+cleanup:
+ TRACE("Leave NtUserMonitorFromWindow, ret=%p\n", hMonitor);
UserLeave();
- END_CLEANUP;
-}
+ return hMonitor;
+}