Moved msacmdrv.h to include directory to avoid inter-dll header
[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     RECT rcWork;
118
119     if ((hMonitor == xPRIMARY_MONITOR) &&
120         lpMonitorInfo &&
121         (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
122         SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0))
123     {
124         SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
125                  GetSystemMetrics(SM_CXSCREEN),
126                  GetSystemMetrics(SM_CYSCREEN) );
127         lpMonitorInfo->rcWork = rcWork;
128         lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
129
130         if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
131             strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, (LPCWSTR)"D\0I\0S\0P\0L\0A\0Y\0\0");
132
133         return TRUE;
134     }
135
136     return FALSE;
137 }
138
139 /***********************************************************************
140  *              EnumDisplayMonitors (USER32.@)
141  */
142 BOOL WINAPI EnumDisplayMonitors(
143         HDC             hdcOptionalForPainting,
144         LPRECT         lprcEnumMonitorsThatIntersect,
145         MONITORENUMPROC lpfnEnumProc,
146         LPARAM          dwData)
147 {
148     RECT rcLimit;
149     SetRect( &rcLimit, 0, 0, GetSystemMetrics(SM_CXSCREEN),
150              GetSystemMetrics(SM_CYSCREEN) );
151
152     if (!lpfnEnumProc)
153         return FALSE;
154
155     if (hdcOptionalForPainting)
156     {
157         RECT    rcClip;
158         POINT   ptOrg;
159
160         switch (GetClipBox(hdcOptionalForPainting, &rcClip))
161         {
162         default:
163             if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
164                 return FALSE;
165
166             OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
167             if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
168                 (!lprcEnumMonitorsThatIntersect ||
169                      IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
170
171                 break;
172             }
173             /* fall through */
174         case NULLREGION:
175              return TRUE;
176         case ERROR:
177              return FALSE;
178         }
179     } else {
180         if (    lprcEnumMonitorsThatIntersect &&
181                 !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
182
183             return TRUE;
184         }
185     }
186
187     return lpfnEnumProc(
188             xPRIMARY_MONITOR,
189             hdcOptionalForPainting,
190             &rcLimit,
191             dwData);
192 }