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

Side by Side Diff: ui/gfx/win/display_manager.cc

Issue 1639623003: ScreenWin Testability and Restructuring (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR Feedback 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/gfx/win/display_manager.h"
6
7 #include <windows.h>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/lazy_instance.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "ui/gfx/win/display_info.h"
14 #include "ui/gfx/win/display_manager_observer.h"
15 #include "ui/gfx/win/dpi.h"
16 #include "ui/gfx/win/screen_win_display.h"
17 #include "ui/gfx/win/singleton_hwnd_observer.h"
18
19 namespace {
20
21 // Use Leaky since gfx::ScreenWin is leaked at exit, and LazyInstance instead of
22 // Singleton allows for a substitution for testing.
23 base::LazyInstance<scoped_ptr<gfx::win::DisplayManager>>::Leaky
24 g_display_manager = LAZY_INSTANCE_INITIALIZER;
25
26 MONITORINFOEX MonitorInfoFromHMONITOR(HMONITOR monitor) {
27 MONITORINFOEX monitor_info;
28 ::ZeroMemory(&monitor_info, sizeof(monitor_info));
29 monitor_info.cbSize = sizeof(monitor_info);
30 ::GetMonitorInfo(monitor, &monitor_info);
31 return monitor_info;
32 }
33
34 BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor,
35 HDC hdc,
36 LPRECT rect,
37 LPARAM data) {
38 std::vector<gfx::win::DisplayInfo>* display_infos =
39 reinterpret_cast<std::vector<gfx::win::DisplayInfo>*>(data);
40 DCHECK(display_infos);
41 display_infos->push_back(
42 gfx::win::DisplayInfo(MonitorInfoFromHMONITOR(monitor),
43 gfx::GetDPIScale()));
44 return TRUE;
45 }
46
47 std::vector<gfx::win::DisplayInfo> GetDisplayInfosFromSystem() {
48 std::vector<gfx::win::DisplayInfo> display_infos;
49 EnumDisplayMonitors(NULL, NULL, EnumMonitorCallback,
50 reinterpret_cast<LPARAM>(&display_infos));
51 DCHECK_EQ(static_cast<size_t>(::GetSystemMetrics(SM_CMONITORS)),
52 display_infos.size());
53 return display_infos;
54 }
55
56 std::vector<gfx::win::ScreenWinDisplay> DisplayInfosToScreenWinDisplays(
57 const std::vector<gfx::win::DisplayInfo>& display_infos) {
58 std::vector<gfx::win::ScreenWinDisplay> screen_win_displays;
59 for (const auto& display_info : display_infos)
60 screen_win_displays.push_back(gfx::win::ScreenWinDisplay(display_info));
61
62 return screen_win_displays;
63 }
64
65 } // namespace
66
67 namespace gfx {
68 namespace win {
69
70 // static
71 DisplayManager* DisplayManager::GetInstance() {
72 if (!g_display_manager.Get().get()) {
73 g_display_manager.Get().reset(new DisplayManager());
74 g_display_manager.Get()->Initialize();
75 }
76 return g_display_manager.Get().get();
77 }
78
79 void DisplayManager::Initialize() {
80 singleton_hwnd_observer_.reset(
81 new gfx::SingletonHwndObserver(
82 base::Bind(&DisplayManager::WndProc, base::Unretained(this))));
83 UpdateFromDisplayInfos(GetDisplayInfosFromSystem());
84 }
85
86 void DisplayManager::AddObserver(DisplayManagerObserver* observer) {
87 observer_list_.AddObserver(observer);
88 }
89
90 void DisplayManager::RemoveObserver(DisplayManagerObserver* observer) {
91 observer_list_.RemoveObserver(observer);
92 }
93
94 const std::vector<ScreenWinDisplay>& DisplayManager::GetScreenWinDisplays() {
95 return screen_win_displays_;
96 }
97
98 ScreenWinDisplay DisplayManager::GetScreenWinDisplayNearestHWND(HWND hwnd)
99 const {
100 return GetScreenWinDisplay(MonitorInfoFromWindow(hwnd,
101 MONITOR_DEFAULTTONEAREST));
102 }
103
104 ScreenWinDisplay DisplayManager::GetScreenWinDisplayNearestScreenRect(
105 const Rect& screen_rect) const {
106 return GetScreenWinDisplay(MonitorInfoFromScreenRect(screen_rect));
107 }
108
109 ScreenWinDisplay DisplayManager::GetScreenWinDisplayNearestScreenPoint(
110 const Point& screen_point) const {
111 return GetScreenWinDisplay(MonitorInfoFromScreenPoint(screen_point));
112 }
113
114 ScreenWinDisplay DisplayManager::GetPrimaryScreenWinDisplay() const {
115 MONITORINFOEX monitor_info = MonitorInfoFromWindow(NULL,
116 MONITOR_DEFAULTTOPRIMARY);
117 ScreenWinDisplay screen_win_display = GetScreenWinDisplay(monitor_info);
118 gfx::Display display = screen_win_display.display();
119 // The Windows primary monitor is defined to have an origin of (0, 0).
120 DCHECK_EQ(0, display.bounds().origin().x());
121 DCHECK_EQ(0, display.bounds().origin().y());
122 return screen_win_display;
123 }
124
125 MONITORINFOEX DisplayManager::MonitorInfoFromScreenPoint(
126 const gfx::Point& screen_point) const {
127 POINT initial_loc = { screen_point.x(), screen_point.y() };
128 return MonitorInfoFromHMONITOR(::MonitorFromPoint(initial_loc,
129 MONITOR_DEFAULTTONEAREST));
130 }
131
132 MONITORINFOEX DisplayManager::MonitorInfoFromScreenRect(
133 const gfx::Rect& screen_rect) const {
134 RECT win_rect = screen_rect.ToRECT();
135 return MonitorInfoFromHMONITOR(::MonitorFromRect(&win_rect,
136 MONITOR_DEFAULTTONEAREST));
137 }
138
139 MONITORINFOEX DisplayManager::MonitorInfoFromWindow(
140 HWND hwnd, DWORD default_options) const {
141 return MonitorInfoFromHMONITOR(::MonitorFromWindow(hwnd, default_options));
142 }
143
144 HWND DisplayManager::GetRootWindow(HWND hwnd) const {
145 return ::GetAncestor(hwnd, GA_ROOT);
146 }
147
148 // static
149 void DisplayManager::SetInstanceForTesting(
150 scoped_ptr<DisplayManager> display_manager) {
151 g_display_manager.Get() = std::move(display_manager);
152 }
153
154 DisplayManager::DisplayManager() = default;
155
156 DisplayManager::~DisplayManager() = default;
157
158 void DisplayManager::UpdateFromDisplayInfos(
159 const std::vector<DisplayInfo>& display_infos) {
160 screen_win_displays_ = DisplayInfosToScreenWinDisplays(display_infos);
161 }
162
163 ScreenWinDisplay DisplayManager::GetScreenWinDisplay(
164 const MONITORINFOEX& monitor_info) const {
165 int64_t id = DisplayInfo::HashDeviceName(monitor_info.szDevice);
166 for (const auto& screen_win_display : screen_win_displays_) {
167 if (screen_win_display.display().id() == id)
168 return screen_win_display;
169 }
170 // When the system isn't initialized, it means we're likely under a test.
171 DCHECK_EQ(screen_win_displays_.size(), 0u);
172 return ScreenWinDisplay();
173 }
174
175 void DisplayManager::WndProc(HWND hwnd,
176 UINT message,
177 WPARAM wparam,LPARAM lparam) {
178 if (message != WM_DISPLAYCHANGE)
179 return;
180
181 std::vector<ScreenWinDisplay> old_displays = screen_win_displays_;
182 UpdateFromDisplayInfos(GetDisplayInfosFromSystem());
183
184 FOR_EACH_OBSERVER(DisplayManagerObserver,
185 observer_list_,
186 OnDisplaysChanged(old_displays, screen_win_displays_));
187 }
188
189 } // namespace win
190 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698