screen_win.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 16namespace { 17 18MONITORINFOEX 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 26gfx::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); 34 return display; 35} 36 37BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor, 38 HDC hdc, 39 LPRECT rect, 40 LPARAM data) { 41 std::vector<gfx::Display>* all_displays = 42 reinterpret_cast<std::vector<gfx::Display>*>(data); 43 DCHECK(all_displays); 44 45 MONITORINFOEX monitor_info = GetMonitorInfoForMonitor(monitor); 46 gfx::Display display = GetDisplay(monitor_info); 47 all_displays->push_back(display); 48 return TRUE; 49} 50 51} // namespace 52 53namespace gfx { 54 55ScreenWin::ScreenWin() { 56} 57 58ScreenWin::~ScreenWin() { 59} 60 61bool ScreenWin::IsDIPEnabled() { 62 return IsInHighDPIMode(); 63} 64 65gfx::Point ScreenWin::GetCursorScreenPoint() { 66 POINT pt; 67 GetCursorPos(&pt); 68 return gfx::Point(pt); 69} 70 71gfx::NativeWindow ScreenWin::GetWindowUnderCursor() { 72 POINT cursor_loc; 73 HWND hwnd = GetCursorPos(&cursor_loc) ? WindowFromPoint(cursor_loc) : NULL; 74 return GetNativeWindowFromHWND(hwnd); 75} 76 77gfx::NativeWindow ScreenWin::GetWindowAtScreenPoint(const gfx::Point& point) { 78 return GetNativeWindowFromHWND(WindowFromPoint(point.ToPOINT())); 79} 80 81int ScreenWin::GetNumDisplays() const { 82 return GetSystemMetrics(SM_CMONITORS); 83} 84 85std::vector<gfx::Display> ScreenWin::GetAllDisplays() const { 86 std::vector<gfx::Display> all_displays; 87 EnumDisplayMonitors(NULL, NULL, EnumMonitorCallback, 88 reinterpret_cast<LPARAM>(&all_displays)); 89 return all_displays; 90} 91 92gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const { 93 HWND window_hwnd = GetHWNDFromNativeView(window); 94 if (!window_hwnd) { 95 // When |window| isn't rooted to a display, we should just return the 96 // default display so we get some correct display information like the 97 // scaling factor. 98 return GetPrimaryDisplay(); 99 } 100 101 MONITORINFOEX monitor_info; 102 monitor_info.cbSize = sizeof(monitor_info); 103 GetMonitorInfo(MonitorFromWindow(window_hwnd, MONITOR_DEFAULTTONEAREST), 104 &monitor_info); 105 return GetDisplay(monitor_info); 106} 107 108gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const { 109 POINT initial_loc = { point.x(), point.y() }; 110 HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST); 111 MONITORINFOEX mi; 112 ZeroMemory(&mi, sizeof(MONITORINFOEX)); 113 mi.cbSize = sizeof(mi); 114 if (monitor && GetMonitorInfo(monitor, &mi)) { 115 return GetDisplay(mi); 116 } 117 return gfx::Display(); 118} 119 120gfx::Display ScreenWin::GetDisplayMatching(const gfx::Rect& match_rect) const { 121 RECT other_bounds_rect = match_rect.ToRECT(); 122 MONITORINFOEX monitor_info = GetMonitorInfoForMonitor(MonitorFromRect( 123 &other_bounds_rect, MONITOR_DEFAULTTONEAREST)); 124 return GetDisplay(monitor_info); 125} 126 127gfx::Display ScreenWin::GetPrimaryDisplay() const { 128 MONITORINFOEX mi = GetMonitorInfoForMonitor( 129 MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY)); 130 gfx::Display display = GetDisplay(mi); 131 // TODO(kevers|girard): Test if these checks can be reintroduced for high-DIP 132 // once more of the app is DIP-aware. 133 if (!(IsInHighDPIMode() || IsHighDPIEnabled())) { 134 DCHECK_EQ(GetSystemMetrics(SM_CXSCREEN), display.size().width()); 135 DCHECK_EQ(GetSystemMetrics(SM_CYSCREEN), display.size().height()); 136 } 137 return display; 138} 139 140void ScreenWin::AddObserver(DisplayObserver* observer) { 141 // TODO(oshima): crbug.com/122863. 142} 143 144void ScreenWin::RemoveObserver(DisplayObserver* observer) { 145 // TODO(oshima): crbug.com/122863. 146} 147 148HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const { 149#if defined(USE_AURA) 150 NOTREACHED(); 151 return NULL; 152#else 153 return window; 154#endif // USE_AURA 155} 156 157NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const { 158#if defined(USE_AURA) 159 NOTREACHED(); 160 return NULL; 161#else 162 return hwnd; 163#endif // USE_AURA 164} 165 166#if !defined(USE_AURA) 167Screen* CreateNativeScreen() { 168 return new ScreenWin; 169} 170#endif // !USE_AURA 171 172} // namespace gfx 173