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

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: Rebase to bdd95f1 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,
142 default_options));
oshima 2016/01/30 00:10:33 fit to single line?
robliao 2016/01/30 01:23:52 Done.
143 }
144
145 HWND DisplayManager::GetRootWindow(HWND hwnd) const {
146 return ::GetAncestor(hwnd, GA_ROOT);
147 }
148
149 // static
150 void DisplayManager::SetInstanceForTesting(
151 scoped_ptr<DisplayManager> display_manager) {
152 g_display_manager.Get() = std::move(display_manager);
153 }
154
155 DisplayManager::DisplayManager() = default;
156
157 DisplayManager::~DisplayManager() = default;
158
159 void DisplayManager::UpdateFromDisplayInfos(
160 const std::vector<DisplayInfo>& display_infos) {
161 screen_win_displays_ = DisplayInfosToScreenWinDisplays(display_infos);
162 }
163
164 ScreenWinDisplay DisplayManager::GetScreenWinDisplay(
165 const MONITORINFOEX& monitor_info) const {
166 int64_t id = DisplayInfo::HashDeviceName(monitor_info.szDevice);
167 for (const auto& screen_win_display : screen_win_displays_) {
168 if (screen_win_display.display().id() == id)
169 return screen_win_display;
170 }
171 // When the system isn't initialized, it means we're likely under a test.
172 DCHECK_EQ(screen_win_displays_.size(), 0u);
173 return ScreenWinDisplay();
174 }
175
176 void DisplayManager::WndProc(HWND hwnd,
177 UINT message,
178 WPARAM wparam,LPARAM lparam) {
179 if (message != WM_DISPLAYCHANGE)
180 return;
181
182 std::vector<ScreenWinDisplay> old_displays = screen_win_displays_;
183 UpdateFromDisplayInfos(GetDisplayInfosFromSystem());
184
185 FOR_EACH_OBSERVER(DisplayManagerObserver,
186 observer_list_,
187 OnDisplaysChanged(old_displays, screen_win_displays_));
188 }
189
190 } // namespace win
191 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698