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