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