Adapted to the interface/implementation separation.
[wine] / windows / multimon.c
1 /*
2  * Multimonitor APIs
3  *
4  * Copyright 1998 Turchanov Sergey
5  */
6
7 #include "winbase.h"
8 #include "winuser.h"
9 #include "monitor.h"
10
11 /**********************************************************************/
12
13 #define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
14
15 MONITOR MONITOR_PrimaryMonitor;
16
17 /***********************************************************************
18  *              MONITOR_Initialize
19  */
20 void MONITOR_Initialize(MONITOR *pMonitor)
21 {
22   pMonitor->pDriver->pInitialize(pMonitor);
23 }
24
25 /***********************************************************************
26  *              MONITOR_Finalize
27  */
28 void MONITOR_Finalize(MONITOR *pMonitor)
29 {
30   pMonitor->pDriver->pFinalize(pMonitor);
31 }
32
33 /***********************************************************************
34  *              MONITOR_GetWidth
35  */
36 int MONITOR_GetWidth(MONITOR *pMonitor)
37 {
38   return pMonitor->pDriver->pGetWidth(pMonitor);
39 }
40
41 /***********************************************************************
42  *              MONITOR_GetHeight
43  */
44 int MONITOR_GetHeight(MONITOR *pMonitor)
45 {
46   return pMonitor->pDriver->pGetHeight(pMonitor);
47 }
48
49 /***********************************************************************
50  *              MONITOR_GetDepth
51  */
52 int MONITOR_GetDepth(MONITOR *pMonitor)
53 {
54   return pMonitor->pDriver->pGetDepth(pMonitor);
55 }
56
57 /**********************************************************************/
58
59 HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
60 {
61     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
62         ((ptScreenCoords.x >= 0) &&
63         (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
64         (ptScreenCoords.y >= 0) &&
65         (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
66     {
67         return xPRIMARY_MONITOR;
68     }
69         return NULL;
70 }
71
72 HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
73 {
74     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
75         ((lprcScreenCoords->right > 0) &&
76         (lprcScreenCoords->bottom > 0) &&
77         (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
78         (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
79     {
80         return xPRIMARY_MONITOR;
81     }
82     return NULL;
83 }
84
85 HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
86 {
87     WINDOWPLACEMENT wp;
88
89     if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
90         return xPRIMARY_MONITOR;
91
92     if (IsIconic(hWnd) ? 
93             GetWindowPlacement(hWnd, &wp) : 
94             GetWindowRect(hWnd, &wp.rcNormalPosition)) {
95
96         return MonitorFromRect(&wp.rcNormalPosition, dwFlags);
97     }
98
99     return NULL;
100 }
101
102 BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
103 {
104     RECT rcWork;
105
106     if ((hMonitor == xPRIMARY_MONITOR) &&
107         lpMonitorInfo &&
108         (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
109         SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
110     {
111         lpMonitorInfo->rcMonitor.left = 0;
112         lpMonitorInfo->rcMonitor.top  = 0;
113         lpMonitorInfo->rcMonitor.right  = GetSystemMetrics(SM_CXSCREEN);
114         lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
115         lpMonitorInfo->rcWork = rcWork;
116         lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
117         
118         if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXA))
119             lstrcpyA(((MONITORINFOEXA*)lpMonitorInfo)->szDevice, "DISPLAY");
120
121         return TRUE;
122     }
123
124     return FALSE;
125 }
126
127 BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
128 {
129     RECT rcWork;
130
131     if ((hMonitor == xPRIMARY_MONITOR) &&
132         lpMonitorInfo &&
133         (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
134         SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0))
135     {
136         lpMonitorInfo->rcMonitor.left = 0;
137         lpMonitorInfo->rcMonitor.top  = 0;
138         lpMonitorInfo->rcMonitor.right  = GetSystemMetrics(SM_CXSCREEN);
139         lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
140         lpMonitorInfo->rcWork = rcWork;
141         lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
142
143         if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
144             lstrcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, (LPCWSTR)"D\0I\0S\0P\0L\0A\0Y\0\0");
145
146         return TRUE;
147     }
148
149     return FALSE;
150 }
151
152 BOOL WINAPI EnumDisplayMonitors(
153         HDC             hdcOptionalForPainting,
154         LPRECT         lprcEnumMonitorsThatIntersect,
155         MONITORENUMPROC lpfnEnumProc,
156         LPARAM          dwData)
157 {
158     RECT rcLimit;
159
160     if (!lpfnEnumProc)
161         return FALSE;
162
163     rcLimit.left   = 0;
164     rcLimit.top    = 0;
165     rcLimit.right  = GetSystemMetrics(SM_CXSCREEN);
166     rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
167
168     if (hdcOptionalForPainting)
169     {
170         RECT    rcClip;
171         POINT   ptOrg;
172
173         switch (GetClipBox(hdcOptionalForPainting, &rcClip))
174         {
175         default:
176             if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
177                 return FALSE;
178
179             OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
180             if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
181                 (!lprcEnumMonitorsThatIntersect ||
182                      IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
183
184                 break;
185             }
186             /*fall thru */
187         case NULLREGION:
188              return TRUE;
189         case ERROR:
190              return FALSE;
191         }
192     } else {
193         if (    lprcEnumMonitorsThatIntersect &&
194                 !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
195
196             return TRUE;
197         }
198     }
199
200     return lpfnEnumProc(
201             xPRIMARY_MONITOR,
202             hdcOptionalForPainting,
203             &rcLimit,
204             dwData);
205 }