Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Multimonitor APIs |
| 3 | * |
| 4 | * Copyright 1998 Turchanov Sergey |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 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 |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 19 | */ |
| 20 | |
James Juran | f4d5fef | 2001-01-26 20:43:40 +0000 | [diff] [blame] | 21 | #include <string.h> |
Jeremy White | d3e22d9 | 2000-02-10 19:03:02 +0000 | [diff] [blame] | 22 | #include "windef.h" |
| 23 | #include "wingdi.h" |
Marcus Meissner | 61afa33 | 1999-02-22 10:16:00 +0000 | [diff] [blame] | 24 | #include "winbase.h" |
| 25 | #include "winuser.h" |
Alexandre Julliard | c7e7df8 | 2000-08-14 14:41:19 +0000 | [diff] [blame] | 26 | #include "wine/unicode.h" |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame] | 27 | |
| 28 | /**********************************************************************/ |
| 29 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 30 | #define xPRIMARY_MONITOR ((HMONITOR)0x12340042) |
| 31 | |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 32 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 33 | * MonitorFromPoint (USER32.@) |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 34 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 35 | HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 36 | { |
| 37 | if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) || |
| 38 | ((ptScreenCoords.x >= 0) && |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 39 | (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) && |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 40 | (ptScreenCoords.y >= 0) && |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 41 | (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN)))) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 42 | { |
| 43 | return xPRIMARY_MONITOR; |
| 44 | } |
Eric Pouech | 12222f0 | 2000-04-29 14:29:41 +0000 | [diff] [blame] | 45 | return (HMONITOR)0; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 46 | } |
| 47 | |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 48 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 49 | * MonitorFromRect (USER32.@) |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 50 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 51 | HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 52 | { |
| 53 | if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) || |
| 54 | ((lprcScreenCoords->right > 0) && |
| 55 | (lprcScreenCoords->bottom > 0) && |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 56 | (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) && |
| 57 | (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN)))) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 58 | { |
| 59 | return xPRIMARY_MONITOR; |
| 60 | } |
Eric Pouech | 12222f0 | 2000-04-29 14:29:41 +0000 | [diff] [blame] | 61 | return (HMONITOR)0; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 62 | } |
| 63 | |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 64 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 65 | * MonitorFromWindow (USER32.@) |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 66 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 67 | HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 68 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 69 | WINDOWPLACEMENT wp; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 70 | |
| 71 | if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) |
| 72 | return xPRIMARY_MONITOR; |
| 73 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 74 | if (IsIconic(hWnd) ? |
| 75 | GetWindowPlacement(hWnd, &wp) : |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 76 | GetWindowRect(hWnd, &wp.rcNormalPosition)) { |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 77 | |
| 78 | return MonitorFromRect(&wp.rcNormalPosition, dwFlags); |
| 79 | } |
| 80 | |
Eric Pouech | 12222f0 | 2000-04-29 14:29:41 +0000 | [diff] [blame] | 81 | return (HMONITOR)0; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 82 | } |
| 83 | |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 84 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 85 | * GetMonitorInfoA (USER32.@) |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 86 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 87 | BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 88 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 89 | RECT rcWork; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 90 | |
| 91 | if ((hMonitor == xPRIMARY_MONITOR) && |
| 92 | lpMonitorInfo && |
| 93 | (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) && |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 94 | SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0)) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 95 | { |
Alexandre Julliard | 646c562 | 2000-07-31 23:32:47 +0000 | [diff] [blame] | 96 | SetRect( &lpMonitorInfo->rcMonitor, 0, 0, |
| 97 | GetSystemMetrics(SM_CXSCREEN), |
| 98 | GetSystemMetrics(SM_CYSCREEN) ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 99 | lpMonitorInfo->rcWork = rcWork; |
| 100 | lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 101 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 102 | if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXA)) |
Alexandre Julliard | c7e7df8 | 2000-08-14 14:41:19 +0000 | [diff] [blame] | 103 | strcpy(((MONITORINFOEXA*)lpMonitorInfo)->szDevice, "DISPLAY"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 104 | |
| 105 | return TRUE; |
| 106 | } |
| 107 | |
| 108 | return FALSE; |
| 109 | } |
| 110 | |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 111 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 112 | * GetMonitorInfoW (USER32.@) |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 113 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 114 | BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 115 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 116 | RECT rcWork; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 117 | |
| 118 | if ((hMonitor == xPRIMARY_MONITOR) && |
| 119 | lpMonitorInfo && |
| 120 | (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) && |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 121 | SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0)) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 122 | { |
Alexandre Julliard | 646c562 | 2000-07-31 23:32:47 +0000 | [diff] [blame] | 123 | SetRect( &lpMonitorInfo->rcMonitor, 0, 0, |
| 124 | GetSystemMetrics(SM_CXSCREEN), |
| 125 | GetSystemMetrics(SM_CYSCREEN) ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 126 | lpMonitorInfo->rcWork = rcWork; |
| 127 | lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY; |
| 128 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 129 | if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW)) |
Alexandre Julliard | c7e7df8 | 2000-08-14 14:41:19 +0000 | [diff] [blame] | 130 | strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, (LPCWSTR)"D\0I\0S\0P\0L\0A\0Y\0\0"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 131 | |
| 132 | return TRUE; |
| 133 | } |
| 134 | |
| 135 | return FALSE; |
| 136 | } |
| 137 | |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 138 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 139 | * EnumDisplayMonitors (USER32.@) |
Patrik Stridvall | 2d6457c | 2000-03-28 20:22:59 +0000 | [diff] [blame] | 140 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 141 | BOOL WINAPI EnumDisplayMonitors( |
| 142 | HDC hdcOptionalForPainting, |
| 143 | LPRECT lprcEnumMonitorsThatIntersect, |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 144 | MONITORENUMPROC lpfnEnumProc, |
| 145 | LPARAM dwData) |
| 146 | { |
Alexandre Julliard | 646c562 | 2000-07-31 23:32:47 +0000 | [diff] [blame] | 147 | RECT rcLimit; |
| 148 | SetRect( &rcLimit, 0, 0, GetSystemMetrics(SM_CXSCREEN), |
| 149 | GetSystemMetrics(SM_CYSCREEN) ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 150 | |
| 151 | if (!lpfnEnumProc) |
| 152 | return FALSE; |
| 153 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 154 | if (hdcOptionalForPainting) |
| 155 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 156 | RECT rcClip; |
| 157 | POINT ptOrg; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 158 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 159 | switch (GetClipBox(hdcOptionalForPainting, &rcClip)) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 160 | { |
| 161 | default: |
| 162 | if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg)) |
| 163 | return FALSE; |
| 164 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 165 | OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y); |
| 166 | if (IntersectRect(&rcLimit, &rcLimit, &rcClip) && |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 167 | (!lprcEnumMonitorsThatIntersect || |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 168 | IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) { |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 169 | |
| 170 | break; |
| 171 | } |
Francois Gouget | 588ff37 | 2001-08-21 17:07:17 +0000 | [diff] [blame] | 172 | /* fall through */ |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 173 | case NULLREGION: |
| 174 | return TRUE; |
| 175 | case ERROR: |
| 176 | return FALSE; |
| 177 | } |
| 178 | } else { |
| 179 | if ( lprcEnumMonitorsThatIntersect && |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 180 | !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) { |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 181 | |
| 182 | return TRUE; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | return lpfnEnumProc( |
| 187 | xPRIMARY_MONITOR, |
| 188 | hdcOptionalForPainting, |
| 189 | &rcLimit, |
| 190 | dwData); |
| 191 | } |