Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: ui/gfx/screen_win.cc

Issue 1639623003: ScreenWin Testability and Restructuring (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sync + VS2015 Friendly - struct -> class to maintain immutability Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gfx/screen_win.h ('k') | ui/gfx/screen_win_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/screen_win.h" 5 #include "ui/gfx/screen_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <stdint.h>
9 8
10 #include "base/bind.h" 9 #include "base/bind.h"
11 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
12 #include "base/hash.h"
13 #include "base/logging.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/win/win_util.h"
16 #include "ui/gfx/display.h" 11 #include "ui/gfx/display.h"
12 #include "ui/gfx/geometry/point.h"
13 #include "ui/gfx/geometry/rect.h"
14 #include "ui/gfx/win/display_info.h"
17 #include "ui/gfx/win/dpi.h" 15 #include "ui/gfx/win/dpi.h"
16 #include "ui/gfx/win/screen_win_display.h"
18 17
19 namespace { 18 namespace {
20 19
21 MONITORINFOEX GetMonitorInfoForMonitor(HMONITOR monitor) { 20 std::vector<gfx::win::ScreenWinDisplay> DisplayInfosToScreenWinDisplays(
22 MONITORINFOEX monitor_info; 21 const std::vector<gfx::win::DisplayInfo>& display_infos) {
23 ZeroMemory(&monitor_info, sizeof(MONITORINFOEX)); 22 std::vector<gfx::win::ScreenWinDisplay> screen_win_displays;
24 monitor_info.cbSize = sizeof(monitor_info); 23 for (const auto& display_info : display_infos)
25 GetMonitorInfo(monitor, &monitor_info); 24 screen_win_displays.push_back(gfx::win::ScreenWinDisplay(display_info));
26 return monitor_info; 25
26 return screen_win_displays;
27 } 27 }
28 28
29 gfx::Display GetDisplay(const MONITORINFOEX& monitor_info) { 29 std::vector<gfx::Display> ScreenWinDisplaysToDisplays(
30 int64_t id = 30 const std::vector<gfx::win::ScreenWinDisplay>& screen_win_displays) {
31 static_cast<int64_t>(base::Hash(base::WideToUTF8(monitor_info.szDevice))); 31 std::vector<gfx::Display> displays;
32 gfx::Rect bounds = gfx::Rect(monitor_info.rcMonitor); 32 for (const auto& screen_win_display : screen_win_displays)
33 gfx::Display display(id); 33 displays.push_back(screen_win_display.display());
34 display.set_bounds(gfx::win::ScreenToDIPRect(bounds));
35 display.set_work_area(
36 gfx::win::ScreenToDIPRect(gfx::Rect(monitor_info.rcWork)));
37 display.SetScaleAndBounds(gfx::GetDPIScale(), bounds);
38 34
39 DEVMODE mode; 35 return displays;
40 memset(&mode, 0, sizeof(DEVMODE)); 36 }
41 mode.dmSize = sizeof(DEVMODE);
42 mode.dmDriverExtra = 0;
43 if (EnumDisplaySettings(monitor_info.szDevice,
44 ENUM_CURRENT_SETTINGS,
45 &mode)) {
46 switch (mode.dmDisplayOrientation) {
47 case DMDO_DEFAULT:
48 display.set_rotation(gfx::Display::ROTATE_0);
49 break;
50 case DMDO_90:
51 display.set_rotation(gfx::Display::ROTATE_90);
52 break;
53 case DMDO_180:
54 display.set_rotation(gfx::Display::ROTATE_180);
55 break;
56 case DMDO_270:
57 display.set_rotation(gfx::Display::ROTATE_270);
58 break;
59 default:
60 NOTREACHED();
61 }
62 }
63 37
64 return display; 38 MONITORINFOEX MonitorInfoFromHMONITOR(HMONITOR monitor) {
39 MONITORINFOEX monitor_info;
40 ::ZeroMemory(&monitor_info, sizeof(monitor_info));
41 monitor_info.cbSize = sizeof(monitor_info);
42 ::GetMonitorInfo(monitor, &monitor_info);
43 return monitor_info;
65 } 44 }
66 45
67 BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor, 46 BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor,
68 HDC hdc, 47 HDC hdc,
69 LPRECT rect, 48 LPRECT rect,
70 LPARAM data) { 49 LPARAM data) {
71 std::vector<gfx::Display>* all_displays = 50 std::vector<gfx::win::DisplayInfo>* display_infos =
72 reinterpret_cast<std::vector<gfx::Display>*>(data); 51 reinterpret_cast<std::vector<gfx::win::DisplayInfo>*>(data);
73 DCHECK(all_displays); 52 DCHECK(display_infos);
74 53 display_infos->push_back(
75 MONITORINFOEX monitor_info = GetMonitorInfoForMonitor(monitor); 54 gfx::win::DisplayInfo(MonitorInfoFromHMONITOR(monitor),
76 gfx::Display display = GetDisplay(monitor_info); 55 gfx::GetDPIScale()));
77 all_displays->push_back(display);
78 return TRUE; 56 return TRUE;
79 } 57 }
80 58
81 std::vector<gfx::Display> GetDisplays() { 59 std::vector<gfx::win::DisplayInfo> GetDisplayInfosFromSystem() {
82 std::vector<gfx::Display> displays; 60 std::vector<gfx::win::DisplayInfo> display_infos;
83 EnumDisplayMonitors(NULL, NULL, EnumMonitorCallback, 61 EnumDisplayMonitors(nullptr, nullptr, EnumMonitorCallback,
84 reinterpret_cast<LPARAM>(&displays)); 62 reinterpret_cast<LPARAM>(&display_infos));
85 return displays; 63 DCHECK_EQ(static_cast<size_t>(::GetSystemMetrics(SM_CMONITORS)),
64 display_infos.size());
65 return display_infos;
86 } 66 }
87 67
88 } // namespace 68 } // namespace
89 69
90 namespace gfx { 70 namespace gfx {
91 71
92 ScreenWin::ScreenWin() 72 ScreenWin::ScreenWin() {
93 : singleton_hwnd_observer_(new SingletonHwndObserver( 73 Initialize();
94 base::Bind(&ScreenWin::OnWndProc, base::Unretained(this)))),
95 displays_(GetDisplays()) {
96 } 74 }
97 75
98 ScreenWin::~ScreenWin() {} 76 ScreenWin::~ScreenWin() = default;
99 77
100 HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const { 78 HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const {
101 NOTREACHED(); 79 NOTREACHED();
102 return NULL; 80 return nullptr;
103 } 81 }
104 82
105 NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const { 83 NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const {
106 NOTREACHED(); 84 NOTREACHED();
107 return NULL; 85 return nullptr;
108 } 86 }
109 87
110 gfx::Point ScreenWin::GetCursorScreenPoint() { 88 gfx::Point ScreenWin::GetCursorScreenPoint() {
111 POINT pt; 89 POINT pt;
112 GetCursorPos(&pt); 90 ::GetCursorPos(&pt);
113 gfx::Point cursor_pos_pixels(pt); 91 gfx::Point cursor_pos_pixels(pt);
114 return gfx::win::ScreenToDIPPoint(cursor_pos_pixels); 92 return gfx::win::ScreenToDIPPoint(cursor_pos_pixels);
115 } 93 }
116 94
117 gfx::NativeWindow ScreenWin::GetWindowUnderCursor() { 95 gfx::NativeWindow ScreenWin::GetWindowUnderCursor() {
118 POINT cursor_loc; 96 POINT cursor_loc;
119 HWND hwnd = GetCursorPos(&cursor_loc) ? WindowFromPoint(cursor_loc) : NULL; 97 HWND hwnd =
98 ::GetCursorPos(&cursor_loc) ? ::WindowFromPoint(cursor_loc) : nullptr;
120 return GetNativeWindowFromHWND(hwnd); 99 return GetNativeWindowFromHWND(hwnd);
121 } 100 }
122 101
123 gfx::NativeWindow ScreenWin::GetWindowAtScreenPoint(const gfx::Point& point) { 102 gfx::NativeWindow ScreenWin::GetWindowAtScreenPoint(const gfx::Point& point) {
124 gfx::Point point_in_pixels = gfx::win::DIPToScreenPoint(point); 103 gfx::Point point_in_pixels = gfx::win::DIPToScreenPoint(point);
125 return GetNativeWindowFromHWND(WindowFromPoint(point_in_pixels.ToPOINT())); 104 return GetNativeWindowFromHWND(WindowFromPoint(point_in_pixels.ToPOINT()));
126 } 105 }
127 106
128 int ScreenWin::GetNumDisplays() const { 107 int ScreenWin::GetNumDisplays() const {
129 return GetSystemMetrics(SM_CMONITORS); 108 return static_cast<int>(screen_win_displays_.size());
130 } 109 }
131 110
132 std::vector<gfx::Display> ScreenWin::GetAllDisplays() const { 111 std::vector<gfx::Display> ScreenWin::GetAllDisplays() const {
133 return displays_; 112 return ScreenWinDisplaysToDisplays(screen_win_displays_);
134 } 113 }
135 114
136 gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const { 115 gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const {
137 HWND window_hwnd = GetHWNDFromNativeView(window); 116 HWND window_hwnd = GetHWNDFromNativeView(window);
138 if (!window_hwnd) { 117 if (!window_hwnd) {
139 // When |window| isn't rooted to a display, we should just return the 118 // When |window| isn't rooted to a display, we should just return the
140 // default display so we get some correct display information like the 119 // default display so we get some correct display information like the
141 // scaling factor. 120 // scaling factor.
142 return GetPrimaryDisplay(); 121 return GetPrimaryDisplay();
143 } 122 }
144 123 gfx::win::ScreenWinDisplay screen_win_display =
145 MONITORINFOEX monitor_info; 124 GetScreenWinDisplayNearestHWND(window_hwnd);
146 monitor_info.cbSize = sizeof(monitor_info); 125 return screen_win_display.display();
147 GetMonitorInfo(MonitorFromWindow(window_hwnd, MONITOR_DEFAULTTONEAREST),
148 &monitor_info);
149 return GetDisplay(monitor_info);
150 } 126 }
151 127
152 gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const { 128 gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const {
153 gfx::Point point_in_pixels = gfx::win::DIPToScreenPoint(point); 129 gfx::Point screen_point(gfx::win::DIPToScreenPoint(point));
154 POINT initial_loc = { point_in_pixels.x(), point_in_pixels.y() }; 130 gfx::win::ScreenWinDisplay screen_win_display =
155 HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST); 131 GetScreenWinDisplayNearestScreenPoint(screen_point);
156 MONITORINFOEX mi; 132 return screen_win_display.display();
157 ZeroMemory(&mi, sizeof(MONITORINFOEX));
158 mi.cbSize = sizeof(mi);
159 if (monitor && GetMonitorInfo(monitor, &mi)) {
160 return GetDisplay(mi);
161 }
162 return gfx::Display();
163 } 133 }
164 134
165 gfx::Display ScreenWin::GetDisplayMatching(const gfx::Rect& match_rect) const { 135 gfx::Display ScreenWin::GetDisplayMatching(const gfx::Rect& match_rect) const {
166 RECT other_bounds_rect = match_rect.ToRECT(); 136 gfx::win::ScreenWinDisplay screen_win_display =
167 MONITORINFOEX monitor_info = GetMonitorInfoForMonitor(MonitorFromRect( 137 GetScreenWinDisplayNearestScreenRect(match_rect);
168 &other_bounds_rect, MONITOR_DEFAULTTONEAREST)); 138 return screen_win_display.display();
169 return GetDisplay(monitor_info);
170 } 139 }
171 140
172 gfx::Display ScreenWin::GetPrimaryDisplay() const { 141 gfx::Display ScreenWin::GetPrimaryDisplay() const {
173 MONITORINFOEX mi = GetMonitorInfoForMonitor( 142 return GetPrimaryScreenWinDisplay().display();
174 MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY));
175 gfx::Display display = GetDisplay(mi);
176 // TODO(kevers|girard): Test if these checks can be reintroduced for high-DIP
177 // once more of the app is DIP-aware.
178 if (GetDPIScale() == 1.0) {
179 DCHECK_EQ(GetSystemMetrics(SM_CXSCREEN), display.size().width());
180 DCHECK_EQ(GetSystemMetrics(SM_CYSCREEN), display.size().height());
181 }
182 return display;
183 } 143 }
184 144
185 void ScreenWin::AddObserver(DisplayObserver* observer) { 145 void ScreenWin::AddObserver(DisplayObserver* observer) {
186 change_notifier_.AddObserver(observer); 146 change_notifier_.AddObserver(observer);
187 } 147 }
188 148
189 void ScreenWin::RemoveObserver(DisplayObserver* observer) { 149 void ScreenWin::RemoveObserver(DisplayObserver* observer) {
190 change_notifier_.RemoveObserver(observer); 150 change_notifier_.RemoveObserver(observer);
191 } 151 }
192 152
153 void ScreenWin::UpdateFromDisplayInfos(
154 const std::vector<gfx::win::DisplayInfo>& display_infos) {
155 screen_win_displays_ = DisplayInfosToScreenWinDisplays(display_infos);
156 }
157
158 void ScreenWin::Initialize() {
159 singleton_hwnd_observer_.reset(
160 new gfx::SingletonHwndObserver(
161 base::Bind(&ScreenWin::OnWndProc, base::Unretained(this))));
162 UpdateFromDisplayInfos(GetDisplayInfosFromSystem());
163 }
164
165 MONITORINFOEX ScreenWin::MonitorInfoFromScreenPoint(
166 const gfx::Point& screen_point) const {
167 POINT initial_loc = { screen_point.x(), screen_point.y() };
168 return MonitorInfoFromHMONITOR(::MonitorFromPoint(initial_loc,
169 MONITOR_DEFAULTTONEAREST));
170 }
171
172 MONITORINFOEX ScreenWin::MonitorInfoFromScreenRect(const gfx::Rect& screen_rect)
173 const {
174 RECT win_rect = screen_rect.ToRECT();
175 return MonitorInfoFromHMONITOR(::MonitorFromRect(&win_rect,
176 MONITOR_DEFAULTTONEAREST));
177 }
178
179 MONITORINFOEX ScreenWin::MonitorInfoFromWindow(HWND hwnd,
180 DWORD default_options) const {
181 return MonitorInfoFromHMONITOR(::MonitorFromWindow(hwnd, default_options));
182 }
183
184 HWND ScreenWin::GetRootWindow(HWND hwnd) const {
185 return ::GetAncestor(hwnd, GA_ROOT);
186 }
187
193 void ScreenWin::OnWndProc(HWND hwnd, 188 void ScreenWin::OnWndProc(HWND hwnd,
194 UINT message, 189 UINT message,
195 WPARAM wparam, 190 WPARAM wparam,
196 LPARAM lparam) { 191 LPARAM lparam) {
197 if (message != WM_DISPLAYCHANGE) 192 if (message != WM_DISPLAYCHANGE)
198 return; 193 return;
199 194
200 std::vector<gfx::Display> old_displays = displays_; 195 std::vector<gfx::Display> old_displays = GetAllDisplays();
201 displays_ = GetDisplays(); 196 UpdateFromDisplayInfos(GetDisplayInfosFromSystem());
202 197 change_notifier_.NotifyDisplaysChanged(old_displays, GetAllDisplays());
203 change_notifier_.NotifyDisplaysChanged(old_displays, displays_);
204 } 198 }
205 199
206 // static 200 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestHWND(HWND hwnd)
207 std::vector<gfx::Display> ScreenWin::GetDisplaysForMonitorInfos( 201 const {
208 const std::vector<MONITORINFOEX>& monitor_infos) { 202 return GetScreenWinDisplay(MonitorInfoFromWindow(hwnd,
209 std::vector<gfx::Display> displays; 203 MONITOR_DEFAULTTONEAREST));
210 for (const MONITORINFOEX& monitor_info : monitor_infos) 204 }
211 displays.push_back(GetDisplay(monitor_info));
212 205
213 return displays; 206 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestScreenRect(
207 const Rect& screen_rect) const {
208 return GetScreenWinDisplay(MonitorInfoFromScreenRect(screen_rect));
209 }
210
211 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestScreenPoint(
212 const Point& screen_point) const {
213 return GetScreenWinDisplay(MonitorInfoFromScreenPoint(screen_point));
214 }
215
216 gfx::win::ScreenWinDisplay ScreenWin::GetPrimaryScreenWinDisplay() const {
217 MONITORINFOEX monitor_info = MonitorInfoFromWindow(nullptr,
218 MONITOR_DEFAULTTOPRIMARY);
219 gfx::win::ScreenWinDisplay screen_win_display =
220 GetScreenWinDisplay(monitor_info);
221 gfx::Display display = screen_win_display.display();
222 // The Windows primary monitor is defined to have an origin of (0, 0).
223 DCHECK_EQ(0, display.bounds().origin().x());
224 DCHECK_EQ(0, display.bounds().origin().y());
225 return screen_win_display;
226 }
227
228 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplay(
229 const MONITORINFOEX& monitor_info) const {
230 int64_t id =
231 gfx::win::DisplayInfo::DeviceIdFromDeviceName(monitor_info.szDevice);
232 for (const auto& screen_win_display : screen_win_displays_) {
233 if (screen_win_display.display().id() == id)
234 return screen_win_display;
235 }
236 // There is 1:1 correspondence between MONITORINFOEX and ScreenWinDisplay.
237 // If we make it here, it means we have no displays and we should hand out the
238 // default display.
239 DCHECK_EQ(screen_win_displays_.size(), 0u);
240 return gfx::win::ScreenWinDisplay();
214 } 241 }
215 242
216 } // namespace gfx 243 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/screen_win.h ('k') | ui/gfx/screen_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698