Fixed a couple of recent bugs, and added some more safeguards (could
[wine.git] / windows / multimon.c
blob2b6f53bdbe77fc9f3b2ac8af07c4b0aa860bdb93
1 /*
2 * Multimonitor APIs
4 * Copyright 1998 Turchanov Sergey
5 */
7 #include "windef.h"
8 #include "wingdi.h"
9 #include "winbase.h"
10 #include "winuser.h"
11 #include "wine/unicode.h"
13 /**********************************************************************/
15 #define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
17 /***********************************************************************
18 * MonitorFromPoint
20 HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
22 if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
23 ((ptScreenCoords.x >= 0) &&
24 (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
25 (ptScreenCoords.y >= 0) &&
26 (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
28 return xPRIMARY_MONITOR;
30 return (HMONITOR)0;
33 /***********************************************************************
34 * MonitorFromRect
36 HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
38 if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
39 ((lprcScreenCoords->right > 0) &&
40 (lprcScreenCoords->bottom > 0) &&
41 (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
42 (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
44 return xPRIMARY_MONITOR;
46 return (HMONITOR)0;
49 /***********************************************************************
50 * MonitorFromWindow
52 HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
54 WINDOWPLACEMENT wp;
56 if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
57 return xPRIMARY_MONITOR;
59 if (IsIconic(hWnd) ?
60 GetWindowPlacement(hWnd, &wp) :
61 GetWindowRect(hWnd, &wp.rcNormalPosition)) {
63 return MonitorFromRect(&wp.rcNormalPosition, dwFlags);
66 return (HMONITOR)0;
69 /***********************************************************************
70 * GetMonitorInfoA
72 BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
74 RECT rcWork;
76 if ((hMonitor == xPRIMARY_MONITOR) &&
77 lpMonitorInfo &&
78 (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
79 SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
81 SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
82 GetSystemMetrics(SM_CXSCREEN),
83 GetSystemMetrics(SM_CYSCREEN) );
84 lpMonitorInfo->rcWork = rcWork;
85 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
87 if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXA))
88 strcpy(((MONITORINFOEXA*)lpMonitorInfo)->szDevice, "DISPLAY");
90 return TRUE;
93 return FALSE;
96 /***********************************************************************
97 * GetMonitorInfoW
99 BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
101 RECT rcWork;
103 if ((hMonitor == xPRIMARY_MONITOR) &&
104 lpMonitorInfo &&
105 (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
106 SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0))
108 SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
109 GetSystemMetrics(SM_CXSCREEN),
110 GetSystemMetrics(SM_CYSCREEN) );
111 lpMonitorInfo->rcWork = rcWork;
112 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
114 if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
115 strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, (LPCWSTR)"D\0I\0S\0P\0L\0A\0Y\0\0");
117 return TRUE;
120 return FALSE;
123 /***********************************************************************
124 * EnumDisplayMonitors
126 BOOL WINAPI EnumDisplayMonitors(
127 HDC hdcOptionalForPainting,
128 LPRECT lprcEnumMonitorsThatIntersect,
129 MONITORENUMPROC lpfnEnumProc,
130 LPARAM dwData)
132 RECT rcLimit;
133 SetRect( &rcLimit, 0, 0, GetSystemMetrics(SM_CXSCREEN),
134 GetSystemMetrics(SM_CYSCREEN) );
136 if (!lpfnEnumProc)
137 return FALSE;
139 if (hdcOptionalForPainting)
141 RECT rcClip;
142 POINT ptOrg;
144 switch (GetClipBox(hdcOptionalForPainting, &rcClip))
146 default:
147 if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
148 return FALSE;
150 OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
151 if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
152 (!lprcEnumMonitorsThatIntersect ||
153 IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
155 break;
157 /*fall thru */
158 case NULLREGION:
159 return TRUE;
160 case ERROR:
161 return FALSE;
163 } else {
164 if ( lprcEnumMonitorsThatIntersect &&
165 !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
167 return TRUE;
171 return lpfnEnumProc(
172 xPRIMARY_MONITOR,
173 hdcOptionalForPainting,
174 &rcLimit,
175 dwData);