| Index: ash/display/display_change_observer_chromeos.cc
|
| diff --git a/ash/display/display_change_observer_x11.cc b/ash/display/display_change_observer_chromeos.cc
|
| similarity index 43%
|
| rename from ash/display/display_change_observer_x11.cc
|
| rename to ash/display/display_change_observer_chromeos.cc
|
| index 2802e6c8984a836f65e3cbfb61e23587db525594..212dd5ac721921704afaa93aec99ec40f62d4563 100644
|
| --- a/ash/display/display_change_observer_x11.cc
|
| +++ b/ash/display/display_change_observer_chromeos.cc
|
| @@ -2,23 +2,20 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "ash/display/display_change_observer_x11.h"
|
| +#include "ash/display/display_change_observer_chromeos.h"
|
|
|
| #include <algorithm>
|
| #include <map>
|
| #include <set>
|
| #include <vector>
|
|
|
| -#include <X11/extensions/Xrandr.h>
|
| -
|
| #include "ash/ash_switches.h"
|
| #include "ash/display/display_info.h"
|
| #include "ash/display/display_layout_store.h"
|
| #include "ash/display/display_manager.h"
|
| -#include "ash/display/display_util_x11.h"
|
| #include "ash/shell.h"
|
| #include "base/command_line.h"
|
| -#include "base/message_loop/message_pump_aurax11.h"
|
| +#include "base/logging.h"
|
| #include "chromeos/display/output_util.h"
|
| #include "grit/ash_strings.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| @@ -39,30 +36,87 @@ const unsigned int kHighDensityDPIThreshold = 160;
|
| // 1 inch in mm.
|
| const float kInchInMm = 25.4f;
|
|
|
| -int64 GetDisplayId(XID output, size_t output_index) {
|
| - int64 display_id;
|
| - if (chromeos::GetDisplayId(output, output_index, &display_id))
|
| - return display_id;
|
| - return gfx::Display::kInvalidDisplayID;
|
| -}
|
| +// A list of bogus sizes in mm that X detects that should be ignored.
|
| +// See crbug.com/136533. The first element maintains the minimum
|
| +// size required to be valid size.
|
| +const unsigned long kInvalidDisplaySizeList[][2] = {
|
| + {40, 30},
|
| + {50, 40},
|
| + {160, 90},
|
| + {160, 100},
|
| +};
|
| +
|
| +// Resolution list are sorted by the area in pixels and the larger
|
| +// one comes first.
|
| +struct ResolutionSorter {
|
| + bool operator()(const Resolution& a, const Resolution& b) {
|
| + return a.size.width() * a.size.height() > b.size.width() * b.size.height();
|
| + }
|
| +};
|
|
|
| } // namespace
|
|
|
| -DisplayChangeObserverX11::DisplayChangeObserverX11()
|
| - : xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
|
| - x_root_window_(DefaultRootWindow(xdisplay_)),
|
| - xrandr_event_base_(0) {
|
| - int error_base_ignored;
|
| - XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored);
|
| +// static
|
| +bool DisplayChangeObserver::ShouldIgnoreSize(unsigned long mm_width,
|
| + unsigned long mm_height) {
|
| + // Ignore if the reported display is smaller than minimum size.
|
| + if (mm_width <= kInvalidDisplaySizeList[0][0] ||
|
| + mm_height <= kInvalidDisplaySizeList[0][1]) {
|
| + LOG(WARNING) << "Smaller than minimum display size";
|
| + return true;
|
| + }
|
| + for (unsigned long i = 1 ; i < arraysize(kInvalidDisplaySizeList); ++i) {
|
| + const unsigned long* size = kInvalidDisplaySizeList[i];
|
| + if (mm_width == size[0] && mm_height == size[1]) {
|
| + LOG(WARNING) << "Black listed display size detected:"
|
| + << size[0] << "x" << size[1];
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
|
|
| +// static
|
| +std::vector<Resolution> DisplayChangeObserver::GetResolutionList(
|
| + const OutputConfigurator::OutputSnapshot& output) {
|
| + typedef std::map<std::pair<int,int>, Resolution> ResolutionMap;
|
| + ResolutionMap resolution_map;
|
| +
|
| + for (std::map<RRMode, OutputConfigurator::ModeInfo>::const_iterator it =
|
| + output.mode_infos.begin(); it != output.mode_infos.end(); ++it) {
|
| + const OutputConfigurator::ModeInfo& mode_info = it->second;
|
| + const std::pair<int, int> size(mode_info.width, mode_info.height);
|
| + const Resolution resolution(gfx::Size(mode_info.width, mode_info.height),
|
| + mode_info.interlaced);
|
| +
|
| + // Add the resolution if it isn't already present and override interlaced
|
| + // resolutions with non-interlaced ones.
|
| + ResolutionMap::iterator resolution_it = resolution_map.find(size);
|
| + if (resolution_it == resolution_map.end())
|
| + resolution_map.insert(std::make_pair(size, resolution));
|
| + else if (resolution_it->second.interlaced && !resolution.interlaced)
|
| + resolution_it->second = resolution;
|
| + }
|
| +
|
| + std::vector<Resolution> resolution_list;
|
| + for (ResolutionMap::const_iterator iter = resolution_map.begin();
|
| + iter != resolution_map.end();
|
| + ++iter) {
|
| + resolution_list.push_back(iter->second);
|
| + }
|
| + std::sort(resolution_list.begin(), resolution_list.end(), ResolutionSorter());
|
| + return resolution_list;
|
| +}
|
| +
|
| +DisplayChangeObserver::DisplayChangeObserver() {
|
| Shell::GetInstance()->AddShellObserver(this);
|
| }
|
|
|
| -DisplayChangeObserverX11::~DisplayChangeObserverX11() {
|
| +DisplayChangeObserver::~DisplayChangeObserver() {
|
| Shell::GetInstance()->RemoveShellObserver(this);
|
| }
|
|
|
| -chromeos::OutputState DisplayChangeObserverX11::GetStateForDisplayIds(
|
| +chromeos::OutputState DisplayChangeObserver::GetStateForDisplayIds(
|
| const std::vector<int64>& display_ids) const {
|
| if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| switches::kAshForceMirrorMode)) {
|
| @@ -77,10 +131,9 @@ chromeos::OutputState DisplayChangeObserverX11::GetStateForDisplayIds(
|
| chromeos::STATE_DUAL_MIRROR : chromeos::STATE_DUAL_EXTENDED;
|
| }
|
|
|
| -bool DisplayChangeObserverX11::GetResolutionForDisplayId(int64 display_id,
|
| - int* width,
|
| - int* height) const {
|
| -
|
| +bool DisplayChangeObserver::GetResolutionForDisplayId(int64 display_id,
|
| + int* width,
|
| + int* height) const {
|
| gfx::Size resolution;
|
| if (!Shell::GetInstance()->display_manager()->
|
| GetSelectedResolutionForDisplayId(display_id, &resolution)) {
|
| @@ -92,86 +145,51 @@ bool DisplayChangeObserverX11::GetResolutionForDisplayId(int64 display_id,
|
| return true;
|
| }
|
|
|
| -void DisplayChangeObserverX11::OnDisplayModeChanged(
|
| +void DisplayChangeObserver::OnDisplayModeChanged(
|
| const std::vector<OutputConfigurator::OutputSnapshot>& outputs) {
|
| - // TODO(derat): Use |outputs| instead of re-fetching information.
|
| - XRRScreenResources* screen_resources =
|
| - XRRGetScreenResources(xdisplay_, x_root_window_);
|
| - std::map<XID, XRRCrtcInfo*> crtc_info_map;
|
| -
|
| - for (int c = 0; c < screen_resources->ncrtc; c++) {
|
| - XID crtc_id = screen_resources->crtcs[c];
|
| - XRRCrtcInfo *crtc_info =
|
| - XRRGetCrtcInfo(xdisplay_, screen_resources, crtc_id);
|
| - crtc_info_map[crtc_id] = crtc_info;
|
| - }
|
| -
|
| std::vector<DisplayInfo> displays;
|
| std::set<int64> ids;
|
| - for (int output_index = 0; output_index < screen_resources->noutput;
|
| - output_index++) {
|
| - XID output = screen_resources->outputs[output_index];
|
| - XRROutputInfo *output_info =
|
| - XRRGetOutputInfo(xdisplay_, screen_resources, output);
|
| -
|
| - const bool is_internal = chromeos::IsInternalOutputName(
|
| - std::string(output_info->name));
|
| + for (size_t i = 0; i < outputs.size(); ++i) {
|
| + const OutputConfigurator::OutputSnapshot& output = outputs[i];
|
|
|
| - if (is_internal &&
|
| + if (output.is_internal &&
|
| gfx::Display::InternalDisplayId() == gfx::Display::kInvalidDisplayID) {
|
| - int64 id = GetDisplayId(output, output_index);
|
| - // Fallback to output index. crbug.com/180100
|
| + // Fall back to output index. crbug.com/180100
|
| gfx::Display::SetInternalDisplayId(
|
| - id == gfx::Display::kInvalidDisplayID ? output_index : id);
|
| + output.display_id == gfx::Display::kInvalidDisplayID ? output.index :
|
| + output.display_id);
|
| }
|
|
|
| - if (output_info->connection != RR_Connected) {
|
| - XRRFreeOutputInfo(output_info);
|
| - continue;
|
| - }
|
| - const XRRCrtcInfo* crtc_info = crtc_info_map[output_info->crtc];
|
| - if (!crtc_info) {
|
| - LOG(WARNING) << "Crtc not found for output: output_index="
|
| - << output_index;
|
| - continue;
|
| - }
|
| - const XRRModeInfo* mode =
|
| - chromeos::FindXRRModeInfo(screen_resources, crtc_info->mode);
|
| - if (!mode) {
|
| - LOG(WARNING) << "Could not find a mode for the output: output_index="
|
| - << output_index;
|
| + const OutputConfigurator::ModeInfo* mode_info =
|
| + OutputConfigurator::GetModeInfo(output, output.current_mode);
|
| + if (!mode_info)
|
| continue;
|
| - }
|
|
|
| float device_scale_factor = 1.0f;
|
| - if (!ShouldIgnoreSize(output_info->mm_width, output_info->mm_height) &&
|
| - (kInchInMm * mode->width / output_info->mm_width) >
|
| + if (!ShouldIgnoreSize(output.width_mm, output.height_mm) &&
|
| + (kInchInMm * mode_info->width / output.width_mm) >
|
| kHighDensityDPIThreshold) {
|
| device_scale_factor = 2.0f;
|
| }
|
| gfx::Rect display_bounds(
|
| - crtc_info->x, crtc_info->y, mode->width, mode->height);
|
| + output.x, output.y, mode_info->width, mode_info->height);
|
|
|
| std::vector<Resolution> resolutions;
|
| - if (!is_internal)
|
| - resolutions = GetResolutionList(screen_resources, output_info);
|
| -
|
| - XRRFreeOutputInfo(output_info);
|
| + if (!output.is_internal)
|
| + resolutions = GetResolutionList(output);
|
|
|
| - std::string name = is_internal ?
|
| + std::string name = output.is_internal ?
|
| l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME) :
|
| - chromeos::GetDisplayName(output);
|
| + chromeos::GetDisplayName(output.output);
|
| if (name.empty())
|
| name = l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME);
|
|
|
| bool has_overscan = false;
|
| - chromeos::GetOutputOverscanFlag(output, &has_overscan);
|
| + chromeos::GetOutputOverscanFlag(output.output, &has_overscan);
|
|
|
| - int64 id = GetDisplayId(output, output_index);
|
| -
|
| - // If ID is invalid or there is an duplicate, just use output index.
|
| + int64 id = output.display_id;
|
| if (id == gfx::Display::kInvalidDisplayID || ids.find(id) != ids.end())
|
| - id = output_index;
|
| + id = output.index;
|
| ids.insert(id);
|
|
|
| displays.push_back(DisplayInfo(id, name, has_overscan));
|
| @@ -181,18 +199,11 @@ void DisplayChangeObserverX11::OnDisplayModeChanged(
|
| displays.back().set_resolutions(resolutions);
|
| }
|
|
|
| - // Free all allocated resources.
|
| - for (std::map<XID, XRRCrtcInfo*>::const_iterator iter = crtc_info_map.begin();
|
| - iter != crtc_info_map.end(); ++iter) {
|
| - XRRFreeCrtcInfo(iter->second);
|
| - }
|
| - XRRFreeScreenResources(screen_resources);
|
| -
|
| // DisplayManager can be null during the boot.
|
| Shell::GetInstance()->display_manager()->OnNativeDisplaysChanged(displays);
|
| }
|
|
|
| -void DisplayChangeObserverX11::OnAppTerminating() {
|
| +void DisplayChangeObserver::OnAppTerminating() {
|
| #if defined(USE_ASH)
|
| // Stop handling display configuration events once the shutdown
|
| // process starts. crbug.com/177014.
|
|
|