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 "ash/screen_ash.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/display/display_controller.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/display/display_manager.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/root_window_controller.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_widget.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/coordinate_conversion.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/screen_position_client.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/env.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/display.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)internal::DisplayManager* GetDisplayManager() {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Shell::GetInstance()->display_manager();
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochDisplayController* GetDisplayController() {
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return Shell::GetInstance()->display_controller();
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScreenAsh::ScreenAsh() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScreenAsh::~ScreenAsh() {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display ScreenAsh::FindDisplayContainingPoint(const gfx::Point& point) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetDisplayManager()->FindDisplayContainingPoint(point);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect ScreenAsh::GetMaximizedWindowBoundsInParent(aura::Window* window) {
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (internal::GetRootWindowController(window->GetRootWindow())->shelf())
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetDisplayWorkAreaBoundsInParent(window);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetDisplayBoundsInParent(window);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect ScreenAsh::GetDisplayBoundsInParent(aura::Window* window) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ConvertRectFromScreen(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window->parent(),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetScreen()->GetDisplayNearestWindow(window).bounds());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect ScreenAsh::GetDisplayWorkAreaBoundsInParent(aura::Window* window) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ConvertRectFromScreen(
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window->parent(),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetScreen()->GetDisplayNearestWindow(window).work_area());
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect ScreenAsh::ConvertRectToScreen(aura::Window* window,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const gfx::Rect& rect) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point point = rect.origin();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::client::GetScreenPositionClient(window->GetRootWindow())->
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertPointToScreen(window, &point);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Rect(point, rect.size());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect ScreenAsh::ConvertRectFromScreen(aura::Window* window,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const gfx::Rect& rect) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point point = rect.origin();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::client::GetScreenPositionClient(window->GetRootWindow())->
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertPointFromScreen(window, &point);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Rect(point, rect.size());
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::Display& ScreenAsh::GetSecondaryDisplay() {
86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  internal::DisplayManager* display_manager = GetDisplayManager();
87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CHECK_EQ(2U, display_manager->GetNumDisplays());
88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return display_manager->GetDisplayAt(0).id() ==
89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      DisplayController::GetPrimaryDisplay().id() ?
90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      display_manager->GetDisplayAt(1) : display_manager->GetDisplayAt(0);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::Display& ScreenAsh::GetDisplayForId(int64 display_id) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetDisplayManager()->GetDisplayForId(display_id);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ScreenAsh::NotifyBoundsChanged(const gfx::Display& display) {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnDisplayBoundsChanged(display));
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ScreenAsh::NotifyDisplayAdded(const gfx::Display& display) {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_, OnDisplayAdded(display));
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ScreenAsh::NotifyDisplayRemoved(const gfx::Display& display) {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::DisplayObserver, observers_, OnDisplayRemoved(display));
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ScreenAsh::IsDIPEnabled() {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Point ScreenAsh::GetCursorScreenPoint() {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return aura::Env::GetInstance()->last_mouse_location();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)gfx::NativeWindow ScreenAsh::GetWindowUnderCursor() {
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return GetWindowAtScreenPoint(Shell::GetScreen()->GetCursorScreenPoint());
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)gfx::NativeWindow ScreenAsh::GetWindowAtScreenPoint(const gfx::Point& point) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return wm::GetRootWindowAt(point)->GetTopWindowContainingPoint(point);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int ScreenAsh::GetNumDisplays() const {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return DisplayController::GetNumDisplays();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)std::vector<gfx::Display> ScreenAsh::GetAllDisplays() const {
13381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  if (!Shell::HasInstance())
13481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)    return std::vector<gfx::Display>(1, GetPrimaryDisplay());
135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return GetDisplayManager()->displays();
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display ScreenAsh::GetDisplayNearestWindow(gfx::NativeView window) const {
13981843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  if (!Shell::HasInstance())
14081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)    return GetPrimaryDisplay();
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return GetDisplayController()->GetDisplayNearestWindow(window);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display ScreenAsh::GetDisplayNearestPoint(const gfx::Point& point) const {
14581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  if (!Shell::HasInstance())
14681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)    return GetPrimaryDisplay();
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return GetDisplayController()->GetDisplayNearestPoint(point);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display ScreenAsh::GetDisplayMatching(const gfx::Rect& match_rect) const {
15181843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)  if (!Shell::HasInstance())
15281843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)    return GetPrimaryDisplay();
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return GetDisplayController()->GetDisplayMatching(match_rect);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display ScreenAsh::GetPrimaryDisplay() const {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DisplayController::GetPrimaryDisplay();
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ScreenAsh::AddObserver(gfx::DisplayObserver* observer) {
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ScreenAsh::RemoveObserver(gfx::DisplayObserver* observer) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
169