• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 "ui/display/util/x11/edid_parser_x11.h"
6 
7 #include <X11/extensions/Xrandr.h>
8 #include <X11/Xatom.h>
9 #include <X11/Xlib.h>
10 
11 #include "base/strings/string_util.h"
12 #include "ui/display/util/edid_parser.h"
13 #include "ui/gfx/x/x11_types.h"
14 
15 namespace ui {
16 
17 namespace {
18 
IsRandRAvailable()19 bool IsRandRAvailable() {
20   int randr_version_major = 0;
21   int randr_version_minor = 0;
22   static bool is_randr_available = XRRQueryVersion(
23       gfx::GetXDisplay(), &randr_version_major, &randr_version_minor);
24   return is_randr_available;
25 }
26 
27 // Get the EDID data from the |output| and stores to |edid|.
28 // Returns true if EDID property is successfully obtained. Otherwise returns
29 // false and does not touch |edid|.
GetEDIDProperty(XID output,std::vector<uint8_t> * edid)30 bool GetEDIDProperty(XID output, std::vector<uint8_t>* edid) {
31   if (!IsRandRAvailable())
32     return false;
33 
34   Display* display = gfx::GetXDisplay();
35 
36   static Atom edid_property = XInternAtom(
37       gfx::GetXDisplay(),
38       RR_PROPERTY_RANDR_EDID, false);
39 
40   bool has_edid_property = false;
41   int num_properties = 0;
42   Atom* properties = XRRListOutputProperties(display, output, &num_properties);
43   for (int i = 0; i < num_properties; ++i) {
44     if (properties[i] == edid_property) {
45       has_edid_property = true;
46       break;
47     }
48   }
49   XFree(properties);
50   if (!has_edid_property)
51     return false;
52 
53   Atom actual_type;
54   int actual_format;
55   unsigned long bytes_after;
56   unsigned long nitems = 0;
57   unsigned char* prop = NULL;
58   XRRGetOutputProperty(display,
59                        output,
60                        edid_property,
61                        0,                // offset
62                        128,              // length
63                        false,            // _delete
64                        false,            // pending
65                        AnyPropertyType,  // req_type
66                        &actual_type,
67                        &actual_format,
68                        &nitems,
69                        &bytes_after,
70                        &prop);
71   DCHECK_EQ(XA_INTEGER, actual_type);
72   DCHECK_EQ(8, actual_format);
73   edid->assign(prop, prop + nitems);
74   XFree(prop);
75   return true;
76 }
77 
78 // Gets some useful data from the specified output device, such like
79 // manufacturer's ID, product code, and human readable name. Returns false if it
80 // fails to get those data and doesn't touch manufacturer ID/product code/name.
81 // NULL can be passed for unwanted output parameters.
GetOutputDeviceData(XID output,uint16_t * manufacturer_id,std::string * human_readable_name)82 bool GetOutputDeviceData(XID output,
83                          uint16_t* manufacturer_id,
84                          std::string* human_readable_name) {
85   std::vector<uint8_t> edid;
86   if (!GetEDIDProperty(output, &edid))
87     return false;
88 
89   bool result = ParseOutputDeviceData(
90       edid, manufacturer_id, human_readable_name);
91   return result;
92 }
93 
94 }  // namespace
95 
GetDisplayId(XID output_id,uint8_t output_index,int64_t * display_id_out)96 bool GetDisplayId(XID output_id,
97                   uint8_t output_index,
98                   int64_t* display_id_out) {
99   std::vector<uint8_t> edid;
100   if (!GetEDIDProperty(output_id, &edid))
101     return false;
102 
103   bool result = GetDisplayIdFromEDID(edid, output_index, display_id_out);
104   return result;
105 }
106 
GetDisplayName(RROutput output)107 std::string GetDisplayName(RROutput output) {
108   std::string display_name;
109   GetOutputDeviceData(output, NULL, &display_name);
110   return display_name;
111 }
112 
GetOutputOverscanFlag(RROutput output,bool * flag)113 bool GetOutputOverscanFlag(RROutput output, bool* flag) {
114   std::vector<uint8_t> edid;
115   if (!GetEDIDProperty(output, &edid))
116     return false;
117 
118   bool found = ParseOutputOverscanFlag(edid, flag);
119   return found;
120 }
121 
122 }  // namespace ui
123