| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "ui/gfx/screen_win.h" | |
| 6 | |
| 7 #include <windows.h> | |
| 8 | |
| 9 #include "base/hash.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" | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 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); | |
| 23 return monitor_info; | |
| 24 } | |
| 25 | |
| 26 gfx::Display GetDisplay(MONITORINFOEX& monitor_info) { | |
| 27 int64 id = static_cast<int64>( | |
| 28 base::Hash(base::WideToUTF8(monitor_info.szDevice))); | |
| 29 gfx::Rect bounds = gfx::Rect(monitor_info.rcMonitor); | |
| 30 gfx::Display display(id, bounds); | |
| 31 display.set_work_area(gfx::Rect(monitor_info.rcWork)); | |
| 32 display.SetScaleAndBounds(gfx::win::GetDeviceScaleFactor(), bounds); | |
| 33 | |
| 34 DEVMODE mode; | |
| 35 memset(&mode, 0, sizeof(DEVMODE)); | |
| 36 mode.dmSize = sizeof(DEVMODE); | |
| 37 mode.dmDriverExtra = 0; | |
| 38 if (EnumDisplaySettings(monitor_info.szDevice, | |
| 39 ENUM_CURRENT_SETTINGS, | |
| 40 &mode)) { | |
| 41 switch (mode.dmDisplayOrientation) { | |
| 42 case DMDO_DEFAULT: | |
| 43 display.set_rotation(gfx::Display::ROTATE_0); | |
| 44 break; | |
| 45 case DMDO_90: | |
| 46 display.set_rotation(gfx::Display::ROTATE_90); | |
| 47 break; | |
| 48 case DMDO_180: | |
| 49 display.set_rotation(gfx::Display::ROTATE_180); | |
| 50 break; | |
| 51 case DMDO_270: | |
| 52 display.set_rotation(gfx::Display::ROTATE_270); | |
| 53 break; | |
| 54 default: | |
| 55 NOTREACHED(); | |
| 56 } | |
| 57 } | |
| 58 | |
| 59 return display; | |
| 60 } | |
| 61 | |
| 62 BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor, | |
| 63 HDC hdc, | |
| 64 LPRECT rect, | |
| 65 LPARAM data) { | |
| 66 std::vector<gfx::Display>* all_displays = | |
| 67 reinterpret_cast<std::vector<gfx::Display>*>(data); | |
| 68 DCHECK(all_displays); | |
| 69 | |
| 70 MONITORINFOEX monitor_info = GetMonitorInfoForMonitor(monitor); | |
| 71 gfx::Display display = GetDisplay(monitor_info); | |
| 72 all_displays->push_back(display); | |
| 73 return TRUE; | |
| 74 } | |
| 75 | |
| 76 std::vector<gfx::Display> GetDisplays() { | |
| 77 std::vector<gfx::Display> displays; | |
| 78 EnumDisplayMonitors(NULL, NULL, EnumMonitorCallback, | |
| 79 reinterpret_cast<LPARAM>(&displays)); | |
| 80 return displays; | |
| 81 } | |
| 82 | |
| 83 } // namespace | |
| 84 | |
| 85 namespace gfx { | |
| 86 | |
| 87 ScreenWin::ScreenWin() | |
| 88 : displays_(GetDisplays()) { | |
| 89 SingletonHwnd::GetInstance()->AddObserver(this); | |
| 90 } | |
| 91 | |
| 92 ScreenWin::~ScreenWin() { | |
| 93 SingletonHwnd::GetInstance()->RemoveObserver(this); | |
| 94 } | |
| 95 | |
| 96 bool ScreenWin::IsDIPEnabled() { | |
| 97 return IsInHighDPIMode(); | |
| 98 } | |
| 99 | |
| 100 gfx::Point ScreenWin::GetCursorScreenPoint() { | |
| 101 POINT pt; | |
| 102 GetCursorPos(&pt); | |
| 103 gfx::Point cursor_pos_pixels(pt); | |
| 104 return gfx::win::ScreenToDIPPoint(cursor_pos_pixels); | |
| 105 } | |
| 106 | |
| 107 gfx::NativeWindow ScreenWin::GetWindowUnderCursor() { | |
| 108 POINT cursor_loc; | |
| 109 HWND hwnd = GetCursorPos(&cursor_loc) ? WindowFromPoint(cursor_loc) : NULL; | |
| 110 return GetNativeWindowFromHWND(hwnd); | |
| 111 } | |
| 112 | |
| 113 gfx::NativeWindow ScreenWin::GetWindowAtScreenPoint(const gfx::Point& point) { | |
| 114 gfx::Point point_in_pixels = gfx::win::DIPToScreenPoint(point); | |
| 115 return GetNativeWindowFromHWND(WindowFromPoint(point_in_pixels.ToPOINT())); | |
| 116 } | |
| 117 | |
| 118 int ScreenWin::GetNumDisplays() const { | |
| 119 return GetSystemMetrics(SM_CMONITORS); | |
| 120 } | |
| 121 | |
| 122 std::vector<gfx::Display> ScreenWin::GetAllDisplays() const { | |
| 123 return displays_; | |
| 124 } | |
| 125 | |
| 126 gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const { | |
| 127 HWND window_hwnd = GetHWNDFromNativeView(window); | |
| 128 if (!window_hwnd) { | |
| 129 // When |window| isn't rooted to a display, we should just return the | |
| 130 // default display so we get some correct display information like the | |
| 131 // scaling factor. | |
| 132 return GetPrimaryDisplay(); | |
| 133 } | |
| 134 | |
| 135 MONITORINFOEX monitor_info; | |
| 136 monitor_info.cbSize = sizeof(monitor_info); | |
| 137 GetMonitorInfo(MonitorFromWindow(window_hwnd, MONITOR_DEFAULTTONEAREST), | |
| 138 &monitor_info); | |
| 139 return GetDisplay(monitor_info); | |
| 140 } | |
| 141 | |
| 142 gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const { | |
| 143 POINT initial_loc = { point.x(), point.y() }; | |
| 144 HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST); | |
| 145 MONITORINFOEX mi; | |
| 146 ZeroMemory(&mi, sizeof(MONITORINFOEX)); | |
| 147 mi.cbSize = sizeof(mi); | |
| 148 if (monitor && GetMonitorInfo(monitor, &mi)) { | |
| 149 return GetDisplay(mi); | |
| 150 } | |
| 151 return gfx::Display(); | |
| 152 } | |
| 153 | |
| 154 gfx::Display ScreenWin::GetDisplayMatching(const gfx::Rect& match_rect) const { | |
| 155 RECT other_bounds_rect = match_rect.ToRECT(); | |
| 156 MONITORINFOEX monitor_info = GetMonitorInfoForMonitor(MonitorFromRect( | |
| 157 &other_bounds_rect, MONITOR_DEFAULTTONEAREST)); | |
| 158 return GetDisplay(monitor_info); | |
| 159 } | |
| 160 | |
| 161 gfx::Display ScreenWin::GetPrimaryDisplay() const { | |
| 162 MONITORINFOEX mi = GetMonitorInfoForMonitor( | |
| 163 MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY)); | |
| 164 gfx::Display display = GetDisplay(mi); | |
| 165 // TODO(kevers|girard): Test if these checks can be reintroduced for high-DIP | |
| 166 // once more of the app is DIP-aware. | |
| 167 if (!(IsInHighDPIMode() || IsHighDPIEnabled())) { | |
| 168 DCHECK_EQ(GetSystemMetrics(SM_CXSCREEN), display.size().width()); | |
| 169 DCHECK_EQ(GetSystemMetrics(SM_CYSCREEN), display.size().height()); | |
| 170 } | |
| 171 return display; | |
| 172 } | |
| 173 | |
| 174 void ScreenWin::AddObserver(DisplayObserver* observer) { | |
| 175 change_notifier_.AddObserver(observer); | |
| 176 } | |
| 177 | |
| 178 void ScreenWin::RemoveObserver(DisplayObserver* observer) { | |
| 179 change_notifier_.RemoveObserver(observer); | |
| 180 } | |
| 181 | |
| 182 void ScreenWin::OnWndProc(HWND hwnd, | |
| 183 UINT message, | |
| 184 WPARAM wparam, | |
| 185 LPARAM lparam) { | |
| 186 if (message != WM_DISPLAYCHANGE) | |
| 187 return; | |
| 188 | |
| 189 std::vector<gfx::Display> old_displays = displays_; | |
| 190 displays_ = GetDisplays(); | |
| 191 | |
| 192 change_notifier_.NotifyDisplaysChanged(old_displays, displays_); | |
| 193 } | |
| 194 | |
| 195 HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const { | |
| 196 NOTREACHED(); | |
| 197 return NULL; | |
| 198 } | |
| 199 | |
| 200 NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const { | |
| 201 NOTREACHED(); | |
| 202 return NULL; | |
| 203 } | |
| 204 | |
| 205 } // namespace gfx | |
| OLD | NEW |