12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/display/display_manager.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <algorithm> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <cmath> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/ash_switches.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ash/display/display_layout_store.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/display/screen_ash.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/auto_reset.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/metrics/histogram.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/ash_strings.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/display.h" 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/gfx/display_observer.h" 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/gfx/font_render_params.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/screen.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size_conversions.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_X11) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/x/x11_util.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS) 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/display/display_configurator_animation.h" 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/sys_info.h" 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/windows_version.h" 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ash { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::vector<gfx::Display> DisplayList; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::vector<DisplayInfo> DisplayInfoList; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// We need to keep this in order for unittests to tell if 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the object in gfx::Screen::GetScreenByType is for shutdown. 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::Screen* screen_for_shutdown = NULL; 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The number of pixels to overlap between the primary and secondary displays, 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// in case that the offset value is too large. 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int kMinimumOverlapForInvalidOffset = 100; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// List of value UI Scale values. Scales for 2x are equivalent to 640, 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 800, 1024, 1280, 1440, 1600 and 1920 pixel width respectively on 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 2560 pixel width 2x density display. Please see crbug.com/233375 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// for the full list of resolutions. 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const float kUIScalesFor2x[] = 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) {0.5f, 0.625f, 0.8f, 1.0f, 1.125f, 1.25f, 1.5f, 2.0f}; 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const float kUIScalesFor1_25x[] = {0.5f, 0.625f, 0.8f, 1.0f, 1.25f }; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const float kUIScalesFor1280[] = {0.5f, 0.625f, 0.8f, 1.0f, 1.125f }; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const float kUIScalesFor1366[] = {0.5f, 0.6f, 0.75f, 1.0f, 1.125f }; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct DisplaySortFunctor { 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool operator()(const gfx::Display& a, const gfx::Display& b) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return a.id() < b.id(); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct DisplayInfoSortFunctor { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool operator()(const DisplayInfo& a, const DisplayInfo& b) { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return a.id() < b.id(); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct DisplayModeMatcher { 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayModeMatcher(const DisplayMode& target_mode) 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : target_mode(target_mode) {} 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool operator()(const DisplayMode& mode) { 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return target_mode.IsEquivalent(mode); 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayMode target_mode; 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct ScaleComparator { 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit ScaleComparator(float s) : scale(s) {} 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool operator()(float s) const { 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const float kEpsilon = 0.0001f; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::abs(scale - s) < kEpsilon; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) float scale; 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Display& GetInvalidDisplay() { 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static gfx::Display* invalid_display = new gfx::Display(); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *invalid_display; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MaybeInitInternalDisplay(int64 id) { 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CommandLine* command_line = CommandLine::ForCurrentProcess(); 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (command_line->HasSwitch(switches::kAshUseFirstDisplayAsInternal)) 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gfx::Display::SetInternalDisplayId(id); 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Scoped objects used to either create or close the non desktop window 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// at specific timing. 1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class NonDesktopDisplayUpdater { 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NonDesktopDisplayUpdater(DisplayManager* manager, 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DisplayManager::Delegate* delegate) 12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : manager_(manager), 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) delegate_(delegate), 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) enabled_(manager_->second_display_mode() != DisplayManager::EXTENDED && 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) manager_->non_desktop_display().is_valid()) { 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ~NonDesktopDisplayUpdater() { 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!delegate_) 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (enabled_) { 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DisplayInfo display_info = manager_->GetDisplayInfo( 1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) manager_->non_desktop_display().id()); 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) delegate_->CreateOrUpdateNonDesktopDisplay(display_info); 13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) delegate_->CloseNonDesktopDisplay(); 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool enabled() const { return enabled_; } 14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DisplayManager* manager_; 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DisplayManager::Delegate* delegate_; 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool enabled_; 1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NonDesktopDisplayUpdater); 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::string; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::vector; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayManager::DisplayManager() 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : delegate_(NULL), 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_ash_(new ScreenAsh), 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_(screen_ash_.get()), 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch layout_store_(new DisplayLayoutStore), 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch first_display_id_(gfx::Display::kInvalidDisplayID), 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_connected_displays_(0), 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) force_bounds_changed_(false), 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) change_display_upon_host_resize_(false), 1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) second_display_mode_(EXTENDED), 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) mirrored_display_id_(gfx::Display::kInvalidDisplayID), 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) registered_internal_display_rotation_lock_(false), 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) registered_internal_display_rotation_(gfx::Display::ROTATE_0) { 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS) 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Enable only on the device so that DisplayManagerFontTest passes. 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (base::SysInfo::IsRunningOnChromeOS()) 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DisplayInfo::SetUse125DSFForUIScaling(true); 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_ash_.get()); 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Screen* current_native = 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE); 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If there is no native, or the native was for shutdown, 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // use ash's screen. 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!current_native || 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_native == screen_for_shutdown) { 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_ash_.get()); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayManager::~DisplayManager() { 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(OS_CHROMEOS) 18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Reset the font params. 19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::SetFontRenderParamsDeviceScaleFactor(1.0f); 19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::vector<float> DisplayManager::GetScalesForDisplay( 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DisplayInfo& info) { 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define ASSIGN_ARRAY(v, a) v.assign(a, a + arraysize(a)) 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<float> ret; 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (info.device_scale_factor() == 2.0f) { 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSIGN_ARRAY(ret, kUIScalesFor2x); 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ret; 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (info.device_scale_factor() == 1.25f) { 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSIGN_ARRAY(ret, kUIScalesFor1_25x); 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ret; 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch (info.bounds_in_native().width()) { 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case 1280: 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSIGN_ARRAY(ret, kUIScalesFor1280); 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case 1366: 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSIGN_ARRAY(ret, kUIScalesFor1366); 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSIGN_ARRAY(ret, kUIScalesFor1280); 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS) 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (base::SysInfo::IsRunningOnChromeOS()) 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED() << "Unknown resolution:" << info.ToString(); 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ret; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)float DisplayManager::GetNextUIScale(const DisplayInfo& info, bool up) { 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) float scale = info.configured_ui_scale(); 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<float> scales = GetScalesForDisplay(info); 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < scales.size(); ++i) { 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ScaleComparator(scales[i])(scale)) { 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (up && i != scales.size() - 1) 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scales[i + 1]; 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!up && i != 0) 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scales[i - 1]; 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scales[i]; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fallback to 1.0f if the |scale| wasn't in the list. 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 1.0f; 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool DisplayManager::InitFromCommandLine() { 2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DisplayInfoList info_list; 24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CommandLine* command_line = CommandLine::ForCurrentProcess(); 2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!command_line->HasSwitch(switches::kAshHostWindowBounds)) 2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; 24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const string size_str = 24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) command_line->GetSwitchValueASCII(switches::kAshHostWindowBounds); 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch vector<string> parts; 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::SplitString(size_str, ',', &parts); 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (vector<string>::const_iterator iter = parts.begin(); 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iter != parts.end(); ++iter) { 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch info_list.push_back(DisplayInfo::CreateFromSpec(*iter)); 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci info_list.back().set_native(true); 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) MaybeInitInternalDisplay(info_list[0].id()); 25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info_list.size() > 1 && 25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) command_line->HasSwitch(switches::kAshEnableSoftwareMirroring)) { 2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SetSecondDisplayMode(MIRRORING); 26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OnNativeDisplaysChanged(info_list); 2620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return true; 2630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void DisplayManager::InitDefaultDisplay() { 2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DisplayInfoList info_list; 2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) info_list.push_back(DisplayInfo::CreateFromSpec(std::string())); 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci info_list.back().set_native(true); 2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) MaybeInitInternalDisplay(info_list[0].id()); 2700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) OnNativeDisplaysChanged(info_list); 2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void DisplayManager::InitFontParams() { 27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(OS_CHROMEOS) 27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!HasInternalDisplay()) 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const DisplayInfo& display_info = 27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) GetDisplayInfo(gfx::Display::InternalDisplayId()); 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::SetFontRenderParamsDeviceScaleFactor( 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci display_info.GetEffectiveDeviceScaleFactor()); 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif // OS_CHROMEOS 28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// static 285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid DisplayManager::UpdateDisplayBoundsForLayoutById( 286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const DisplayLayout& layout, 287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const gfx::Display& primary_display, 288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int64 secondary_display_id) { 289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK_NE(gfx::Display::kInvalidDisplayID, secondary_display_id); 290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch UpdateDisplayBoundsForLayout( 291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch layout, primary_display, 292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Shell::GetInstance()->display_manager()-> 293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch FindDisplayForId(secondary_display_id)); 294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DisplayManager::IsActiveDisplay(const gfx::Display& display) const { 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DisplayList::const_iterator iter = displays_.begin(); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != displays_.end(); ++iter) { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter).id() == display.id()) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DisplayManager::HasInternalDisplay() const { 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Display::InternalDisplayId() != gfx::Display::kInvalidDisplayID; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DisplayManager::IsInternalDisplayId(int64 id) const { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Display::InternalDisplayId() == id; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)DisplayLayout DisplayManager::GetCurrentDisplayLayout() { 3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(2U, num_connected_displays()); 3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Invert if the primary was swapped. 3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (num_connected_displays() > 1) { 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DisplayIdPair pair = GetCurrentDisplayIdPair(); 3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return layout_store_->ComputeDisplayLayoutForDisplayIdPair(pair); 3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED() << "DisplayLayout is requested for single display"; 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // On release build, just fallback to default instead of blowing up. 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DisplayLayout layout = 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) layout_store_->default_display_layout(); 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) layout.primary_id = displays_[0].id(); 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return layout; 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const { 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsMirrored()) { 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (software_mirroring_enabled()) { 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CHECK_EQ(2u, num_connected_displays()); 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This comment is to make it easy to distinguish the crash 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // between two checks. 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CHECK_EQ(1u, displays_.size()); 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return std::make_pair(displays_[0].id(), mirrored_display_id_); 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 3388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CHECK_GE(2u, displays_.size()); 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 id_at_zero = displays_[0].id(); 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (id_at_zero == gfx::Display::InternalDisplayId() || 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) id_at_zero == first_display_id()) { 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return std::make_pair(id_at_zero, displays_[1].id()); 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return std::make_pair(displays_[1].id(), id_at_zero); 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DisplayManager::SetLayoutForCurrentDisplays( 3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const DisplayLayout& layout_relative_to_primary) { 3518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_EQ(2U, GetNumDisplays()); 3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (GetNumDisplays() < 2) 3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Display& primary = screen_->GetPrimaryDisplay(); 3558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const DisplayIdPair pair = GetCurrentDisplayIdPair(); 3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Invert if the primary was swapped. 3578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DisplayLayout to_set = pair.first == primary.id() ? 3588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) layout_relative_to_primary : layout_relative_to_primary.Invert(); 3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DisplayLayout current_layout = 3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) layout_store_->GetRegisteredDisplayLayout(pair); 3628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (to_set.position != current_layout.position || 3638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) to_set.offset != current_layout.offset) { 3648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) to_set.primary_id = primary.id(); 3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) layout_store_->RegisterLayoutForDisplayIdPair( 3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) pair.first, pair.second, to_set); 3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (delegate_) 3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) delegate_->PreDisplayConfigurationChange(false); 3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // PreDisplayConfigurationChange(false); 3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // TODO(oshima): Call UpdateDisplays instead. 3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const DisplayLayout layout = GetCurrentDisplayLayout(); 3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UpdateDisplayBoundsForLayoutById( 3738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) layout, primary, 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScreenUtil::GetSecondaryDisplay().id()); 3758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Primary's bounds stay the same. Just notify bounds change 3778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // on the secondary. 378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) screen_ash_->NotifyMetricsChanged( 379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScreenUtil::GetSecondaryDisplay(), 380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS | 381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA); 3828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (delegate_) 3838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) delegate_->PostDisplayConfigurationChange(); 3848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const gfx::Display& DisplayManager::GetDisplayForId(int64 id) const { 388ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Display* display = 389ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const_cast<DisplayManager*>(this)->FindDisplayForId(id); 390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return display ? *display : GetInvalidDisplay(); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const gfx::Display& DisplayManager::FindDisplayContainingPoint( 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Point& point_in_screen) const { 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DisplayList::const_iterator iter = displays_.begin(); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != displays_.end(); ++iter) { 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Display& display = *iter; 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (display.bounds().Contains(point_in_screen)) 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return display; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetInvalidDisplay(); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 404ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool DisplayManager::UpdateWorkAreaOfDisplay(int64 display_id, 405ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const gfx::Insets& insets) { 406ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Display* display = FindDisplayForId(display_id); 407ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(display); 408ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Rect old_work_area = display->work_area(); 409ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch display->UpdateWorkAreaFromInsets(insets); 410ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return old_work_area != display->work_area(); 411ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 412ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayManager::SetOverscanInsets(int64 display_id, 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Insets& insets_in_dip) { 415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch display_info_[display_id].SetOverscanInsets(insets_in_dip); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfoList display_info_list; 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DisplayList::const_iterator iter = displays_.begin(); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != displays_.end(); ++iter) { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_list.push_back(GetDisplayInfo(iter->id())); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddMirrorDisplayInfoIfAny(&display_info_list); 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateDisplays(display_info_list); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayManager::SetDisplayRotation(int64 display_id, 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Display::Rotation rotation) { 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfoList display_info_list; 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DisplayList::const_iterator iter = displays_.begin(); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != displays_.end(); ++iter) { 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfo info = GetDisplayInfo(iter->id()); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (info.id() == display_id) { 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (info.rotation() == rotation) 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.set_rotation(rotation); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_list.push_back(info); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddMirrorDisplayInfoIfAny(&display_info_list); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateDisplays(display_info_list); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayManager::SetDisplayUIScale(int64 display_id, 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float ui_scale) { 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsDisplayUIScalingEnabled() || 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Display::InternalDisplayId() != display_id) { 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(mukai): merge this implementation into SetDisplayMode(). 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfoList display_info_list; 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DisplayList::const_iterator iter = displays_.begin(); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != displays_.end(); ++iter) { 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfo info = GetDisplayInfo(iter->id()); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (info.id() == display_id) { 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (info.configured_ui_scale() == ui_scale) 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<float> scales = GetScalesForDisplay(info); 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScaleComparator comparator(ui_scale); 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (std::find_if(scales.begin(), scales.end(), comparator) == 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scales.end()) { 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) info.set_configured_ui_scale(ui_scale); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_list.push_back(info); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddMirrorDisplayInfoIfAny(&display_info_list); 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateDisplays(display_info_list); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DisplayManager::SetDisplayResolution(int64 display_id, 472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const gfx::Size& resolution) { 473a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK_NE(gfx::Display::InternalDisplayId(), display_id); 474a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (gfx::Display::InternalDisplayId() == display_id) 475a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const DisplayInfo& display_info = GetDisplayInfo(display_id); 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<DisplayMode>& modes = display_info.display_modes(); 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(0u, modes.size()); 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayMode target_mode; 4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_mode.size = resolution; 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<DisplayMode>::const_iterator iter = 4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::find_if(modes.begin(), modes.end(), DisplayModeMatcher(target_mode)); 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter == modes.end()) { 4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LOG(WARNING) << "Unsupported resolution was requested:" 4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resolution.ToString(); 4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes_[display_id] = *iter; 489effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 4904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (base::SysInfo::IsRunningOnChromeOS()) 491c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Shell::GetInstance()->display_configurator()->OnConfigurationChanged(); 492a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 493a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 494a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool DisplayManager::SetDisplayMode(int64 display_id, 4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DisplayMode& display_mode) { 4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (IsInternalDisplayId(display_id)) { 4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetDisplayUIScale(display_id, display_mode.ui_scale); 4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayInfoList display_info_list; 5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool display_property_changed = false; 5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool resolution_changed = false; 5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (DisplayList::const_iterator iter = displays_.begin(); 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) iter != displays_.end(); ++iter) { 5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayInfo info = GetDisplayInfo(iter->id()); 5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (info.id() == display_id) { 5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<DisplayMode>& modes = info.display_modes(); 5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<DisplayMode>::const_iterator iter = 5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::find_if(modes.begin(), 5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) modes.end(), 5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayModeMatcher(display_mode)); 5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (iter == modes.end()) { 5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(WARNING) << "Unsupported resolution was requested:" 5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << display_mode.size.ToString(); 5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) display_modes_[display_id] = *iter; 5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (info.bounds_in_native().size() != display_mode.size) 5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resolution_changed = true; 5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (info.device_scale_factor() != display_mode.device_scale_factor) { 5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) info.set_device_scale_factor(display_mode.device_scale_factor); 5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) display_property_changed = true; 5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) display_info_list.push_back(info); 5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (display_property_changed) { 5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) AddMirrorDisplayInfoIfAny(&display_info_list); 5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UpdateDisplays(display_info_list); 5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS) 5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (resolution_changed && base::SysInfo::IsRunningOnChromeOS()) 5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Shell::GetInstance()->display_configurator()->OnConfigurationChanged(); 5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return resolution_changed; 5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayManager::RegisterDisplayProperty( 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 display_id, 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Display::Rotation rotation, 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float ui_scale, 544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const gfx::Insets* overscan_insets, 545effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const gfx::Size& resolution_in_pixels, 5466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) float device_scale_factor, 547effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui::ColorCalibrationProfile color_profile) { 5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (display_info_.find(display_id) == display_info_.end()) 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_info_[display_id] = DisplayInfo(display_id, std::string(), false); 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_[display_id].set_rotation(rotation); 552effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch display_info_[display_id].SetColorProfile(color_profile); 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Just in case the preference file was corrupted. 5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(mukai): register |display_modes_| here as well, so the lookup for the 5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // default mode in GetActiveModeForDisplayId() gets much simpler. 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (0.5f <= ui_scale && ui_scale <= 2.0f) 557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) display_info_[display_id].set_configured_ui_scale(ui_scale); 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (overscan_insets) 559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch display_info_[display_id].SetOverscanInsets(*overscan_insets); 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!resolution_in_pixels.IsEmpty()) { 5616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(!IsInternalDisplayId(display_id)); 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Default refresh rate, until OnNativeDisplaysChanged() updates us with the 5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // actual display info, is 60 Hz. 5646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DisplayMode mode(resolution_in_pixels, 60.0f, false, false); 5656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mode.device_scale_factor = device_scale_factor; 5666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) display_modes_[display_id] = mode; 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)DisplayMode DisplayManager::GetActiveModeForDisplayId(int64 display_id) const { 5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayMode selected_mode; 5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (GetSelectedModeForDisplayId(display_id, &selected_mode)) 5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return selected_mode; 5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If 'selected' mode is empty, it should return the default mode. This means 5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the native mode for the external display. Unfortunately this is not true 5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // for the internal display because restoring UI-scale doesn't register the 5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // restored mode to |display_mode_|, so it needs to look up the mode whose 5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // UI-scale value matches. See the TODO in RegisterDisplayProperty(). 5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DisplayInfo& info = GetDisplayInfo(display_id); 5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<DisplayMode>& display_modes = info.display_modes(); 5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (IsInternalDisplayId(display_id)) { 5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (size_t i = 0; i < display_modes.size(); ++i) { 5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (info.configured_ui_scale() == display_modes[i].ui_scale) 5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return display_modes[i]; 5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (size_t i = 0; i < display_modes.size(); ++i) { 5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (display_modes[i].native) 5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return display_modes[i]; 5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return selected_mode; 5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void DisplayManager::RegisterDisplayRotationProperties(bool rotation_lock, 59803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::Display::Rotation rotation) { 59903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (delegate_) 60003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) delegate_->PreDisplayConfigurationChange(false); 60103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) registered_internal_display_rotation_lock_ = rotation_lock; 60203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) registered_internal_display_rotation_ = rotation; 60303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (delegate_) 60403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) delegate_->PostDisplayConfigurationChange(); 60503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 60603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool DisplayManager::GetSelectedModeForDisplayId(int64 id, 6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DisplayMode* mode_out) const { 6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::map<int64, DisplayMode>::const_iterator iter = display_modes_.find(id); 6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter == display_modes_.end()) 611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *mode_out = iter->second; 613a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DisplayManager::IsDisplayUIScalingEnabled() const { 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetDisplayIdForUIScaling() != gfx::Display::kInvalidDisplayID; 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Insets DisplayManager::GetOverscanInsets(int64 display_id) const { 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<int64, DisplayInfo>::const_iterator it = 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_.find(display_id); 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (it != display_info_.end()) ? 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->second.overscan_insets_in_dip() : gfx::Insets(); 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 627effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DisplayManager::SetColorCalibrationProfile( 628effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int64 display_id, 629effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui::ColorCalibrationProfile profile) { 630effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 631effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!display_info_[display_id].IsColorProfileAvailable(profile)) 632effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 633effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 634effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (delegate_) 635effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch delegate_->PreDisplayConfigurationChange(false); 636e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Just sets color profile if it's not running on ChromeOS (like tests). 637e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!base::SysInfo::IsRunningOnChromeOS() || 638c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile( 639effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch display_id, profile)) { 640effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch display_info_[display_id].SetColorProfile(profile); 641effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_ENUMERATION( 642effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "ChromeOS.Display.ColorProfile", profile, ui::NUM_COLOR_PROFILES); 643effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 644effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (delegate_) 645effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch delegate_->PostDisplayConfigurationChange(); 646effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif 647effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 648effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayManager::OnNativeDisplaysChanged( 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<DisplayInfo>& updated_displays) { 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (updated_displays.empty()) { 6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG(1) << "OnNativeDisplaysChanged(0): # of current displays=" 653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << displays_.size(); 6547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If the device is booted without display, or chrome is started 6557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // without --ash-host-window-bounds on linux desktop, use the 6567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // default display. 6577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (displays_.empty()) { 6587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::vector<DisplayInfo> init_displays; 6597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch init_displays.push_back(DisplayInfo::CreateFromSpec(std::string())); 6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MaybeInitInternalDisplay(init_displays[0].id()); 6617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OnNativeDisplaysChanged(init_displays); 6627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 6637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Otherwise don't update the displays when all displays are disconnected. 6647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // This happens when: 6657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // - the device is idle and powerd requested to turn off all displays. 6667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // - the device is suspended. (kernel turns off all displays) 6677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // - the internal display's brightness is set to 0 and no external 6687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // display is connected. 6697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // - the internal display's brightness is 0 and external display is 6707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // disconnected. 6717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // The display will be updated when one of displays is turned on, and the 6727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // display list will be updated correctly. 6737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) first_display_id_ = updated_displays[0].id(); 6777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::set<gfx::Point> origins; 6787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (updated_displays.size() == 1) { 680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << "OnNativeDisplaysChanged(1):" << updated_displays[0].ToString(); 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << "OnNativeDisplaysChanged(" << updated_displays.size() 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << ") [0]=" << updated_displays[0].ToString() 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << ", [1]=" << updated_displays[1].ToString(); 685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool internal_display_connected = false; 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_connected_displays_ = updated_displays.size(); 6891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mirrored_display_id_ = gfx::Display::kInvalidDisplayID; 6901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) non_desktop_display_ = gfx::Display(); 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfoList new_display_info_list; 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DisplayInfoList::const_iterator iter = updated_displays.begin(); 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != updated_displays.end(); 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) { 695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!internal_display_connected) 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal_display_connected = IsInternalDisplayId(iter->id()); 6977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Mirrored monitors have the same origins. 69868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Point origin = iter->bounds_in_native().origin(); 6997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (origins.find(origin) != origins.end()) { 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InsertAndUpdateDisplayInfo(*iter); 7011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mirrored_display_id_ = iter->id(); 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 7037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch origins.insert(origin); 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_display_info_list.push_back(*iter); 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayMode new_mode; 7085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_mode.size = iter->bounds_in_native().size(); 7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_mode.device_scale_factor = iter->device_scale_factor(); 7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_mode.ui_scale = iter->configured_ui_scale(); 7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<DisplayMode>& display_modes = iter->display_modes(); 7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is empty the displays are initialized from InitFromCommandLine. 7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!display_modes.size()) 7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<DisplayMode>::const_iterator display_modes_iter = 7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::find_if(display_modes.begin(), 7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes.end(), 7185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DisplayModeMatcher(new_mode)); 7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Update the actual resolution selected as the resolution request may fail. 7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (display_modes_iter == display_modes.end()) 7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes_.erase(iter->id()); 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (display_modes_.find(iter->id()) != display_modes_.end()) 7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes_[iter->id()] = *display_modes_iter; 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (HasInternalDisplay() && 726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !internal_display_connected && 727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) display_info_.find(gfx::Display::InternalDisplayId()) == 728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) display_info_.end()) { 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DisplayInfo internal_display_info( 730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Display::InternalDisplayId(), 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME), 732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false /*Internal display must not have overscan */); 733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) internal_display_info.SetBounds(gfx::Rect(0, 0, 800, 600)); 734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) display_info_[gfx::Display::InternalDisplayId()] = internal_display_info; 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateDisplays(new_display_info_list); 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayManager::UpdateDisplays() { 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfoList display_info_list; 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DisplayList::const_iterator iter = displays_.begin(); 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != displays_.end(); ++iter) { 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_list.push_back(GetDisplayInfo(iter->id())); 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddMirrorDisplayInfoIfAny(&display_info_list); 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateDisplays(display_info_list); 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayManager::UpdateDisplays( 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<DisplayInfo>& updated_display_info_list) { 7517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN) 752cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_EQ(1u, updated_display_info_list.size()) << 753cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ": Multiple display test does not work on Windows bots. Please " 754cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "skip (don't disable) the test using SupportsMultipleDisplays()"; 7557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 7567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfoList new_display_info_list = updated_display_info_list; 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::sort(displays_.begin(), displays_.end(), DisplaySortFunctor()); 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::sort(new_display_info_list.begin(), 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_display_info_list.end(), 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfoSortFunctor()); 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayList removed_displays; 763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::map<size_t, uint32_t> display_changes; 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<size_t> added_display_indices; 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayList::iterator curr_iter = displays_.begin(); 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayList new_displays; 770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Use the internal display or 1st as the mirror source, then scale 772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // the root window so that it matches the external display's 773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // resolution. This is necessary in order for scaling to work while 774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // mirrored. 7751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int64 non_desktop_display_id = gfx::Display::kInvalidDisplayID; 7761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 7771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (second_display_mode_ != EXTENDED && new_display_info_list.size() == 2) { 7784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool zero_is_source = 7794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) first_display_id_ == new_display_info_list[0].id() || 7804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Display::InternalDisplayId() == new_display_info_list[0].id(); 7811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (second_display_mode_ == MIRRORING) { 7821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mirrored_display_id_ = new_display_info_list[zero_is_source ? 1 : 0].id(); 7831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) non_desktop_display_id = mirrored_display_id_; 7841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 7851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // TODO(oshima|bshe): The virtual keyboard is currently assigned to 7861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // the 1st display. 7871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) non_desktop_display_id = 7881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new_display_info_list[zero_is_source ? 0 : 1].id(); 7891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 79190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (curr_iter != displays_.end() || 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_info_iter != new_display_info_list.end()) { 79490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (new_info_iter != new_display_info_list.end() && 7951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) non_desktop_display_id == new_info_iter->id()) { 796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DisplayInfo info = *new_info_iter; 797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch info.SetOverscanInsets(gfx::Insets()); 798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) InsertAndUpdateDisplayInfo(info); 7991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) non_desktop_display_ = 8001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CreateDisplayFromDisplayInfoById(non_desktop_display_id); 80190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++new_info_iter; 8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Remove existing external display if it is going to be used as 8031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // non desktop. 80490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (curr_iter != displays_.end() && 8051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) curr_iter->id() == non_desktop_display_id) { 80690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) removed_displays.push_back(*curr_iter); 80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++curr_iter; 80890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 80990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 81090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 81190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (curr_iter == displays_.end()) { 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // more displays in new list. 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) added_display_indices.push_back(new_displays.size()); 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InsertAndUpdateDisplayInfo(*new_info_iter); 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_displays.push_back( 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDisplayFromDisplayInfoById(new_info_iter->id())); 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++new_info_iter; 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (new_info_iter == new_display_info_list.end()) { 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // more displays in current list. 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) removed_displays.push_back(*curr_iter); 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++curr_iter; 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (curr_iter->id() == new_info_iter->id()) { 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Display& current_display = *curr_iter; 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Copy the info because |CreateDisplayFromInfo| updates the instance. 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DisplayInfo current_display_info = 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayInfo(current_display.id()); 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InsertAndUpdateDisplayInfo(*new_info_iter); 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Display new_display = 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDisplayFromDisplayInfoById(new_info_iter->id()); 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DisplayInfo& new_display_info = GetDisplayInfo(new_display.id()); 832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32_t metrics = gfx::DisplayObserver::DISPLAY_METRIC_NONE; 834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // At that point the new Display objects we have are not entirely updated, 836cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // they are missing the translation related to the Display disposition in 837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the layout. 838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Using display.bounds() and display.work_area() would fail most of the 839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // time. 840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (force_bounds_changed_ || (current_display_info.bounds_in_native() != 841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new_display_info.bounds_in_native()) || 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (current_display_info.size_in_pixel() != 843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new_display.GetSizeInPixel())) { 844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metrics |= gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS | 845cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA; 846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (current_display.device_scale_factor() != 849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new_display.device_scale_factor()) { 850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metrics |= gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; 851cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 852cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (current_display.rotation() != new_display.rotation()) 854cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metrics |= gfx::DisplayObserver::DISPLAY_METRIC_ROTATION; 855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 856cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (metrics != gfx::DisplayObserver::DISPLAY_METRIC_NONE) { 857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) display_changes.insert( 858cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::pair<size_t, uint32_t>(new_displays.size(), metrics)); 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_display.UpdateWorkAreaFromInsets(current_display.GetWorkAreaInsets()); 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_displays.push_back(new_display); 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++curr_iter; 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++new_info_iter; 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (curr_iter->id() < new_info_iter->id()) { 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // more displays in current list between ids, which means it is deleted. 8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) removed_displays.push_back(*curr_iter); 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++curr_iter; 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // more displays in new list between ids, which means it is added. 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) added_display_indices.push_back(new_displays.size()); 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InsertAndUpdateDisplayInfo(*new_info_iter); 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_displays.push_back( 8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateDisplayFromDisplayInfoById(new_info_iter->id())); 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++new_info_iter; 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<NonDesktopDisplayUpdater> non_desktop_display_updater( 8801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new NonDesktopDisplayUpdater(this, delegate_)); 88190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 882f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Clear focus if the display has been removed, but don't clear focus if 883f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the destkop has been moved from one display to another 884f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // (mirror -> docked, docked -> single internal). 885f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool clear_focus = 886f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !removed_displays.empty() && 887f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !(removed_displays.size() == 1 && added_display_indices.size() == 1); 8887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (delegate_) 889f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->PreDisplayConfigurationChange(clear_focus); 890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Do not update |displays_| if there's nothing to be updated. Without this, 8921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // it will not update the display layout, which causes the bug 8931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // http://crbug.com/155948. 8941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (display_changes.empty() && added_display_indices.empty() && 8951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci removed_displays.empty()) { 8961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // When changing from software mirroring mode to sinlge display mode, it 8971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // is possible there is no need to update |displays_| and we early out 8981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // here. But we still want to run the PostDisplayConfigurationChange() 8991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // cause there are some clients need to act on this, e.g. 9001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TouchTransformerController needs to adjust the TouchTransformer when 9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // switching from dual displays to single display. 9021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (delegate_) 9031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->PostDisplayConfigurationChange(); 9041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 9051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 9061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 907eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t updated_index; 908eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (UpdateSecondaryDisplayBoundsForLayout(&new_displays, &updated_index) && 909eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::find(added_display_indices.begin(), 910eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch added_display_indices.end(), 911cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) updated_index) == added_display_indices.end()) { 912cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32_t metrics = gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS | 913cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA; 914cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (display_changes.find(updated_index) != display_changes.end()) 915cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) metrics |= display_changes[updated_index]; 916cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 917cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) display_changes[updated_index] = metrics; 918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) displays_ = new_displays; 9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::AutoReset<bool> resetter(&change_display_upon_host_resize_, false); 923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Temporarily add displays to be removed because display object 9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // being removed are accessed during shutting down the root. 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) displays_.insert(displays_.end(), removed_displays.begin(), 9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) removed_displays.end()); 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DisplayList::const_reverse_iterator iter = removed_displays.rbegin(); 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != removed_displays.rend(); ++iter) { 9315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_ash_->NotifyDisplayRemoved(displays_.back()); 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) displays_.pop_back(); 9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Close the non desktop window here to avoid creating two compositor on 9357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // one display. 9361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!non_desktop_display_updater->enabled()) 9371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) non_desktop_display_updater.reset(); 9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::vector<size_t>::iterator iter = added_display_indices.begin(); 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != added_display_indices.end(); ++iter) { 9405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_ash_->NotifyDisplayAdded(displays_[*iter]); 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Create the non destkop window after all displays are added so that 9437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // it can mirror the display newly added. This can happen when switching 9447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // from dock mode to software mirror mode. 9451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) non_desktop_display_updater.reset(); 946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (std::map<size_t, uint32_t>::iterator iter = display_changes.begin(); 947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) iter != display_changes.end(); 948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++iter) { 949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) screen_ash_->NotifyMetricsChanged(displays_[iter->first], iter->second); 9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (delegate_) 9527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch delegate_->PostDisplayConfigurationChange(); 9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_X11) && defined(OS_CHROMEOS) 955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!display_changes.empty() && base::SysInfo::IsRunningOnChromeOS()) 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ClearX11DefaultRootWindow(); 9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 960ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst gfx::Display& DisplayManager::GetDisplayAt(size_t index) const { 961ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK_LT(index, displays_.size()); 962ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return displays_[index]; 9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const gfx::Display& DisplayManager::GetPrimaryDisplayCandidate() const { 9661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (GetNumDisplays() == 1) 9673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return displays_[0]; 9683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DisplayLayout layout = layout_store_->GetRegisteredDisplayLayout( 9693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetCurrentDisplayIdPair()); 9703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return GetDisplayForId(layout.primary_id); 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t DisplayManager::GetNumDisplays() const { 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return displays_.size(); 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DisplayManager::IsMirrored() const { 9781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return mirrored_display_id_ != gfx::Display::kInvalidDisplayID; 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { 9820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK_NE(gfx::Display::kInvalidDisplayID, display_id); 9830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<int64, DisplayInfo>::const_iterator iter = 9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_.find(display_id); 986868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK(iter != display_info_.end()) << display_id; 9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return iter->second; 9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DisplayManager::GetDisplayNameForId(int64 id) { 9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (id == gfx::Display::kInvalidDisplayID) 9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); 9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<int64, DisplayInfo>::const_iterator iter = display_info_.find(id); 9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != display_info_.end() && !iter->second.name().empty()) 9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return iter->second.name(); 9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf("Display %d", static_cast<int>(id)); 9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1001eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint64 DisplayManager::GetDisplayIdForUIScaling() const { 1002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // UI Scaling is effective only on internal display. 1003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 display_id = gfx::Display::InternalDisplayId(); 1004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN) 1005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch display_id = first_display_id(); 1006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 1007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return display_id; 1008eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 101090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DisplayManager::SetMirrorMode(bool mirrored) { 101190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (num_connected_displays() <= 1) 101290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 101390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 101490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS) 10154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (base::SysInfo::IsRunningOnChromeOS()) { 1016c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ui::MultipleDisplayState new_state = 1017c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch mirrored ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR : 1018c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; 1019c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Shell::GetInstance()->display_configurator()->SetDisplayMode(new_state); 102090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 102190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 102290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 10231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // This is fallback path to emulate mirroroing on desktop. 10241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SetSecondDisplayMode(mirrored ? MIRRORING : EXTENDED); 102590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DisplayInfoList display_info_list; 102690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int count = 0; 102790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (std::map<int64, DisplayInfo>::const_iterator iter = 102890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) display_info_.begin(); 102990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) count < 2; ++iter, ++count) { 103090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) display_info_list.push_back(GetDisplayInfo(iter->second.id())); 103190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 103290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UpdateDisplays(display_info_list); 103390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS) 10345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (Shell::GetInstance()->display_configurator_animation()) { 10355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Shell::GetInstance()->display_configurator_animation()-> 103690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StartFadeInAnimation(); 103790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 103890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 103990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 104090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 104190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DisplayManager::AddRemoveDisplay() { 104290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!displays_.empty()); 104390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<DisplayInfo> new_display_info_list; 10443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const DisplayInfo& first_display = GetDisplayInfo(displays_[0].id()); 10457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch new_display_info_list.push_back(first_display); 104690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Add if there is only one display connected. 104790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (num_connected_displays() == 1) { 104890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Layout the 2nd display below the primary as with the real device. 104968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect host_bounds = first_display.bounds_in_native(); 105090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_display_info_list.push_back(DisplayInfo::CreateFromSpec( 105190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::StringPrintf( 105290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "%d+%d-500x400", host_bounds.x(), host_bounds.bottom()))); 105390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 105490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) num_connected_displays_ = new_display_info_list.size(); 10551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mirrored_display_id_ = gfx::Display::kInvalidDisplayID; 1056f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) non_desktop_display_ = gfx::Display(); 105790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UpdateDisplays(new_display_info_list); 105890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 105990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 106090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DisplayManager::ToggleDisplayScaleFactor() { 106190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!displays_.empty()); 106290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<DisplayInfo> new_display_info_list; 106390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (DisplayList::const_iterator iter = displays_.begin(); 106490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) iter != displays_.end(); ++iter) { 106590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DisplayInfo display_info = GetDisplayInfo(iter->id()); 106690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) display_info.set_device_scale_factor( 106790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); 106890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new_display_info_list.push_back(display_info); 106990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 1070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddMirrorDisplayInfoIfAny(&new_display_info_list); 107190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UpdateDisplays(new_display_info_list); 107290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 107390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_CHROMEOS) 107590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DisplayManager::SetSoftwareMirroring(bool enabled) { 10761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SetSecondDisplayMode(enabled ? MIRRORING : EXTENDED); 10771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1078cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1079cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool DisplayManager::SoftwareMirroringEnabled() const { 1080cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return software_mirroring_enabled(); 1081cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 10821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 10831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 10841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DisplayManager::SetSecondDisplayMode(SecondDisplayMode mode) { 10851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) second_display_mode_ = mode; 10861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mirrored_display_id_ = gfx::Display::kInvalidDisplayID; 10871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) non_desktop_display_ = gfx::Display(); 108890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 108990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool DisplayManager::UpdateDisplayBounds(int64 display_id, 10917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Rect& new_bounds) { 10927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (change_display_upon_host_resize_) { 10937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch display_info_[display_id].SetBounds(new_bounds); 10947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Don't notify observers if the mirrored window has changed. 10951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (software_mirroring_enabled() && mirrored_display_id_ == display_id) 10967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 1097ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Display* display = FindDisplayForId(display_id); 1098ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch display->SetSize(display_info_[display_id].size_in_pixel()); 1099cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) screen_ash_->NotifyMetricsChanged( 1100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *display, gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS); 11017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 11027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 11037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 11047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 11057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 110668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DisplayManager::CreateMirrorWindowIfAny() { 11071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NonDesktopDisplayUpdater updater(this, delegate_); 110868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 110968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DisplayManager::CreateScreenForShutdown() const { 11115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool native_is_ash = 11125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE) == 11135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_ash_.get(); 11145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete screen_for_shutdown; 11155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_for_shutdown = screen_ash_->CloneForShutdown(); 11165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, 11175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_for_shutdown); 11185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (native_is_ash) { 11195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, 11205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) screen_for_shutdown); 11215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 11225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 11235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1124ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochgfx::Display* DisplayManager::FindDisplayForId(int64 id) { 1125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (DisplayList::iterator iter = displays_.begin(); 1126ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch iter != displays_.end(); ++iter) { 1127ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if ((*iter).id() == id) 1128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return &(*iter); 1129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 1130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DLOG(WARNING) << "Could not find display:" << id; 1131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return NULL; 1132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void DisplayManager::AddMirrorDisplayInfoIfAny( 1135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<DisplayInfo>* display_info_list) { 11361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (software_mirroring_enabled() && IsMirrored()) 11371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) display_info_list->push_back(GetDisplayInfo(mirrored_display_id_)); 1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) { 11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<int64, DisplayInfo>::iterator info = 11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_.find(new_info.id()); 11435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (info != display_info_.end()) { 11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info->second.Copy(new_info); 11455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_[new_info.id()] = new_info; 11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_[new_info.id()].set_native(false); 11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_[new_info.id()].UpdateDisplaySize(); 1150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnDisplayInfoUpdated(display_info_[new_info.id()]); 1152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 1153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DisplayManager::OnDisplayInfoUpdated(const DisplayInfo& display_info) { 1155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 1156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui::ColorCalibrationProfile color_profile = display_info.color_profile(); 1157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (color_profile != ui::COLOR_PROFILE_STANDARD) { 1158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile( 1159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch display_info.id(), color_profile); 1160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 1161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif 11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { 11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(display_info_.find(id) != display_info_.end()); 11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DisplayInfo& display_info = display_info_[id]; 11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Display new_display(display_info.id()); 116968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect bounds_in_native(display_info.size_in_pixel()); 1170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor(); 11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Simply set the origin to (0,0). The primary display's origin is 11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // always (0,0) and the secondary display's bounds will be updated 1174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // in |UpdateSecondaryDisplayBoundsForLayout| called in |UpdateDisplay|. 11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_display.SetScaleAndBounds( 1176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_scale_factor, gfx::Rect(bounds_in_native.size())); 11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_display.set_rotation(display_info.rotation()); 11781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new_display.set_touch_support(display_info.touch_support()); 11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new_display; 11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool DisplayManager::UpdateSecondaryDisplayBoundsForLayout( 1183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DisplayList* displays, 1184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t* updated_index) const { 1185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (displays->size() != 2U) 1186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 1187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 id_at_zero = displays->at(0).id(); 1189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DisplayIdPair pair = 1190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (id_at_zero == first_display_id_ || 1191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch id_at_zero == gfx::Display::InternalDisplayId()) ? 1192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::make_pair(id_at_zero, displays->at(1).id()) : 11935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::make_pair(displays->at(1).id(), id_at_zero); 1194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DisplayLayout layout = 11957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch layout_store_->ComputeDisplayLayoutForDisplayIdPair(pair); 1196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Ignore if a user has a old format (should be extremely rare) 1198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // and this will be replaced with DCHECK. 1199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (layout.primary_id != gfx::Display::kInvalidDisplayID) { 1200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t primary_index, secondary_index; 1201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (displays->at(0).id() == layout.primary_id) { 1202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch primary_index = 0; 1203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch secondary_index = 1; 1204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 1205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch primary_index = 1; 1206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch secondary_index = 0; 1207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 12083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This function may be called before the secondary display is 12093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // registered. The bounds is empty in that case and will 12103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // return true. 1211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect bounds = 1212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetDisplayForId(displays->at(secondary_index).id()).bounds(); 1213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UpdateDisplayBoundsForLayout( 1214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch layout, displays->at(primary_index), &displays->at(secondary_index)); 1215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *updated_index = secondary_index; 1216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return bounds != displays->at(secondary_index).bounds(); 1217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 1219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// static 1222ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid DisplayManager::UpdateDisplayBoundsForLayout( 1223ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const DisplayLayout& layout, 1224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const gfx::Display& primary_display, 1225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Display* secondary_display) { 1226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); 1227ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const gfx::Rect& primary_bounds = primary_display.bounds(); 1229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const gfx::Rect& secondary_bounds = secondary_display->bounds(); 1230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Point new_secondary_origin = primary_bounds.origin(); 1231ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DisplayLayout::Position position = layout.position; 1233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Ignore the offset in case the secondary display doesn't share edges with 1235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // the primary display. 1236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int offset = layout.offset; 1237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (position == DisplayLayout::TOP || position == DisplayLayout::BOTTOM) { 1238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch offset = std::min( 1239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch offset, primary_bounds.width() - kMinimumOverlapForInvalidOffset); 1240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch offset = std::max( 1241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch offset, -secondary_bounds.width() + kMinimumOverlapForInvalidOffset); 1242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 1243ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch offset = std::min( 1244ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch offset, primary_bounds.height() - kMinimumOverlapForInvalidOffset); 1245ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch offset = std::max( 1246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch offset, -secondary_bounds.height() + kMinimumOverlapForInvalidOffset); 1247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 1248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch switch (position) { 1249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case DisplayLayout::TOP: 1250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new_secondary_origin.Offset(offset, -secondary_bounds.height()); 1251ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 1252ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case DisplayLayout::RIGHT: 1253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new_secondary_origin.Offset(primary_bounds.width(), offset); 1254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 1255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case DisplayLayout::BOTTOM: 1256ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new_secondary_origin.Offset(offset, primary_bounds.height()); 1257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 1258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case DisplayLayout::LEFT: 1259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new_secondary_origin.Offset(-secondary_bounds.width(), offset); 1260ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 1261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 1262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Insets insets = secondary_display->GetWorkAreaInsets(); 1263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch secondary_display->set_bounds( 1264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Rect(new_secondary_origin, secondary_bounds.size())); 1265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch secondary_display->UpdateWorkAreaFromInsets(insets); 1266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 1267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace ash 1269