screen_win.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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 gfx::Point cursor_pos_pixels(pt); 69 return gfx::win::ScreenToDIPPoint(cursor_pos_pixels); 70} 71 72gfx::NativeWindow ScreenWin::GetWindowUnderCursor() { 73 POINT cursor_loc; 74 HWND hwnd = GetCursorPos(&cursor_loc) ? WindowFromPoint(cursor_loc) : NULL; 75 return GetNativeWindowFromHWND(hwnd); 76} 77 78gfx::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())); 81} 82 83int ScreenWin::GetNumDisplays() const { 84 return GetSystemMetrics(SM_CMONITORS); 85} 86 87std::vector<gfx::Display> ScreenWin::GetAllDisplays() const { 88 std::vector<gfx::Display> all_displays; 89 EnumDisplayMonitors(NULL, NULL, EnumMonitorCallback, 90 reinterpret_cast<LPARAM>(&all_displays)); 91 return all_displays; 92} 93 94gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const { 95 HWND window_hwnd = GetHWNDFromNativeView(window); 96 if (!window_hwnd) { 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 99 // scaling factor. 100 return GetPrimaryDisplay(); 101 } 102 103 MONITORINFOEX monitor_info; 104 monitor_info.cbSize = sizeof(monitor_info); 105 GetMonitorInfo(MonitorFromWindow(window_hwnd, MONITOR_DEFAULTTONEAREST), 106 &monitor_info); 107 return GetDisplay(monitor_info); 108} 109 110gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const { 111 POINT initial_loc = { point.x(), point.y() }; 112 HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST); 113 MONITORINFOEX mi; 114 ZeroMemory(&mi, sizeof(MONITORINFOEX)); 115 mi.cbSize = sizeof(mi); 116 if (monitor && GetMonitorInfo(monitor, &mi)) { 117 return GetDisplay(mi); 118 } 119 return gfx::Display(); 120} 121 122gfx::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); 127} 128 129gfx::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()); 138 } 139 return display; 140} 141 142void ScreenWin::AddObserver(DisplayObserver* observer) { 143 // TODO(oshima): crbug.com/122863. 144} 145 146void ScreenWin::RemoveObserver(DisplayObserver* observer) { 147 // TODO(oshima): crbug.com/122863. 148} 149 150HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const { 151 NOTREACHED(); 152 return NULL; 153} 154 155NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const { 156 NOTREACHED(); 157 return NULL; 158} 159 160} // namespace gfx 161