display_util_x11.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ash/display/display_util_x11.h" 6 7#include <algorithm> 8#include <map> 9#include <X11/extensions/Xrandr.h> 10 11#include "ash/display/display_info.h" 12#include "base/logging.h" 13#include "chromeos/display/output_util.h" 14 15namespace ash { 16namespace internal { 17namespace { 18 19// A list of bogus sizes in mm that X detects that should be ignored. 20// See crbug.com/136533. The first element maintains the minimum 21// size required to be valid size. 22const unsigned long kInvalidDisplaySizeList[][2] = { 23 {40, 30}, 24 {50, 40}, 25 {160, 90}, 26 {160, 100}, 27}; 28 29// Resolution list are sorted by the area in pixels and the larger 30// one comes first. 31struct ResolutionSorter { 32 bool operator()(const Resolution& a, const Resolution& b) { 33 return a.size.width() * a.size.height() > b.size.width() * b.size.height(); 34 } 35}; 36 37} // namespace 38 39bool ShouldIgnoreSize(unsigned long mm_width, unsigned long mm_height) { 40 // Ignore if the reported display is smaller than minimum size. 41 if (mm_width <= kInvalidDisplaySizeList[0][0] || 42 mm_height <= kInvalidDisplaySizeList[0][1]) { 43 LOG(WARNING) << "Smaller than minimum display size"; 44 return true; 45 } 46 for (unsigned long i = 1 ; i < arraysize(kInvalidDisplaySizeList); ++i) { 47 const unsigned long* size = kInvalidDisplaySizeList[i]; 48 if (mm_width == size[0] && mm_height == size[1]) { 49 LOG(WARNING) << "Black listed display size detected:" 50 << size[0] << "x" << size[1]; 51 return true; 52 } 53 } 54 return false; 55} 56 57std::vector<Resolution> GetResolutionList( 58 XRRScreenResources* screen_resources, 59 XRROutputInfo* output_info) { 60 typedef std::map<std::pair<int,int>, Resolution> ResolutionMap; 61 62 ResolutionMap resolution_map; 63 64 for (int i = 0; i < output_info->nmode; i++) { 65 RRMode mode = output_info->modes[i]; 66 const XRRModeInfo* info = chromeos::FindModeInfo(screen_resources, mode); 67 DCHECK(info); 68 // Just ignore bad entry on Release build. 69 if (!info) 70 continue; 71 ResolutionMap::key_type size = std::make_pair(info->width, info->height); 72 bool interlaced = (info->modeFlags & RR_Interlace) != 0; 73 74 ResolutionMap::iterator iter = resolution_map.find(size); 75 76 // Add new resolution if it's new size or override interlaced mode. 77 if (iter == resolution_map.end()) { 78 resolution_map.insert(ResolutionMap::value_type( 79 size, 80 Resolution(gfx::Size(info->width, info->height), interlaced))); 81 } else if (iter->second.interlaced && !interlaced) { 82 iter->second.interlaced = false; 83 } 84 } 85 86 std::vector<Resolution> resolution_list; 87 for (ResolutionMap::const_iterator iter = resolution_map.begin(); 88 iter != resolution_map.end(); 89 ++iter) { 90 resolution_list.push_back(iter->second); 91 } 92 std::sort(resolution_list.begin(), resolution_list.end(), ResolutionSorter()); 93 return resolution_list; 94} 95 96} // namespace internal 97} // namespace ash 98