/* NtUserMonitorFromPoint * * Returns a handle to the monitor containing the given point. * * Arguments * * pt * Point for which to find monitor * * dwFlags * Specifies the behaviour if the point isn't on any of the monitors. * * Return value * If the point is found a handle to the monitor is returned; if not the * return value depends on dwFlags */ HMONITOR APIENTRY NtUserMonitorFromPoint( IN POINT pt, IN DWORD dwFlags) { RECTL rc; HMONITOR hMonitor = NULL; /* 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 */ IntGetMonitorsFromRect(&rc, &hMonitor, NULL, 1, dwFlags); UserLeave(); return hMonitor; }
/* NtUserMonitorFromPoint * * Returns a handle to the monitor containing the given point. * * Arguments * * point * Point for which to find monitor * * dwFlags * Specifies the behaviour if the point isn't on any of the monitors. * * Return value * If the point is found a handle to the monitor is returned; if not the * return value depends on dwFlags */ HMONITOR APIENTRY NtUserMonitorFromPoint( IN POINT point, IN DWORD dwFlags) { INT NumMonitors; RECTL InRect; 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; /* find intersecting monitor */ NumMonitors = IntGetMonitorsFromRect(&InRect, &hMonitor, NULL, 1, dwFlags); if (NumMonitors < 0) { return (HMONITOR)NULL; } return hMonitor; }
HMONITOR APIENTRY NtUserMonitorFromWindow( IN HWND hWnd, IN DWORD dwFlags) { PWND Window; HMONITOR hMonitor = NULL; RECTL Rect; DECLARE_RETURN(HMONITOR); TRACE("Enter NtUserMonitorFromWindow\n"); 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; IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags); RETURN(hMonitor); CLEANUP: TRACE("Leave NtUserMonitorFromWindow, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
HMONITOR APIENTRY NtUserMonitorFromWindow( IN HWND hWnd, IN DWORD dwFlags) { PWND pWnd; HMONITOR hMonitor = NULL; 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 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); cleanup: TRACE("Leave NtUserMonitorFromWindow, ret=%p\n", hMonitor); UserLeave(); return hMonitor; }
/* NtUserMonitorFromRect * * Returns a handle to the monitor having the largest intersection with a * given rectangle * * Arguments * * pRect * Pointer to a RECT for which to find monitor * * dwFlags * Specifies the behaviour if no monitor intersects the given rect * * Return value * If a monitor intersects the rect a handle to it is returned; if not the * return value depends on dwFlags */ HMONITOR APIENTRY NtUserMonitorFromRect( IN LPCRECTL pRect, IN DWORD dwFlags) { ULONG numMonitors, iLargestArea = 0, i; PRECTL rectList; HMONITOR *hMonitorList; HMONITOR hMonitor = NULL; RECTL rect; NTSTATUS status; /* get rect */ status = MmCopyFromCaller(&rect, pRect, sizeof (RECT)); if (!NT_SUCCESS(status)) { SetLastNtError(status); return (HMONITOR)NULL; } /* find intersecting monitors */ numMonitors = IntGetMonitorsFromRect(&rect, &hMonitor, NULL, 1, dwFlags); if (numMonitors <= 1) { return hMonitor; } hMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof(HMONITOR) * numMonitors, USERTAG_MONITORRECTS); if (hMonitorList == NULL) { /* FIXME: EngSetLastError? */ return (HMONITOR)NULL; } rectList = ExAllocatePoolWithTag(PagedPool, sizeof(RECT) * numMonitors, USERTAG_MONITORRECTS); if (rectList == NULL) { ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS); /* FIXME: EngSetLastError? */ return (HMONITOR)NULL; } /* get intersecting monitors */ numMonitors = IntGetMonitorsFromRect(&rect, hMonitorList, rectList, numMonitors, 0); if (numMonitors == 0) { ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS); ExFreePoolWithTag(rectList, USERTAG_MONITORRECTS); return (HMONITOR)NULL; } /* 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]; } } ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS); ExFreePoolWithTag(rectList, USERTAG_MONITORRECTS); return hMonitor; }
/* NtUserEnumDisplayMonitors * * Enumerates display monitors which intersect the given HDC/cliprect * * Arguments * * 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 * 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 * Pointer to an array of HMONITOR which is filled with monitor handles. * Can be NULL * * monitorRectList * Pointer to an array of RECT which is filled with intersection rectangles. * Can be NULL * * listSize * Size of the hMonitorList and monitorRectList arguments. If this is zero * hMonitorList and monitorRectList are ignored. * * Returns * The number of monitors which intersect the specified region or -1 on failure. */ 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)) { TRACE("MmCopyFromCaller() failed!\n"); SetLastNtError(status); return -1; } } if (hDC != NULL) { PDC dc; INT regionType; /* get visible region bounding rect */ dc = DC_LockDc(hDC); if (dc == NULL) { TRACE("DC_LockDc() failed!\n"); /* FIXME: setlasterror? */ return -1; } regionType = REGION_GetRgnBox(dc->prgnVis, &dcRect); DC_UnlockDc(dc); if (regionType == 0) { TRACE("NtGdiGetRgnBox() failed!\n"); return -1; } if (regionType == NULLREGION) return 0; if (regionType == COMPLEXREGION) { /* TODO: warning */ } /* 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 */ else { rect = dcRect; } } if (hDC == NULL && pRect == NULL) myRect = NULL; else myRect = ▭ /* find intersecting monitors */ numMonitors = IntGetMonitorsFromRect(myRect, NULL, NULL, 0, 0); if (numMonitors == 0 || listSize == 0 || (hMonitorList == NULL && monitorRectList == NULL)) { TRACE("numMonitors = %d\n", numMonitors); return numMonitors; } if (hMonitorList != NULL && listSize != 0) { safeHMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * listSize, USERTAG_MONITORRECTS); if (safeHMonitorList == NULL) { /* FIXME: EngSetLastError? */ return -1; } } if (monitorRectList != NULL && listSize != 0) { safeRectList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * listSize, USERTAG_MONITORRECTS); if (safeRectList == NULL) { ExFreePoolWithTag(safeHMonitorList, USERTAG_MONITORRECTS); /* FIXME: EngSetLastError? */ return -1; } } /* 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); ExFreePool(safeHMonitorList); if (!NT_SUCCESS(status)) { ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS); SetLastNtError(status); return -1; } } if (monitorRectList != NULL && listSize != 0) { status = MmCopyToCaller(monitorRectList, safeRectList, sizeof (RECT) * listSize); ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS); if (!NT_SUCCESS(status)) { SetLastNtError(status); return -1; } } return numMonitors; }
/* NtUserMonitorFromRect * * Returns a handle to the monitor having the largest intersection with a * given rectangle * * Arguments * * pRectUnsafe * Pointer to a RECT for which to find monitor * * dwFlags * Specifies the behaviour if no monitor intersects the given rect * * Return value * If a monitor intersects the rect a handle to it is returned; if not the * return value depends on dwFlags */ HMONITOR APIENTRY NtUserMonitorFromRect( IN LPCRECTL pRectUnsafe, IN DWORD dwFlags) { ULONG cMonitors, LargestArea = 0, i; PRECTL prcMonitorList = NULL; HMONITOR *phMonitorList = NULL; HMONITOR 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 */ cMonitors = IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags); if (cMonitors <= 1) { /* No or one monitor found. Just return handle. */ goto cleanup; } /* 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); goto cleanup; } prcMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof(RECT) * cMonitors, USERTAG_MONITORRECTS); if (prcMonitorList == NULL) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } /* 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 (phMonitorList) ExFreePoolWithTag(phMonitorList, USERTAG_MONITORRECTS); if (prcMonitorList) ExFreePoolWithTag(prcMonitorList, USERTAG_MONITORRECTS); UserLeave(); return hMonitor; }
/* NtUserEnumDisplayMonitors * * Enumerates display monitors which intersect the given HDC/cliprect * * Arguments * * 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. * * 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 * * phUnsafeMonitorList * Pointer to an array of HMONITOR which is filled with monitor handles. * Can be NULL * * prcUnsafeMonitorList * Pointer to an array of RECT which is filled with intersection rectangles. * Can be NULL * * dwListSize * Size of the hMonitorList and monitorRectList arguments. If this is zero * hMonitorList and monitorRectList are ignored. * * Returns * The number of monitors which intersect the specified region or -1 on failure. */ INT APIENTRY NtUserEnumDisplayMonitors( 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); return -1; } } 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; } iRgnType = REGION_GetRgnBox(pDc->prgnVis, &DcRect); DC_UnlockDc(pDc); if (iRgnType == 0) { TRACE("NtGdiGetRgnBox() failed!\n"); return -1; } if (iRgnType == NULLREGION) return 0; if (iRgnType == COMPLEXREGION) { /* TODO: Warning */ } /* If hdc and pRect are given the area of interest is pRect with coordinate origin at the DC position */ 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 { rc = DcRect; } } if (hdc == NULL && pUnsafeRect == NULL) pRect = NULL; else pRect = &rc; UserEnterShared(); /* 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; } /* Allocate safe buffers */ if (phUnsafeMonitorList != NULL && dwListSize != 0) { phMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * dwListSize, USERTAG_MONITORRECTS); if (phMonitorList == NULL) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } } if (prcUnsafeMonitorList != NULL && dwListSize != 0) { prcMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * dwListSize, USERTAG_MONITORRECTS); if (prcMonitorList == NULL) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } } /* 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 (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 iRet; }
PMONITOR NTAPI UserMonitorFromRect( PRECTL pRect, DWORD dwFlags) { ULONG cMonitors, LargestArea = 0, i; PRECTL prcMonitorList = NULL; HMONITOR *phMonitorList = NULL; HMONITOR hMonitor = NULL; /* Check if flags are valid */ if (dwFlags != MONITOR_DEFAULTTONULL && dwFlags != MONITOR_DEFAULTTOPRIMARY && dwFlags != MONITOR_DEFAULTTONEAREST) { EngSetLastError(ERROR_INVALID_FLAGS); return NULL; } /* Find intersecting monitors */ cMonitors = IntGetMonitorsFromRect(pRect, &hMonitor, NULL, 1, dwFlags); if (cMonitors <= 1) { /* No or one monitor found. Just return handle. */ goto cleanup; } /* 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); goto cleanup; } prcMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof(RECT) * cMonitors, USERTAG_MONITORRECTS); if (prcMonitorList == NULL) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } /* Get intersecting monitors again but now with rectangle list */ cMonitors = IntGetMonitorsFromRect(pRect, 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 (phMonitorList) ExFreePoolWithTag(phMonitorList, USERTAG_MONITORRECTS); if (prcMonitorList) ExFreePoolWithTag(prcMonitorList, USERTAG_MONITORRECTS); return UserGetMonitorObject(hMonitor); }