desktop_screen_x11.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_screen_x11.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <X11/extensions/Xrandr.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/Xlib.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It clashes with out RootWindow. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef RootWindow 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/debug/trace_event.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window_tree_host.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/layout.h" 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/display/util/display_util.h" 200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/display/util/x11/edid_parser_x11.h" 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/events/platform/platform_event_source.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/display.h" 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/display_observer.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/native_widget_types.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/x/x11_types.h" 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_screen.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// The delay to perform configuration after RRNotify. See the comment 3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// in |Dispatch()|. 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int64 kConfigureDelayMs = 500; 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)float GetDeviceScaleFactor(int screen_pixels, int screen_mm) { 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int kCSSDefaultDPI = 96; 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const float kInchInMm = 25.4f; 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) float screen_inches = screen_mm / kInchInMm; 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) float screen_dpi = screen_pixels / screen_inches; 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) float scale = screen_dpi / kCSSDefaultDPI; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ui::GetImageScale(ui::GetSupportedScaleFactor(scale)); 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<gfx::Display> GetFallbackDisplayList() { 4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ::XDisplay* display = gfx::GetXDisplay(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::Screen* screen = DefaultScreenOfDisplay(display); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = WidthOfScreen(screen); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height = HeightOfScreen(screen); 52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Size physical_size(WidthMMOfScreen(screen), HeightMMOfScreen(screen)); 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect bounds_in_pixels(0, 0, width, height); 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Display gfx_display(0, bounds_in_pixels); 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!gfx::Display::HasForceDeviceScaleFactor() && 57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch !ui::IsDisplaySizeBlackListed(physical_size)) { 58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch float device_scale_factor = GetDeviceScaleFactor( 59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch width, physical_size.width()); 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_LE(1.0f, device_scale_factor); 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx_display.SetScaleAndBounds(device_scale_factor, bounds_in_pixels); 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return std::vector<gfx::Display>(1, gfx_display); 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Helper class to GetWindowAtScreenPoint() which returns the topmost window at 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the location passed to FindAt(). NULL is returned if a window which does not 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// belong to Chromium is topmost at the passed in location. 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ToplevelWindowFinder : public ui::EnumerateWindowsDelegate { 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ToplevelWindowFinder() : toplevel_(NULL) { 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~ToplevelWindowFinder() { 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* FindAt(const gfx::Point& screen_loc) { 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) screen_loc_ = screen_loc; 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::EnumerateTopLevelWindows(this); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return toplevel_; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected: 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool ShouldStopIterating(XID xid) OVERRIDE { 8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!ui::IsWindowVisible(xid)) 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window = 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) views::DesktopWindowTreeHostX11::GetContentWindowForXID(xid); 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (window) { 9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Currently |window|->IsVisible() always returns true. 9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // TODO(pkotwicz): Fix this. crbug.com/353038 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (window->IsVisible() && 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->GetBoundsInScreen().Contains(screen_loc_)) { 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) toplevel_ = window; 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (ui::WindowContainsPoint(xid, screen_loc_)) { 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // toplevel_ = NULL 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Point screen_loc_; 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* toplevel_; 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ToplevelWindowFinder); 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace 11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace views { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DesktopScreenX11, public: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)DesktopScreenX11::DesktopScreenX11() 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : xdisplay_(gfx::GetXDisplay()), 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) x_root_window_(DefaultRootWindow(xdisplay_)), 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) has_xrandr_(false), 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) xrandr_event_base_(0) { 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We only support 1.3+. There were library changes before this and we should 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // use the new interface instead of the 1.2 one. 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int randr_version_major = 0; 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int randr_version_minor = 0; 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) has_xrandr_ = XRRQueryVersion( 13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) xdisplay_, &randr_version_major, &randr_version_minor) && 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) randr_version_major == 1 && 13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) randr_version_minor >= 3; 13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (has_xrandr_) { 13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int error_base_ignored = 0; 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored); 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (ui::PlatformEventSource::GetInstance()) 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRSelectInput(xdisplay_, 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) x_root_window_, 1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RRScreenChangeNotifyMask | 1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RROutputChangeNotifyMask | 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RRCrtcChangeNotifyMask); 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) displays_ = BuildDisplaysFromXRandRInfo(); 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) displays_ = GetFallbackDisplayList(); 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DesktopScreenX11::~DesktopScreenX11() { 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (has_xrandr_ && ui::PlatformEventSource::GetInstance()) 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DesktopScreenX11::ProcessDisplayChange( 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::vector<gfx::Display>& incoming) { 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<gfx::Display> old_displays = displays_; 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) displays_ = incoming; 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef std::vector<gfx::Display>::const_iterator DisplayIt; 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<gfx::Display>::const_iterator old_it = old_displays.begin(); 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (; old_it != old_displays.end(); ++old_it) { 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool found = false; 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (std::vector<gfx::Display>::const_iterator new_it = 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) displays_.begin(); new_it != displays_.end(); ++new_it) { 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (old_it->id() == new_it->id()) { 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) found = true; 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!found) { 17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FOR_EACH_OBSERVER(gfx::DisplayObserver, observer_list_, 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnDisplayRemoved(*old_it)); 17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<gfx::Display>::const_iterator new_it = displays_.begin(); 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (; new_it != displays_.end(); ++new_it) { 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool found = false; 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (std::vector<gfx::Display>::const_iterator old_it = 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) old_displays.begin(); old_it != old_displays.end(); ++old_it) { 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (new_it->id() == old_it->id()) { 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (new_it->bounds() != old_it->bounds()) { 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FOR_EACH_OBSERVER(gfx::DisplayObserver, observer_list_, 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnDisplayBoundsChanged(*new_it)); 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) found = true; 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!found) { 19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FOR_EACH_OBSERVER(gfx::DisplayObserver, observer_list_, 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnDisplayAdded(*new_it)); 20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DesktopScreenX11, gfx::Screen implementation: 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DesktopScreenX11::IsDIPEnabled() { 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Point DesktopScreenX11::GetCursorScreenPoint() { 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TRACE_EVENT0("views", "DesktopScreenX11::GetCursorScreenPoint()"); 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XDisplay* display = gfx::GetXDisplay(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::Window root, child; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int root_x, root_y, win_x, win_y; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int mask; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XQueryPointer(display, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultRootWindow(display), 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &root, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &child, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &root_x, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &root_y, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &win_x, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &win_y, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mask); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Point(root_x, root_y); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)gfx::NativeWindow DesktopScreenX11::GetWindowUnderCursor() { 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetWindowAtScreenPoint(GetCursorScreenPoint()); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)gfx::NativeWindow DesktopScreenX11::GetWindowAtScreenPoint( 238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const gfx::Point& point) { 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ToplevelWindowFinder finder; 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return finder.FindAt(point); 241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int DesktopScreenX11::GetNumDisplays() const { 24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return displays_.size(); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)std::vector<gfx::Display> DesktopScreenX11::GetAllDisplays() const { 24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return displays_; 249424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display DesktopScreenX11::GetDisplayNearestWindow( 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeView window) const { 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Getting screen bounds here safely is hard. 25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // You'd think we'd be able to just call window->GetBoundsInScreen(), but we 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // can't because |window| (and the associated WindowEventDispatcher*) can be 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // partially initialized at this point; WindowEventDispatcher initializations 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // call through into GetDisplayNearestWindow(). But the X11 resources are 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // created before we create the aura::WindowEventDispatcher. So we ask what 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the DRWHX11 believes the window bounds are instead of going through the 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // aura::Window's screen bounds. 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::WindowTreeHost* host = window->GetHost(); 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (host) { 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DesktopWindowTreeHostX11* rwh = DesktopWindowTreeHostX11::GetHostForXID( 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host->GetAcceleratedWidget()); 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (rwh) 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return GetDisplayMatching(rwh->GetX11RootWindowBounds()); 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 27068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetPrimaryDisplay(); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display DesktopScreenX11::GetDisplayNearestPoint( 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& point) const { 27568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::vector<gfx::Display>::const_iterator it = displays_.begin(); 27668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it != displays_.end(); ++it) { 27768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (it->bounds().Contains(point)) 27868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return *it; 27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetPrimaryDisplay(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display DesktopScreenX11::GetDisplayMatching( 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& match_rect) const { 28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int max_area = 0; 28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const gfx::Display* matching = NULL; 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::vector<gfx::Display>::const_iterator it = displays_.begin(); 28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it != displays_.end(); ++it) { 29068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect intersect = gfx::IntersectRects(it->bounds(), match_rect); 29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int area = intersect.width() * intersect.height(); 29268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (area > max_area) { 29368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) max_area = area; 29468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) matching = &*it; 29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 29768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Fallback to the primary display if there is no matching display. 29868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return matching ? *matching : GetPrimaryDisplay(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Display DesktopScreenX11::GetPrimaryDisplay() const { 30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return displays_.front(); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DesktopScreenX11::AddObserver(gfx::DisplayObserver* observer) { 30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) observer_list_.AddObserver(observer); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DesktopScreenX11::RemoveObserver(gfx::DisplayObserver* observer) { 31068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) observer_list_.RemoveObserver(observer); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 313c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool DesktopScreenX11::CanDispatchEvent(const ui::PlatformEvent& event) { 314c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return event->type - xrandr_event_base_ == RRScreenChangeNotify || 315c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch event->type - xrandr_event_base_ == RRNotify; 316c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 317c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 318c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochuint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) { 31968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (event->type - xrandr_event_base_ == RRScreenChangeNotify) { 32068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Pass the event through to xlib. 32168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRUpdateConfiguration(event); 32268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else if (event->type - xrandr_event_base_ == RRNotify) { 32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // There's some sort of observer dispatch going on here, but I don't think 32468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // it's the screen's? 325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (configure_timer_.get() && configure_timer_->IsRunning()) { 32668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) configure_timer_->Reset(); 32768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 32868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) configure_timer_.reset(new base::OneShotTimer<DesktopScreenX11>()); 32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) configure_timer_->Start( 33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FROM_HERE, 33168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kConfigureDelayMs), 33268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) this, 33368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &DesktopScreenX11::ConfigureTimerFired); 33468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NOTREACHED(); 33768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 33868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 339c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return ui::POST_DISPATCH_NONE; 34068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 34368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// DesktopScreenX11, private: 34468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)DesktopScreenX11::DesktopScreenX11( 34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::vector<gfx::Display>& test_displays) 347a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : xdisplay_(gfx::GetXDisplay()), 34868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) x_root_window_(DefaultRootWindow(xdisplay_)), 34968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) has_xrandr_(false), 35068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) xrandr_event_base_(0), 35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) displays_(test_displays) { 35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() { 35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<gfx::Display> displays; 35668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRScreenResources* resources = 35768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRGetScreenResourcesCurrent(xdisplay_, x_root_window_); 35868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!resources) { 35968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) LOG(ERROR) << "XRandR returned no displays. Falling back to Root Window."; 36068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetFallbackDisplayList(); 36168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 36268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 36368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool has_work_area = false; 36468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect work_area; 36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<int> value; 36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) && 36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) value.size() >= 4) { 36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) work_area = gfx::Rect(value[0], value[1], value[2], value[3]); 36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) has_work_area = true; 37068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 37168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) float device_scale_factor = 1.0f; 37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int i = 0; i < resources->noutput; ++i) { 37468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RROutput output_id = resources->outputs[i]; 37568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRROutputInfo* output_info = 37668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRGetOutputInfo(xdisplay_, resources, output_id); 37768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 37868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool is_connected = (output_info->connection == RR_Connected); 37968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!is_connected) { 38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRFreeOutputInfo(output_info); 38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) continue; 38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 38468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (output_info->crtc) { 38568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRCrtcInfo *crtc = XRRGetCrtcInfo(xdisplay_, 38668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) resources, 38768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) output_info->crtc); 38868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 38968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int64 display_id = -1; 390effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!ui::GetDisplayId(output_id, static_cast<uint8>(i), &display_id)) { 39168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It isn't ideal, but if we can't parse the EDID data, fallback on the 39268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // display number. 39368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) display_id = i; 39468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 39568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 39668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect crtc_bounds(crtc->x, crtc->y, crtc->width, crtc->height); 39768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Display display(display_id, crtc_bounds); 398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!gfx::Display::HasForceDeviceScaleFactor()) { 400c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (i == 0 && !ui::IsDisplaySizeBlackListed( 401c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Size(output_info->mm_width, output_info->mm_height))) { 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // As per display scale factor is not supported right now, 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the primary display's scale factor is always used. 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) device_scale_factor = GetDeviceScaleFactor(crtc->width, 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) output_info->mm_width); 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_LE(1.0f, device_scale_factor); 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) display.SetScaleAndBounds(device_scale_factor, crtc_bounds); 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 41168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (has_work_area) { 41268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect intersection = crtc_bounds; 41368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) intersection.Intersect(work_area); 41468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) display.set_work_area(intersection); 41568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 41668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 41768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) displays.push_back(display); 41868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 41968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRFreeCrtcInfo(crtc); 42068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 42168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRFreeOutputInfo(output_info); 42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 42468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 42568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XRRFreeScreenResources(resources); 42668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 42768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (displays.empty()) 42868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return GetFallbackDisplayList(); 42968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 43068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return displays; 43168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 43268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 43368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DesktopScreenX11::ConfigureTimerFired() { 43468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<gfx::Display> new_displays = BuildDisplaysFromXRandRInfo(); 43568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ProcessDisplayChange(new_displays); 43668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 43768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 43868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Screen* CreateDesktopScreen() { 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new DesktopScreenX11; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace views 445