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