- Make MTA dynamically allocated so that proxies and other resources
[wine] / windows / multimon.c
1 /*
2  * Multimonitor APIs
3  *
4  * Copyright 1998 Turchanov Sergey
5  *
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
19  */
20
21 #include <stdarg.h>
22 #include <string.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "wine/unicode.h"
28
29 /**********************************************************************/
30
31 #define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
32
33 /***********************************************************************
34  *              MonitorFromPoint (USER32.@)
35  */
36 HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
37 {
38     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
39         ((ptScreenCoords.x >= 0) &&
40         (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
41         (ptScreenCoords.y >= 0) &&
42         (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
43     {
44         return xPRIMARY_MONITOR;
45     }
46     return NULL;
47 }
48
49 /***********************************************************************
50  *              MonitorFromRect (USER32.@)
51  */
52 HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
53 {
54     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
55         ((lprcScreenCoords->right > 0) &&
56         (lprcScreenCoords->bottom > 0) &&
57         (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
58         (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
59     {
60         return xPRIMARY_MONITOR;
61     }
62     return NULL;
63 }
64
65 /***********************************************************************
66  *              MonitorFromWindow (USER32.@)
67  */
68 HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
69 {
70     WINDOWPLACEMENT wp;
71
72     if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
73         return xPRIMARY_MONITOR;
74
75     if (IsIconic(hWnd) ?
76             GetWindowPlacement(hWnd, &wp) :
77             GetWindowRect(hWnd, &wp.rcNormalPosition)) {
78
79         return MonitorFromRect(&wp.rcNormalPosition, dwFlags);
80     }
81
82     return NULL;
83 }
84
85 /***********************************************************************
86  *              GetMonitorInfoA (USER32.@)
87  */
88 BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
89 {
90     RECT rcWork;
91
92     if ((hMonitor == xPRIMARY_MONITOR) &&
93         lpMonitorInfo &&
94         (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
95         SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
96     {
97         SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
98                  GetSystemMetrics(SM_CXSCREEN),
99                  GetSystemMetrics(SM_CYSCREEN) );
100         lpMonitorInfo->rcWork = rcWork;
101         lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
102
103         if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXA))
104             strcpy(((MONITORINFOEXA*)lpMonitorInfo)->szDevice, "DISPLAY");
105
106         return TRUE;
107     }
108
109     return FALSE;
110 }
111
112 /***********************************************************************
113  *              GetMonitorInfoW (USER32.@)
114  */
115 BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
116 {
117     static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0};
118     RECT rcWork;
119
120     if ((hMonitor == xPRIMARY_MONITOR) &&
121         lpMonitorInfo &&
122         (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
123         SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0))
124     {
125         SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
126                  GetSystemMetrics(SM_CXSCREEN),
127                  GetSystemMetrics(SM_CYSCREEN) );
128         lpMonitorInfo->rcWork = rcWork;
129         lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
130
131         if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
132             strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, displayW);
133
134         return TRUE;
135     }
136
137     return FALSE;
138 }
139
140 /***********************************************************************
141  *              EnumDisplayMonitors (USER32.@)
142  */
143 BOOL WINAPI EnumDisplayMonitors(
144         HDC             hdcOptionalForPainting,
145         LPRECT         lprcEnumMonitorsThatIntersect,
146         MONITORENUMPROC lpfnEnumProc,
147         LPARAM          dwData)
148 {
149     RECT rcLimit;
150     SetRect( &rcLimit, 0, 0, GetSystemMetrics(SM_CXSCREEN),
151              GetSystemMetrics(SM_CYSCREEN) );
152
153     if (!lpfnEnumProc)
154         return FALSE;
155
156     if (hdcOptionalForPainting)
157     {
158         RECT    rcClip;
159         POINT   ptOrg;
160
161         switch (GetClipBox(hdcOptionalForPainting, &rcClip))
162         {
163         default:
164             if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
165                 return FALSE;
166
167             OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
168             if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
169                 (!lprcEnumMonitorsThatIntersect ||
170                      IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
171
172                 break;
173             }
174             /* fall through */
175         case NULLREGION:
176              return TRUE;
177         case ERROR:
178              return FALSE;
179         }
180     } else {
181         if (    lprcEnumMonitorsThatIntersect &&
182                 !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
183
184             return TRUE;
185         }
186     }
187
188     return lpfnEnumProc(
189             xPRIMARY_MONITOR,
190             hdcOptionalForPainting,
191             &rcLimit,
192             dwData);
193 }