blob: 1b9617a91b7f134e0ba58b5d8e4f428e872c2d58 [file] [log] [blame]
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001/*
2 * Multimonitor APIs
3 *
4 * Copyright 1998 Turchanov Sergey
5 */
6
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +00007#include "monitor.h"
Jeremy Whited3e22d92000-02-10 19:03:02 +00008#include "windef.h"
9#include "wingdi.h"
Marcus Meissner61afa331999-02-22 10:16:00 +000010#include "winbase.h"
11#include "winuser.h"
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000012
13/**********************************************************************/
14
15MONITOR_DRIVER *MONITOR_Driver;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000016
Patrik Stridvalle8c89481999-02-04 10:12:55 +000017/**********************************************************************/
18
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000019#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
20
Patrik Stridvalle8c89481999-02-04 10:12:55 +000021MONITOR MONITOR_PrimaryMonitor;
22
23/***********************************************************************
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000024 * MONITOR_GetMonitor
25 */
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +000026static MONITOR *MONITOR_GetMonitor(HMONITOR hMonitor)
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000027{
28 if(hMonitor == xPRIMARY_MONITOR)
29 {
30 return &MONITOR_PrimaryMonitor;
31 }
32 else
33 {
34 return NULL;
35 }
36}
37
38/***********************************************************************
Patrik Stridvalle8c89481999-02-04 10:12:55 +000039 * MONITOR_Initialize
40 */
41void MONITOR_Initialize(MONITOR *pMonitor)
42{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000043 MONITOR_Driver->pInitialize(pMonitor);
Patrik Stridvalle8c89481999-02-04 10:12:55 +000044}
45
46/***********************************************************************
47 * MONITOR_Finalize
48 */
49void MONITOR_Finalize(MONITOR *pMonitor)
50{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000051 MONITOR_Driver->pFinalize(pMonitor);
52}
53
54/***********************************************************************
55 * MONITOR_IsSingleWindow
56 */
57BOOL MONITOR_IsSingleWindow(MONITOR *pMonitor)
58{
59 return MONITOR_Driver->pIsSingleWindow(pMonitor);
Patrik Stridvalle8c89481999-02-04 10:12:55 +000060}
61
62/***********************************************************************
63 * MONITOR_GetWidth
64 */
65int MONITOR_GetWidth(MONITOR *pMonitor)
66{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000067 return MONITOR_Driver->pGetWidth(pMonitor);
Patrik Stridvalle8c89481999-02-04 10:12:55 +000068}
69
70/***********************************************************************
71 * MONITOR_GetHeight
72 */
73int MONITOR_GetHeight(MONITOR *pMonitor)
74{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000075 return MONITOR_Driver->pGetHeight(pMonitor);
Patrik Stridvalle8c89481999-02-04 10:12:55 +000076}
77
78/***********************************************************************
79 * MONITOR_GetDepth
80 */
81int MONITOR_GetDepth(MONITOR *pMonitor)
82{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000083 return MONITOR_Driver->pGetDepth(pMonitor);
Patrik Stridvalle8c89481999-02-04 10:12:55 +000084}
85
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000086/***********************************************************************
87 * MONITOR_GetScreenSaveActive
88 */
89BOOL MONITOR_GetScreenSaveActive(MONITOR *pMonitor)
90{
91 return MONITOR_Driver->pGetScreenSaveActive(pMonitor);
92}
93
94/***********************************************************************
95 * MONITOR_SetScreenSaveActive
96 */
97void MONITOR_SetScreenSaveActive(MONITOR *pMonitor, BOOL bActivate)
98{
99 MONITOR_Driver->pSetScreenSaveActive(pMonitor, bActivate);
100}
101
102/***********************************************************************
103 * MONITOR_GetScreenSaveTimeout
104 */
105int MONITOR_GetScreenSaveTimeout(MONITOR *pMonitor)
106{
107 return MONITOR_Driver->pGetScreenSaveTimeout(pMonitor);
108}
109
110/***********************************************************************
111 * MONITOR_SetScreenSaveTimeout
112 */
113void MONITOR_SetScreenSaveTimeout(MONITOR *pMonitor, int nTimeout)
114{
115 MONITOR_Driver->pSetScreenSaveTimeout(pMonitor, nTimeout);
116}
117
118
Patrik Stridvalle8c89481999-02-04 10:12:55 +0000119/**********************************************************************/
120
Alexandre Julliarda3960291999-02-26 11:11:13 +0000121HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000122{
123 if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
124 ((ptScreenCoords.x >= 0) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000125 (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000126 (ptScreenCoords.y >= 0) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000127 (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000128 {
129 return xPRIMARY_MONITOR;
130 }
131 return NULL;
132}
133
Alexandre Julliarda3960291999-02-26 11:11:13 +0000134HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000135{
136 if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
137 ((lprcScreenCoords->right > 0) &&
138 (lprcScreenCoords->bottom > 0) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000139 (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
140 (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000141 {
142 return xPRIMARY_MONITOR;
143 }
144 return NULL;
145}
146
Alexandre Julliarda3960291999-02-26 11:11:13 +0000147HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000148{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000149 WINDOWPLACEMENT wp;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000150
151 if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
152 return xPRIMARY_MONITOR;
153
Alexandre Julliarda3960291999-02-26 11:11:13 +0000154 if (IsIconic(hWnd) ?
155 GetWindowPlacement(hWnd, &wp) :
156 GetWindowRect(hWnd, &wp.rcNormalPosition)) {
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000157
158 return MonitorFromRect(&wp.rcNormalPosition, dwFlags);
159 }
160
161 return NULL;
162}
163
Alexandre Julliarda3960291999-02-26 11:11:13 +0000164BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000165{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000166 RECT rcWork;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000167
168 if ((hMonitor == xPRIMARY_MONITOR) &&
169 lpMonitorInfo &&
170 (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000171 SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000172 {
173 lpMonitorInfo->rcMonitor.left = 0;
174 lpMonitorInfo->rcMonitor.top = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000175 lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
176 lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000177 lpMonitorInfo->rcWork = rcWork;
178 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
179
Alexandre Julliarda3960291999-02-26 11:11:13 +0000180 if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXA))
181 lstrcpyA(((MONITORINFOEXA*)lpMonitorInfo)->szDevice, "DISPLAY");
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000182
183 return TRUE;
184 }
185
186 return FALSE;
187}
188
Alexandre Julliarda3960291999-02-26 11:11:13 +0000189BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000190{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000191 RECT rcWork;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000192
193 if ((hMonitor == xPRIMARY_MONITOR) &&
194 lpMonitorInfo &&
195 (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000196 SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000197 {
198 lpMonitorInfo->rcMonitor.left = 0;
199 lpMonitorInfo->rcMonitor.top = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000200 lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
201 lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000202 lpMonitorInfo->rcWork = rcWork;
203 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
204
Alexandre Julliarda3960291999-02-26 11:11:13 +0000205 if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
206 lstrcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, (LPCWSTR)"D\0I\0S\0P\0L\0A\0Y\0\0");
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000207
208 return TRUE;
209 }
210
211 return FALSE;
212}
213
Alexandre Julliarda3960291999-02-26 11:11:13 +0000214BOOL WINAPI EnumDisplayMonitors(
215 HDC hdcOptionalForPainting,
216 LPRECT lprcEnumMonitorsThatIntersect,
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000217 MONITORENUMPROC lpfnEnumProc,
218 LPARAM dwData)
219{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000220 RECT rcLimit;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000221
222 if (!lpfnEnumProc)
223 return FALSE;
224
225 rcLimit.left = 0;
226 rcLimit.top = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000227 rcLimit.right = GetSystemMetrics(SM_CXSCREEN);
228 rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000229
230 if (hdcOptionalForPainting)
231 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000232 RECT rcClip;
233 POINT ptOrg;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000234
Alexandre Julliarda3960291999-02-26 11:11:13 +0000235 switch (GetClipBox(hdcOptionalForPainting, &rcClip))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000236 {
237 default:
238 if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
239 return FALSE;
240
Alexandre Julliarda3960291999-02-26 11:11:13 +0000241 OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
242 if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000243 (!lprcEnumMonitorsThatIntersect ||
Alexandre Julliarda3960291999-02-26 11:11:13 +0000244 IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000245
246 break;
247 }
Marcus Meissner73458b01998-12-26 12:54:29 +0000248 /*fall thru */
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000249 case NULLREGION:
250 return TRUE;
251 case ERROR:
252 return FALSE;
253 }
254 } else {
255 if ( lprcEnumMonitorsThatIntersect &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000256 !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000257
258 return TRUE;
259 }
260 }
261
262 return lpfnEnumProc(
263 xPRIMARY_MONITOR,
264 hdcOptionalForPainting,
265 &rcLimit,
266 dwData);
267}