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 15 namespace ash { 16 namespace internal { 17 namespace { 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. 22 const 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. 31 struct 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 39 bool 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 57 std::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