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
3 // found in the LICENSE file.
5 #include "ui/gfx/screen_win.h"
10 #include "base/logging.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/win/win_util.h"
13 #include "ui/gfx/display.h"
14 #include "ui/gfx/win/dpi.h"
18 MONITORINFOEX
GetMonitorInfoForMonitor(HMONITOR monitor
) {
19 MONITORINFOEX monitor_info
;
20 ZeroMemory(&monitor_info
, sizeof(MONITORINFOEX
));
21 monitor_info
.cbSize
= sizeof(monitor_info
);
22 GetMonitorInfo(monitor
, &monitor_info
);
26 gfx::Display
GetDisplay(MONITORINFOEX
& monitor_info
) {
27 // TODO(oshima): Implement Observer.
28 int64 id
= static_cast<int64
>(
29 base::Hash(base::WideToUTF8(monitor_info
.szDevice
)));
30 gfx::Rect bounds
= gfx::Rect(monitor_info
.rcMonitor
);
31 gfx::Display
display(id
, bounds
);
32 display
.set_work_area(gfx::Rect(monitor_info
.rcWork
));
33 display
.SetScaleAndBounds(gfx::win::GetDeviceScaleFactor(), bounds
);
37 BOOL CALLBACK
EnumMonitorCallback(HMONITOR monitor
,
41 std::vector
<gfx::Display
>* all_displays
=
42 reinterpret_cast<std::vector
<gfx::Display
>*>(data
);
45 MONITORINFOEX monitor_info
= GetMonitorInfoForMonitor(monitor
);
46 gfx::Display display
= GetDisplay(monitor_info
);
47 all_displays
->push_back(display
);
55 ScreenWin::ScreenWin() {
58 ScreenWin::~ScreenWin() {
61 bool ScreenWin::IsDIPEnabled() {
62 return IsInHighDPIMode();
65 gfx::Point
ScreenWin::GetCursorScreenPoint() {
68 gfx::Point
cursor_pos_pixels(pt
);
69 return gfx::win::ScreenToDIPPoint(cursor_pos_pixels
);
72 gfx::NativeWindow
ScreenWin::GetWindowUnderCursor() {
74 HWND hwnd
= GetCursorPos(&cursor_loc
) ? WindowFromPoint(cursor_loc
) : NULL
;
75 return GetNativeWindowFromHWND(hwnd
);
78 gfx::NativeWindow
ScreenWin::GetWindowAtScreenPoint(const gfx::Point
& point
) {
79 gfx::Point point_in_pixels
= gfx::win::DIPToScreenPoint(point
);
80 return GetNativeWindowFromHWND(WindowFromPoint(point_in_pixels
.ToPOINT()));
83 int ScreenWin::GetNumDisplays() const {
84 return GetSystemMetrics(SM_CMONITORS
);
87 std::vector
<gfx::Display
> ScreenWin::GetAllDisplays() const {
88 std::vector
<gfx::Display
> all_displays
;
89 EnumDisplayMonitors(NULL
, NULL
, EnumMonitorCallback
,
90 reinterpret_cast<LPARAM
>(&all_displays
));
94 gfx::Display
ScreenWin::GetDisplayNearestWindow(gfx::NativeView window
) const {
95 HWND window_hwnd
= GetHWNDFromNativeView(window
);
97 // When |window| isn't rooted to a display, we should just return the
98 // default display so we get some correct display information like the
100 return GetPrimaryDisplay();
103 MONITORINFOEX monitor_info
;
104 monitor_info
.cbSize
= sizeof(monitor_info
);
105 GetMonitorInfo(MonitorFromWindow(window_hwnd
, MONITOR_DEFAULTTONEAREST
),
107 return GetDisplay(monitor_info
);
110 gfx::Display
ScreenWin::GetDisplayNearestPoint(const gfx::Point
& point
) const {
111 POINT initial_loc
= { point
.x(), point
.y() };
112 HMONITOR monitor
= MonitorFromPoint(initial_loc
, MONITOR_DEFAULTTONEAREST
);
114 ZeroMemory(&mi
, sizeof(MONITORINFOEX
));
115 mi
.cbSize
= sizeof(mi
);
116 if (monitor
&& GetMonitorInfo(monitor
, &mi
)) {
117 return GetDisplay(mi
);
119 return gfx::Display();
122 gfx::Display
ScreenWin::GetDisplayMatching(const gfx::Rect
& match_rect
) const {
123 RECT other_bounds_rect
= match_rect
.ToRECT();
124 MONITORINFOEX monitor_info
= GetMonitorInfoForMonitor(MonitorFromRect(
125 &other_bounds_rect
, MONITOR_DEFAULTTONEAREST
));
126 return GetDisplay(monitor_info
);
129 gfx::Display
ScreenWin::GetPrimaryDisplay() const {
130 MONITORINFOEX mi
= GetMonitorInfoForMonitor(
131 MonitorFromWindow(NULL
, MONITOR_DEFAULTTOPRIMARY
));
132 gfx::Display display
= GetDisplay(mi
);
133 // TODO(kevers|girard): Test if these checks can be reintroduced for high-DIP
134 // once more of the app is DIP-aware.
135 if (!(IsInHighDPIMode() || IsHighDPIEnabled())) {
136 DCHECK_EQ(GetSystemMetrics(SM_CXSCREEN
), display
.size().width());
137 DCHECK_EQ(GetSystemMetrics(SM_CYSCREEN
), display
.size().height());
142 void ScreenWin::AddObserver(DisplayObserver
* observer
) {
143 // TODO(oshima): crbug.com/122863.
146 void ScreenWin::RemoveObserver(DisplayObserver
* observer
) {
147 // TODO(oshima): crbug.com/122863.
150 HWND
ScreenWin::GetHWNDFromNativeView(NativeView window
) const {
155 NativeWindow
ScreenWin::GetNativeWindowFromHWND(HWND hwnd
) const {