screen_win.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen_win.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/win/dpi.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/display.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MONITORINFO GetMonitorInfoForMonitor(HMONITOR monitor) {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MONITORINFO monitor_info = { 0 };
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  monitor_info.cbSize = sizeof(monitor_info);
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMonitorInfo(monitor, &monitor_info);
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return monitor_info;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display GetDisplay(MONITORINFO& monitor_info) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(oshima): Implement ID and Observer.
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds = gfx::Rect(monitor_info.rcMonitor);
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Display display(0, bounds);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  display.set_work_area(gfx::Rect(monitor_info.rcWork));
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  display.SetScaleAndBounds(ui::win::GetDeviceScaleFactor(), bounds);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return display;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScreenWin::ScreenWin() {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScreenWin::~ScreenWin() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ScreenWin::IsDIPEnabled() {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_HIDPI)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Point ScreenWin::GetCursorScreenPoint() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  POINT pt;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetCursorPos(&pt);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Point(pt);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeWindow ScreenWin::GetWindowAtCursorScreenPoint() {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  POINT location;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HWND window_hwnd = GetCursorPos(&location) ? WindowFromPoint(location) : NULL;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetNativeWindowFromHWND(window_hwnd);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ScreenWin::GetNumDisplays() {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetSystemMetrics(SM_CMONITORS);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HWND window_hwnd = GetHWNDFromNativeView(window);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!window_hwnd) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When |window| isn't rooted to a display, we should just return the
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // default display so we get some correct display information like the
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // scaling factor.
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return GetPrimaryDisplay();
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MONITORINFO monitor_info;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  monitor_info.cbSize = sizeof(monitor_info);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMonitorInfo(MonitorFromWindow(window_hwnd, MONITOR_DEFAULTTONEAREST),
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &monitor_info);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetDisplay(monitor_info);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  POINT initial_loc = { point.x(), point.y() };
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MONITORINFO mi = {0};
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mi.cbSize = sizeof(mi);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (monitor && GetMonitorInfo(monitor, &mi))
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetDisplay(mi);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Display();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display ScreenWin::GetDisplayMatching(const gfx::Rect& match_rect) const {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RECT other_bounds_rect = match_rect.ToRECT();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MONITORINFO monitor_info = GetMonitorInfoForMonitor(MonitorFromRect(
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &other_bounds_rect, MONITOR_DEFAULTTONEAREST));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetDisplay(monitor_info);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display ScreenWin::GetPrimaryDisplay() const {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MONITORINFO mi = GetMonitorInfoForMonitor(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Display display = GetDisplay(mi);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(ENABLE_HIDPI)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(kevers|girard): Test if these checks can be reintroduced for high-DIP
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // once more of the app is DIP-aware.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(GetSystemMetrics(SM_CXSCREEN), display.size().width());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(GetSystemMetrics(SM_CYSCREEN), display.size().height());
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return display;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ScreenWin::AddObserver(DisplayObserver* observer) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(oshima): crbug.com/122863.
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ScreenWin::RemoveObserver(DisplayObserver* observer) {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(oshima): crbug.com/122863.
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // USE_AURA
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hwnd;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // USE_AURA
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_AURA)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Screen* CreateNativeScreen() {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new ScreenWin;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !USE_AURA
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
144