ReactOS 0.4.15-dev-7788-g1ad9096
monitor.c File Reference
#include <win32k.h>
#include <debug.h>
Include dependency graph for monitor.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

 DBG_DEFAULT_CHANNEL (UserMonitor)
 
static PMONITOR IntCreateMonitorObject (VOID)
 
static void IntDestroyMonitorObject (IN PMONITOR pMonitor)
 
PMONITOR NTAPI UserGetMonitorObject (IN HMONITOR hMonitor)
 
PMONITOR NTAPI UserGetPrimaryMonitor (VOID)
 
NTSTATUS NTAPI UserAttachMonitor (IN HDEV hDev)
 
NTSTATUS NTAPI UserDetachMonitor (IN HDEV hDev)
 
NTSTATUS NTAPI UserUpdateMonitorSize (IN HDEV hDev)
 
static UINT IntGetMonitorsFromRect (OPTIONAL IN LPCRECTL pRect, OPTIONAL OUT HMONITOR *phMonitorList, OPTIONAL OUT PRECTL prcMonitorList, OPTIONAL IN DWORD dwListSize, OPTIONAL IN DWORD dwFlags)
 
PMONITOR NTAPI UserMonitorFromRect (PRECTL pRect, DWORD dwFlags)
 
PMONITOR FASTCALL UserMonitorFromPoint (IN POINT pt, IN DWORD dwFlags)
 
INT APIENTRY NtUserEnumDisplayMonitors (OPTIONAL IN HDC hdc, OPTIONAL IN LPCRECTL pUnsafeRect, OPTIONAL OUT HMONITOR *phUnsafeMonitorList, OPTIONAL OUT PRECTL prcUnsafeMonitorList, OPTIONAL IN DWORD dwListSize)
 
BOOL APIENTRY NtUserGetMonitorInfo (IN HMONITOR hMonitor, OUT LPMONITORINFO pMonitorInfoUnsafe)
 
HMONITOR APIENTRY NtUserMonitorFromPoint (IN POINT pt, IN DWORD dwFlags)
 
HMONITOR APIENTRY NtUserMonitorFromRect (IN LPCRECTL pRectUnsafe, IN DWORD dwFlags)
 
HMONITOR APIENTRY NtUserMonitorFromWindow (IN HWND hWnd, IN DWORD dwFlags)
 

Variables

static PMONITOR gMonitorList = NULL
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file monitor.c.

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserMonitor  )

◆ IntCreateMonitorObject()

static PMONITOR IntCreateMonitorObject ( VOID  )
static

Definition at line 33 of file monitor.c.

34{
36}
#define NULL
Definition: types.h:112
@ TYPE_MONITOR
Definition: ntuser.h:52
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:568

Referenced by UserAttachMonitor().

◆ IntDestroyMonitorObject()

static void IntDestroyMonitorObject ( IN PMONITOR  pMonitor)
static

Definition at line 50 of file monitor.c.

51{
52 /* Remove monitor region */
53 if (pMonitor->hrgnMonitor)
54 {
55 GreSetObjectOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
56 GreDeleteObject(pMonitor->hrgnMonitor);
57 }
58
59 /* Destroy monitor object */
60 UserDereferenceObject(pMonitor);
62}
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
BOOL NTAPI GreSetObjectOwner(HGDIOBJ hobj, ULONG ulOwner)
Definition: gdiobj.c:1255
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:717

Referenced by UserDetachMonitor().

◆ IntGetMonitorsFromRect()

static UINT IntGetMonitorsFromRect ( OPTIONAL IN LPCRECTL  pRect,
OPTIONAL OUT HMONITOR phMonitorList,
OPTIONAL OUT PRECTL  prcMonitorList,
OPTIONAL IN DWORD  dwListSize,
OPTIONAL IN DWORD  dwFlags 
)
static

Definition at line 310 of file monitor.c.

315{
316 PMONITOR pMonitor, pNearestMonitor = NULL, pPrimaryMonitor = NULL;
317 UINT cMonitors = 0;
318 ULONG iNearestDistance = 0xffffffff;
319
320 /* Find monitors which intersects the rectangle */
321 for (pMonitor = gMonitorList; pMonitor != NULL; pMonitor = pMonitor->pMonitorNext)
322 {
323 RECTL MonitorRect, IntersectionRect;
324
325 MonitorRect = pMonitor->rcMonitor;
326
327 TRACE("MonitorRect: left = %d, top = %d, right = %d, bottom = %d\n",
328 MonitorRect.left, MonitorRect.top, MonitorRect.right, MonitorRect.bottom);
329
330 /* Save primary monitor for later usage */
331 if (dwFlags == MONITOR_DEFAULTTOPRIMARY && pMonitor->IsPrimary)
332 pPrimaryMonitor = pMonitor;
333
334 /* Check if a rect is given */
335 if (pRect == NULL)
336 {
337 /* No rect given, so use the full monitor rect */
338 IntersectionRect = MonitorRect;
339 }
340 /* We have a rect, calculate intersection */
341 else if (!RECTL_bIntersectRect(&IntersectionRect, &MonitorRect, pRect))
342 {
343 /* Rects did not intersect */
344 if (dwFlags == MONITOR_DEFAULTTONEAREST)
345 {
346 ULONG cx, cy, iDistance;
347
348 /* Get x and y distance */
349 cx = min(abs(MonitorRect.left - pRect->right),
350 abs(pRect->left - MonitorRect.right));
351 cy = min(abs(MonitorRect.top - pRect->bottom),
352 abs(pRect->top - MonitorRect.bottom));
353
354 /* Calculate distance square */
355 iDistance = cx * cx + cy * cy;
356
357 /* Check if this is the new nearest monitor */
358 if (iDistance < iNearestDistance)
359 {
360 iNearestDistance = iDistance;
361 pNearestMonitor = pMonitor;
362 }
363 }
364
365 continue;
366 }
367
368 /* Check if there's space in the buffer */
369 if (cMonitors < dwListSize)
370 {
371 /* Save monitor data */
372 if (phMonitorList != NULL)
373 phMonitorList[cMonitors] = UserHMGetHandle(pMonitor);
374 if (prcMonitorList != NULL)
375 prcMonitorList[cMonitors] = IntersectionRect;
376 }
377
378 /* Increase count of found monitors */
379 cMonitors++;
380 }
381
382 /* Nothing has been found? */
383 if (cMonitors == 0)
384 {
385 /* Check if we shall default to the nearest monitor */
386 if (dwFlags == MONITOR_DEFAULTTONEAREST && pNearestMonitor)
387 {
388 if (phMonitorList && dwListSize > 0)
389 phMonitorList[cMonitors] = UserHMGetHandle(pNearestMonitor);
390 cMonitors++;
391 }
392 /* Check if we shall default to the primary monitor */
393 else if (dwFlags == MONITOR_DEFAULTTOPRIMARY && pPrimaryMonitor)
394 {
395 if (phMonitorList != NULL && dwListSize > 0)
396 phMonitorList[cMonitors] = UserHMGetHandle(pPrimaryMonitor);
397 cMonitors++;
398 }
399 }
400
401 return cMonitors;
402}
#define abs(i)
Definition: fconv.c:206
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
#define TRACE(s)
Definition: solgame.cpp:4
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
RECT rcMonitor
Definition: monitor.h:18
DWORD IsPrimary
Definition: monitor.h:15
struct _MONITOR * pMonitorNext
Definition: monitor.h:7
uint32_t ULONG
Definition: typedefs.h:59
BOOL FASTCALL RECTL_bIntersectRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:55
static PMONITOR gMonitorList
Definition: monitor.c:19
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176

Referenced by NtUserEnumDisplayMonitors(), NtUserMonitorFromPoint(), NtUserMonitorFromRect(), NtUserMonitorFromWindow(), UserMonitorFromPoint(), and UserMonitorFromRect().

◆ NtUserEnumDisplayMonitors()

INT APIENTRY NtUserEnumDisplayMonitors ( OPTIONAL IN HDC  hdc,
OPTIONAL IN LPCRECTL  pUnsafeRect,
OPTIONAL OUT HMONITOR phUnsafeMonitorList,
OPTIONAL OUT PRECTL  prcUnsafeMonitorList,
OPTIONAL IN DWORD  dwListSize 
)

Definition at line 543 of file monitor.c.

549{
550 UINT cMonitors, i;
551 INT iRet = -1;
552 HMONITOR *phMonitorList = NULL;
553 PRECTL prcMonitorList = NULL;
554 RECTL rc, *pRect;
555 RECTL DcRect = {0};
557
558 /* Get rectangle */
559 if (pUnsafeRect != NULL)
560 {
561 Status = MmCopyFromCaller(&rc, pUnsafeRect, sizeof(RECT));
562 if (!NT_SUCCESS(Status))
563 {
564 TRACE("MmCopyFromCaller() failed!\n");
566 return -1;
567 }
568 }
569
570 if (hdc != NULL)
571 {
572 PDC pDc;
573 INT iRgnType;
574
575 /* Get visible region bounding rect */
576 pDc = DC_LockDc(hdc);
577 if (pDc == NULL)
578 {
579 TRACE("DC_LockDc() failed!\n");
580 /* FIXME: setlasterror? */
581 return -1;
582 }
583 iRgnType = REGION_GetRgnBox(pDc->prgnVis, &DcRect);
584 DC_UnlockDc(pDc);
585
586 if (iRgnType == 0)
587 {
588 TRACE("NtGdiGetRgnBox() failed!\n");
589 return -1;
590 }
591 if (iRgnType == NULLREGION)
592 return 0;
593 if (iRgnType == COMPLEXREGION)
594 {
595 /* TODO: Warning */
596 }
597
598 /* If hdc and pRect are given the area of interest is pRect with
599 coordinate origin at the DC position */
600 if (pUnsafeRect != NULL)
601 {
602 rc.left += DcRect.left;
603 rc.right += DcRect.left;
604 rc.top += DcRect.top;
605 rc.bottom += DcRect.top;
606 }
607 /* If hdc is given and pRect is not the area of interest is the
608 bounding rect of hdc */
609 else
610 {
611 rc = DcRect;
612 }
613 }
614
615 if (hdc == NULL && pUnsafeRect == NULL)
616 pRect = NULL;
617 else
618 pRect = &rc;
619
621
622 /* Find intersecting monitors */
623 cMonitors = IntGetMonitorsFromRect(pRect, NULL, NULL, 0, MONITOR_DEFAULTTONULL);
624 if (cMonitors == 0 || dwListSize == 0 ||
625 (phUnsafeMonitorList == NULL && prcUnsafeMonitorList == NULL))
626 {
627 /* Simple case - just return monitors count */
628 TRACE("cMonitors = %u\n", cMonitors);
629 iRet = cMonitors;
630 goto cleanup;
631 }
632
633 /* Allocate safe buffers */
634 if (phUnsafeMonitorList != NULL && dwListSize != 0)
635 {
636 phMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * dwListSize, USERTAG_MONITORRECTS);
637 if (phMonitorList == NULL)
638 {
640 goto cleanup;
641 }
642 }
643 if (prcUnsafeMonitorList != NULL && dwListSize != 0)
644 {
645 prcMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof(RECT) * dwListSize,USERTAG_MONITORRECTS);
646 if (prcMonitorList == NULL)
647 {
649 goto cleanup;
650 }
651 }
652
653 /* Get intersecting monitors */
654 cMonitors = IntGetMonitorsFromRect(pRect, phMonitorList, prcMonitorList,
655 dwListSize, MONITOR_DEFAULTTONULL);
656
657 if (hdc != NULL && pRect != NULL && prcMonitorList != NULL)
658 {
659 for (i = 0; i < min(cMonitors, dwListSize); i++)
660 {
661 _Analysis_assume_(i < dwListSize);
662 prcMonitorList[i].left -= DcRect.left;
663 prcMonitorList[i].right -= DcRect.left;
664 prcMonitorList[i].top -= DcRect.top;
665 prcMonitorList[i].bottom -= DcRect.top;
666 }
667 }
668
669 /* Output result */
670 if (phUnsafeMonitorList != NULL && dwListSize != 0)
671 {
672 Status = MmCopyToCaller(phUnsafeMonitorList, phMonitorList, sizeof(HMONITOR) * dwListSize);
673 if (!NT_SUCCESS(Status))
674 {
676 goto cleanup;
677 }
678 }
679 if (prcUnsafeMonitorList != NULL && dwListSize != 0)
680 {
681 Status = MmCopyToCaller(prcUnsafeMonitorList, prcMonitorList, sizeof(RECT) * dwListSize);
682 if (!NT_SUCCESS(Status))
683 {
685 goto cleanup;
686 }
687 }
688
689 /* Return monitors count on success */
690 iRet = cMonitors;
691
692cleanup:
693 if (phMonitorList)
695 if (prcMonitorList)
697
698 UserLeave();
699 return iRet;
700}
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:238
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:220
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static void cleanup(void)
Definition: main.c:1335
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
HDC hdc
Definition: main.c:9
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:251
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:235
#define MmCopyFromCaller
Definition: polytest.cpp:29
Definition: polytest.cpp:41
int32_t INT
Definition: typedefs.h:58
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
INT FASTCALL REGION_GetRgnBox(PREGION Rgn, PRECTL pRect)
Definition: region.c:2543
static UINT IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect, OPTIONAL OUT HMONITOR *phMonitorList, OPTIONAL OUT PRECTL prcMonitorList, OPTIONAL IN DWORD dwListSize, OPTIONAL IN DWORD dwFlags)
Definition: monitor.c:310
#define USERTAG_MONITORRECTS
Definition: tags.h:254
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
#define COMPLEXREGION
Definition: wingdi.h:363
#define NULLREGION
Definition: wingdi.h:361

◆ NtUserGetMonitorInfo()

BOOL APIENTRY NtUserGetMonitorInfo ( IN HMONITOR  hMonitor,
OUT LPMONITORINFO  pMonitorInfoUnsafe 
)

Definition at line 728 of file monitor.c.

731{
732 PMONITOR pMonitor;
733 MONITORINFOEXW MonitorInfo;
735 BOOL bRet = FALSE;
736 PWCHAR pwstrDeviceName;
737
738 TRACE("Enter NtUserGetMonitorInfo\n");
740
741 /* Get monitor object */
742 pMonitor = UserGetMonitorObject(hMonitor);
743 if (!pMonitor)
744 {
745 TRACE("Couldnt find monitor %p\n", hMonitor);
746 goto cleanup;
747 }
748
749 /* Check if pMonitorInfoUnsafe is valid */
750 if(pMonitorInfoUnsafe == NULL)
751 {
753 goto cleanup;
754 }
755
756 pwstrDeviceName = ((PPDEVOBJ)(pMonitor->hDev))->pGraphicsDevice->szWinDeviceName;
757
758 /* Get size of pMonitorInfoUnsafe */
759 Status = MmCopyFromCaller(&MonitorInfo.cbSize, &pMonitorInfoUnsafe->cbSize, sizeof(MonitorInfo.cbSize));
760 if (!NT_SUCCESS(Status))
761 {
763 goto cleanup;
764 }
765
766 /* Check if size of struct is valid */
767 if (MonitorInfo.cbSize != sizeof(MONITORINFO) &&
768 MonitorInfo.cbSize != sizeof(MONITORINFOEXW))
769 {
771 goto cleanup;
772 }
773
774 /* Fill monitor info */
775 MonitorInfo.rcMonitor = pMonitor->rcMonitor;
776 MonitorInfo.rcWork = pMonitor->rcWork;
777 MonitorInfo.dwFlags = 0;
778 if (pMonitor->IsPrimary)
779 MonitorInfo.dwFlags |= MONITORINFOF_PRIMARY;
780
781 /* Fill device name */
782 if (MonitorInfo.cbSize == sizeof(MONITORINFOEXW))
783 {
784 RtlStringCbCopyNExW(MonitorInfo.szDevice,
785 sizeof(MonitorInfo.szDevice),
786 pwstrDeviceName,
787 (wcslen(pwstrDeviceName)+1) * sizeof(WCHAR),
789 }
790
791 /* Output data */
792 Status = MmCopyToCaller(pMonitorInfoUnsafe, &MonitorInfo, MonitorInfo.cbSize);
793 if (!NT_SUCCESS(Status))
794 {
795 TRACE("GetMonitorInfo: MmCopyToCaller failed\n");
797 goto cleanup;
798 }
799
800 TRACE("GetMonitorInfo: success\n");
801 bRet = TRUE;
802
803cleanup:
804 TRACE("Leave NtUserGetMonitorInfo, ret=%i\n", bRet);
805 UserLeave();
806 return bRet;
807}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
struct _PDEVOBJ * PPDEVOBJ
Definition: mdevobj.h:6
NTSTRSAFEAPI RtlStringCbCopyNExW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy, _Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR *ppszDestEnd, _Out_opt_ size_t *pcbRemaining, _In_ STRSAFE_DWORD dwFlags)
Definition: ntstrsafe.h:547
#define STRSAFE_FILL_BEHIND_NULL
Definition: ntstrsafe.h:32
RECT rcWork
Definition: monitor.h:19
HDEV hDev
Definition: monitor.h:23
WCHAR szDevice[CCHDEVICENAME]
Definition: winuser.h:3804
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PMONITOR NTAPI UserGetMonitorObject(IN HMONITOR hMonitor)
Definition: monitor.c:74
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by GetMonitorInfoA(), and GetMonitorInfoW().

◆ NtUserMonitorFromPoint()

HMONITOR APIENTRY NtUserMonitorFromPoint ( IN POINT  pt,
IN DWORD  dwFlags 
)

Definition at line 827 of file monitor.c.

830{
831 RECTL rc;
832 HMONITOR hMonitor = NULL;
833
834 /* Check if flags are valid */
835 if (dwFlags != MONITOR_DEFAULTTONULL &&
836 dwFlags != MONITOR_DEFAULTTOPRIMARY &&
837 dwFlags != MONITOR_DEFAULTTONEAREST)
838 {
840 return NULL;
841 }
842
843 /* Fill rect (bottom-right exclusive) */
844 rc.left = pt.x;
845 rc.right = pt.x + 1;
846 rc.top = pt.y;
847 rc.bottom = pt.y + 1;
848
850
851 /* Find intersecting monitor */
852 IntGetMonitorsFromRect(&rc, &hMonitor, NULL, 1, dwFlags);
853
854 UserLeave();
855 return hMonitor;
856}
#define pt(x, y)
Definition: drawing.c:79
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583

Referenced by MonitorFromPoint().

◆ NtUserMonitorFromRect()

HMONITOR APIENTRY NtUserMonitorFromRect ( IN LPCRECTL  pRectUnsafe,
IN DWORD  dwFlags 
)

Definition at line 877 of file monitor.c.

880{
881 ULONG cMonitors, LargestArea = 0, i;
882 PRECTL prcMonitorList = NULL;
883 HMONITOR *phMonitorList = NULL;
884 HMONITOR hMonitor = NULL;
885 RECTL Rect;
887
888 /* Check if flags are valid */
889 if (dwFlags != MONITOR_DEFAULTTONULL &&
890 dwFlags != MONITOR_DEFAULTTOPRIMARY &&
891 dwFlags != MONITOR_DEFAULTTONEAREST)
892 {
894 return NULL;
895 }
896
897 /* Copy rectangle to safe buffer */
898 Status = MmCopyFromCaller(&Rect, pRectUnsafe, sizeof (RECT));
899 if (!NT_SUCCESS(Status))
900 {
902 return NULL;
903 }
904
906
907 /* Find intersecting monitors */
908 cMonitors = IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags);
909 if (cMonitors <= 1)
910 {
911 /* No or one monitor found. Just return handle. */
912 goto cleanup;
913 }
914
915 /* There is more than one monitor. Find monitor with largest intersection.
916 Temporary reset hMonitor */
917 hMonitor = NULL;
918
919 /* Allocate helper buffers */
920 phMonitorList = ExAllocatePoolWithTag(PagedPool,
921 sizeof(HMONITOR) * cMonitors,
923 if (phMonitorList == NULL)
924 {
926 goto cleanup;
927 }
928
929 prcMonitorList = ExAllocatePoolWithTag(PagedPool,
930 sizeof(RECT) * cMonitors,
932 if (prcMonitorList == NULL)
933 {
935 goto cleanup;
936 }
937
938 /* Get intersecting monitors again but now with rectangle list */
939 cMonitors = IntGetMonitorsFromRect(&Rect, phMonitorList, prcMonitorList,
940 cMonitors, 0);
941
942 /* Find largest intersection */
943 for (i = 0; i < cMonitors; i++)
944 {
945 ULONG Area = (prcMonitorList[i].right - prcMonitorList[i].left) *
946 (prcMonitorList[i].bottom - prcMonitorList[i].top);
947 if (Area >= LargestArea)
948 {
949 hMonitor = phMonitorList[i];
950 LargestArea = Area;
951 }
952 }
953
954cleanup:
955 if (phMonitorList)
957 if (prcMonitorList)
959 UserLeave();
960
961 return hMonitor;
962}
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLint GLint bottom
Definition: glext.h:7726

◆ NtUserMonitorFromWindow()

HMONITOR APIENTRY NtUserMonitorFromWindow ( IN HWND  hWnd,
IN DWORD  dwFlags 
)

Definition at line 967 of file monitor.c.

970{
971 PWND pWnd;
972 HMONITOR hMonitor = NULL;
973 RECTL Rect = {0, 0, 0, 0};
974
975 TRACE("Enter NtUserMonitorFromWindow\n");
976
977 /* Check if flags are valid */
978 if (dwFlags != MONITOR_DEFAULTTONULL &&
979 dwFlags != MONITOR_DEFAULTTOPRIMARY &&
980 dwFlags != MONITOR_DEFAULTTONEAREST)
981 {
983 return NULL;
984 }
985
987
988 /* If window is given, use it first */
989 if (hWnd)
990 {
991 /* Get window object */
993 if (!pWnd)
994 goto cleanup;
995
996 /* Find only monitors which have intersection with given window */
997 Rect.left = Rect.right = pWnd->rcWindow.left;
998 Rect.top = Rect.bottom = pWnd->rcWindow.bottom;
999 }
1000
1001 /* Find monitors now */
1002 IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags);
1003
1004cleanup:
1005 TRACE("Leave NtUserMonitorFromWindow, ret=%p\n", hMonitor);
1006 UserLeave();
1007 return hMonitor;
1008}
HWND hWnd
Definition: settings.c:17
Definition: ntuser.h:694
RECT rcWindow
Definition: ntuser.h:716
LONG bottom
Definition: windef.h:309
LONG left
Definition: windef.h:306
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:122

Referenced by MonitorFromWindow().

◆ UserAttachMonitor()

NTSTATUS NTAPI UserAttachMonitor ( IN HDEV  hDev)

Definition at line 129 of file monitor.c.

130{
131 PMONITOR pMonitor;
132
133 TRACE("Attaching monitor...\n");
134
135 /* Create new monitor object */
136 pMonitor = IntCreateMonitorObject();
137 if (pMonitor == NULL)
138 {
139 TRACE("Couldnt create monitor object\n");
141 }
142
143 pMonitor->hDev = hDev;
144 pMonitor->cWndStack = 0;
145
146 if (gMonitorList == NULL)
147 {
148 TRACE("Primary monitor is beeing attached\n");
149 pMonitor->IsPrimary = TRUE;
150 gMonitorList = pMonitor;
151 }
152 else
153 {
154 PMONITOR pmonLast = gMonitorList;
155 TRACE("Additional monitor is beeing attached\n");
156 while (pmonLast->pMonitorNext != NULL)
157 pmonLast = pmonLast->pMonitorNext;
158
159 pmonLast->pMonitorNext = pMonitor;
160 }
161
163
164 return STATUS_SUCCESS;
165}
#define STATUS_SUCCESS
Definition: shellext.h:65
SHORT cWndStack
Definition: monitor.h:22
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static PMONITOR IntCreateMonitorObject(VOID)
Definition: monitor.c:33
NTSTATUS NTAPI UserUpdateMonitorSize(IN HDEV hDev)
Definition: monitor.c:225

Referenced by co_IntInitializeDesktopGraphics().

◆ UserDetachMonitor()

NTSTATUS NTAPI UserDetachMonitor ( IN HDEV  hDev)

Definition at line 179 of file monitor.c.

180{
181 PMONITOR pMonitor = gMonitorList, *pLink = &gMonitorList;
182
183 /* Find monitor attached to given device */
184 while (pMonitor != NULL)
185 {
186 if (pMonitor->hDev == hDev)
187 break;
188
189 pLink = &pMonitor->pMonitorNext;
190 pMonitor = pMonitor->pMonitorNext;
191 }
192
193 if (pMonitor == NULL)
194 {
195 /* No monitor has been found */
197 }
198
199 /* We destroy primary monitor - set next as primary */
200 if (pMonitor->IsPrimary && pMonitor->pMonitorNext != NULL)
201 pMonitor->pMonitorNext->IsPrimary = TRUE;
202
203 /* Update Next ptr in previous monitor */
204 *pLink = pMonitor->pMonitorNext;
205
206 /* Finally destroy monitor */
207 IntDestroyMonitorObject(pMonitor);
208
209 return STATUS_SUCCESS;
210}
static void IntDestroyMonitorObject(IN PMONITOR pMonitor)
Definition: monitor.c:50

◆ UserGetMonitorObject()

PMONITOR NTAPI UserGetMonitorObject ( IN HMONITOR  hMonitor)

Definition at line 74 of file monitor.c.

75{
76 PMONITOR pMonitor;
77
78 if (!hMonitor)
79 {
81 return NULL;
82 }
83
84 pMonitor = (PMONITOR)UserGetObject(gHandleTable, hMonitor, TYPE_MONITOR);
85 if (!pMonitor)
86 {
88 return NULL;
89 }
90
91 return pMonitor;
92}
struct _MONITOR * PMONITOR
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:495
#define ERROR_INVALID_MONITOR_HANDLE
Definition: winerror.h:942

Referenced by NtUserGetMonitorInfo(), UserMonitorFromPoint(), and UserMonitorFromRect().

◆ UserGetPrimaryMonitor()

PMONITOR NTAPI UserGetPrimaryMonitor ( VOID  )

Definition at line 102 of file monitor.c.

103{
104 PMONITOR pMonitor;
105
106 /* Find primary monitor */
107 for (pMonitor = gMonitorList; pMonitor != NULL; pMonitor = pMonitor->pMonitorNext)
108 {
109 if (pMonitor->IsPrimary)
110 break;
111 }
112
113 return pMonitor;
114}

Referenced by co_UserExcludeUpdateRgn(), co_WinPosGetMinMaxInfo(), IntFixWindowCoordinates(), IntIsWindowFullscreen(), SpiGetSet(), and UserGetDesktopDC().

◆ UserMonitorFromPoint()

PMONITOR FASTCALL UserMonitorFromPoint ( IN POINT  pt,
IN DWORD  dwFlags 
)

Definition at line 481 of file monitor.c.

484{
485 RECTL rc;
486 HMONITOR hMonitor = NULL;
487
488 /* Check if flags are valid */
489 if (dwFlags != MONITOR_DEFAULTTONULL &&
490 dwFlags != MONITOR_DEFAULTTOPRIMARY &&
491 dwFlags != MONITOR_DEFAULTTONEAREST)
492 {
494 return NULL;
495 }
496
497 /* Fill rect (bottom-right exclusive) */
498 rc.left = pt.x;
499 rc.right = pt.x + 1;
500 rc.top = pt.y;
501 rc.bottom = pt.y + 1;
502
503 /* Find intersecting monitor */
504 IntGetMonitorsFromRect(&rc, &hMonitor, NULL, 1, dwFlags);
505
506 return UserGetMonitorObject(hMonitor);
507}

Referenced by MENU_ShowPopup().

◆ UserMonitorFromRect()

PMONITOR NTAPI UserMonitorFromRect ( PRECTL  pRect,
DWORD  dwFlags 
)

Definition at line 405 of file monitor.c.

408{
409 ULONG cMonitors, LargestArea = 0, i;
410 PRECTL prcMonitorList = NULL;
411 HMONITOR *phMonitorList = NULL;
412 HMONITOR hMonitor = NULL;
413
414 /* Check if flags are valid */
415 if (dwFlags != MONITOR_DEFAULTTONULL &&
416 dwFlags != MONITOR_DEFAULTTOPRIMARY &&
417 dwFlags != MONITOR_DEFAULTTONEAREST)
418 {
420 return NULL;
421 }
422
423 /* Find intersecting monitors */
424 cMonitors = IntGetMonitorsFromRect(pRect, &hMonitor, NULL, 1, dwFlags);
425 if (cMonitors <= 1)
426 {
427 /* No or one monitor found. Just return handle. */
428 goto cleanup;
429 }
430
431 /* There is more than one monitor. Find monitor with largest intersection.
432 Temporary reset hMonitor */
433 hMonitor = NULL;
434
435 /* Allocate helper buffers */
436 phMonitorList = ExAllocatePoolWithTag(PagedPool,
437 sizeof(HMONITOR) * cMonitors,
439 if (phMonitorList == NULL)
440 {
442 goto cleanup;
443 }
444
445 prcMonitorList = ExAllocatePoolWithTag(PagedPool,
446 sizeof(RECT) * cMonitors,
448 if (prcMonitorList == NULL)
449 {
451 goto cleanup;
452 }
453
454 /* Get intersecting monitors again but now with rectangle list */
455 cMonitors = IntGetMonitorsFromRect(pRect, phMonitorList, prcMonitorList,
456 cMonitors, 0);
457
458 /* Find largest intersection */
459 for (i = 0; i < cMonitors; i++)
460 {
461 ULONG Area = (prcMonitorList[i].right - prcMonitorList[i].left) *
462 (prcMonitorList[i].bottom - prcMonitorList[i].top);
463 if (Area >= LargestArea)
464 {
465 hMonitor = phMonitorList[i];
466 LargestArea = Area;
467 }
468 }
469
470cleanup:
471 if (phMonitorList)
473 if (prcMonitorList)
475
476 return UserGetMonitorObject(hMonitor);
477}

Referenced by IntGetWindowPlacement(), make_rect_onscreen(), SpiGetSet(), and WinPosInitInternalPos().

◆ UserUpdateMonitorSize()

NTSTATUS NTAPI UserUpdateMonitorSize ( IN HDEV  hDev)

Definition at line 225 of file monitor.c.

226{
227 PMONITOR pMonitor;
228 SIZEL DeviceSize;
229
230 /* Find monitor attached to given device */
231 for (pMonitor = gMonitorList; pMonitor != NULL; pMonitor = pMonitor->pMonitorNext)
232 {
233 if (pMonitor->hDev == hDev)
234 break;
235 }
236
237 if (pMonitor == NULL)
238 {
239 /* No monitor has been found */
241 }
242
243 /* Get the size of the hdev */
244 PDEVOBJ_sizl((PPDEVOBJ)hDev, &DeviceSize);
245
246 /* Update monitor size */
247 pMonitor->rcMonitor.left = 0;
248 pMonitor->rcMonitor.top = 0;
249 pMonitor->rcMonitor.right = pMonitor->rcMonitor.left + DeviceSize.cx;
250 pMonitor->rcMonitor.bottom = pMonitor->rcMonitor.top + DeviceSize.cy;
251 pMonitor->rcWork = pMonitor->rcMonitor;
252
253 /* Destroy monitor region... */
254 if (pMonitor->hrgnMonitor)
255 {
257 GreDeleteObject(pMonitor->hrgnMonitor);
258 }
259
260 /* ...and create new one */
262 pMonitor->rcMonitor.left,
263 pMonitor->rcMonitor.top,
264 pMonitor->rcMonitor.right,
265 pMonitor->rcMonitor.bottom);
266 if (pMonitor->hrgnMonitor)
268
269 //
270 // Should be Virtual accumulation of all the available monitors.
271 //
272 gpsi->rcScreenReal = pMonitor->rcMonitor;
273
274 return STATUS_SUCCESS;
275}
PSERVERINFO gpsi
Definition: imm.c:18
__kernel_entry W32KAPI HRGN APIENTRY NtGdiCreateRectRgn(_In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom)
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
PSIZEL FASTCALL PDEVOBJ_sizl(PPDEVOBJ ppdev, PSIZEL psizl)
Definition: pdevobj.c:1359
HRGN hrgnMonitor
Definition: monitor.h:20
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
LONG right
Definition: windef.h:308
LONG top
Definition: windef.h:307
BOOL FASTCALL IntGdiSetRegionOwner(HRGN hRgn, DWORD OwnerMask)
Definition: region.c:2459

Referenced by co_IntInitializeDesktopGraphics(), UserAttachMonitor(), and UserChangeDisplaySettings().

Variable Documentation

◆ gMonitorList