blob: 895fe066d18053d5cd59c942ce99fddfa8c9bd09 [file] [log] [blame]
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001/*
2 * Multimonitor APIs
3 *
4 * Copyright 1998 Turchanov Sergey
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00005 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000019 */
20
James Juranf4d5fef2001-01-26 20:43:40 +000021#include <string.h>
Jeremy Whited3e22d92000-02-10 19:03:02 +000022#include "windef.h"
23#include "wingdi.h"
Marcus Meissner61afa331999-02-22 10:16:00 +000024#include "winbase.h"
25#include "winuser.h"
Alexandre Julliardc7e7df82000-08-14 14:41:19 +000026#include "wine/unicode.h"
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000027
28/**********************************************************************/
29
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000030#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
31
Patrik Stridvall2d6457c2000-03-28 20:22:59 +000032/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +000033 * MonitorFromPoint (USER32.@)
Patrik Stridvall2d6457c2000-03-28 20:22:59 +000034 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000035HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000036{
37 if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
38 ((ptScreenCoords.x >= 0) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +000039 (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000040 (ptScreenCoords.y >= 0) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +000041 (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000042 {
43 return xPRIMARY_MONITOR;
44 }
Eric Pouech12222f02000-04-29 14:29:41 +000045 return (HMONITOR)0;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000046}
47
Patrik Stridvall2d6457c2000-03-28 20:22:59 +000048/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +000049 * MonitorFromRect (USER32.@)
Patrik Stridvall2d6457c2000-03-28 20:22:59 +000050 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000051HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000052{
53 if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
54 ((lprcScreenCoords->right > 0) &&
55 (lprcScreenCoords->bottom > 0) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +000056 (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
57 (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000058 {
59 return xPRIMARY_MONITOR;
60 }
Eric Pouech12222f02000-04-29 14:29:41 +000061 return (HMONITOR)0;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000062}
63
Patrik Stridvall2d6457c2000-03-28 20:22:59 +000064/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +000065 * MonitorFromWindow (USER32.@)
Patrik Stridvall2d6457c2000-03-28 20:22:59 +000066 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000067HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000068{
Alexandre Julliarda3960291999-02-26 11:11:13 +000069 WINDOWPLACEMENT wp;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000070
71 if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
72 return xPRIMARY_MONITOR;
73
Vincent Béron9a624912002-05-31 23:06:46 +000074 if (IsIconic(hWnd) ?
75 GetWindowPlacement(hWnd, &wp) :
Alexandre Julliarda3960291999-02-26 11:11:13 +000076 GetWindowRect(hWnd, &wp.rcNormalPosition)) {
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000077
78 return MonitorFromRect(&wp.rcNormalPosition, dwFlags);
79 }
80
Eric Pouech12222f02000-04-29 14:29:41 +000081 return (HMONITOR)0;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000082}
83
Patrik Stridvall2d6457c2000-03-28 20:22:59 +000084/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +000085 * GetMonitorInfoA (USER32.@)
Patrik Stridvall2d6457c2000-03-28 20:22:59 +000086 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000087BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000088{
Alexandre Julliarda3960291999-02-26 11:11:13 +000089 RECT rcWork;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000090
91 if ((hMonitor == xPRIMARY_MONITOR) &&
92 lpMonitorInfo &&
93 (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +000094 SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000095 {
Alexandre Julliard646c5622000-07-31 23:32:47 +000096 SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
97 GetSystemMetrics(SM_CXSCREEN),
98 GetSystemMetrics(SM_CYSCREEN) );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000099 lpMonitorInfo->rcWork = rcWork;
100 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
Vincent Béron9a624912002-05-31 23:06:46 +0000101
Alexandre Julliarda3960291999-02-26 11:11:13 +0000102 if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXA))
Alexandre Julliardc7e7df82000-08-14 14:41:19 +0000103 strcpy(((MONITORINFOEXA*)lpMonitorInfo)->szDevice, "DISPLAY");
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000104
105 return TRUE;
106 }
107
108 return FALSE;
109}
110
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000111/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000112 * GetMonitorInfoW (USER32.@)
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000113 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000114BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000115{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000116 RECT rcWork;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000117
118 if ((hMonitor == xPRIMARY_MONITOR) &&
119 lpMonitorInfo &&
120 (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000121 SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000122 {
Alexandre Julliard646c5622000-07-31 23:32:47 +0000123 SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
124 GetSystemMetrics(SM_CXSCREEN),
125 GetSystemMetrics(SM_CYSCREEN) );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000126 lpMonitorInfo->rcWork = rcWork;
127 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
128
Alexandre Julliarda3960291999-02-26 11:11:13 +0000129 if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
Alexandre Julliardc7e7df82000-08-14 14:41:19 +0000130 strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, (LPCWSTR)"D\0I\0S\0P\0L\0A\0Y\0\0");
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000131
132 return TRUE;
133 }
134
135 return FALSE;
136}
137
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000138/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000139 * EnumDisplayMonitors (USER32.@)
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000140 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000141BOOL WINAPI EnumDisplayMonitors(
142 HDC hdcOptionalForPainting,
143 LPRECT lprcEnumMonitorsThatIntersect,
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000144 MONITORENUMPROC lpfnEnumProc,
145 LPARAM dwData)
146{
Alexandre Julliard646c5622000-07-31 23:32:47 +0000147 RECT rcLimit;
148 SetRect( &rcLimit, 0, 0, GetSystemMetrics(SM_CXSCREEN),
149 GetSystemMetrics(SM_CYSCREEN) );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000150
151 if (!lpfnEnumProc)
152 return FALSE;
153
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000154 if (hdcOptionalForPainting)
155 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000156 RECT rcClip;
157 POINT ptOrg;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000158
Alexandre Julliarda3960291999-02-26 11:11:13 +0000159 switch (GetClipBox(hdcOptionalForPainting, &rcClip))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000160 {
161 default:
162 if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
163 return FALSE;
164
Alexandre Julliarda3960291999-02-26 11:11:13 +0000165 OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
166 if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000167 (!lprcEnumMonitorsThatIntersect ||
Alexandre Julliarda3960291999-02-26 11:11:13 +0000168 IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000169
170 break;
171 }
Francois Gouget588ff372001-08-21 17:07:17 +0000172 /* fall through */
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000173 case NULLREGION:
174 return TRUE;
175 case ERROR:
176 return FALSE;
177 }
178 } else {
179 if ( lprcEnumMonitorsThatIntersect &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000180 !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000181
182 return TRUE;
183 }
184 }
185
186 return lpfnEnumProc(
187 xPRIMARY_MONITOR,
188 hdcOptionalForPainting,
189 &rcLimit,
190 dwData);
191}