Generate display product id with EDID manufacturer product code
[chromium-blink-merge.git] / ui / display / util / x11 / edid_parser_x11.cc
blob13059f0fea1a4abf4c09fa0d4a37c73429597da4
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.
5 #include "ui/display/util/x11/edid_parser_x11.h"
7 #include <X11/extensions/Xrandr.h>
8 #include <X11/Xatom.h>
9 #include <X11/Xlib.h>
11 #include "base/strings/string_util.h"
12 #include "ui/display/util/edid_parser.h"
13 #include "ui/gfx/x/x11_types.h"
15 namespace ui {
17 namespace {
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;
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|.
30 bool GetEDIDProperty(XID output, std::vector<uint8_t>* edid) {
31 if (!IsRandRAvailable())
32 return false;
34 Display* display = gfx::GetXDisplay();
36 static Atom edid_property = XInternAtom(
37 gfx::GetXDisplay(),
38 RR_PROPERTY_RANDR_EDID, false);
40 bool has_edid_property = false;
41 int num_properties = 0;
42 gfx::XScopedPtr<Atom[]> properties(
43 XRRListOutputProperties(display, output, &num_properties));
44 for (int i = 0; i < num_properties; ++i) {
45 if (properties[i] == edid_property) {
46 has_edid_property = true;
47 break;
50 if (!has_edid_property)
51 return false;
53 Atom actual_type;
54 int actual_format;
55 unsigned long bytes_after;
56 unsigned long nitems = 0;
57 unsigned char* prop = nullptr;
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;
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 // nullptr can be passed for unwanted output parameters.
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;
89 return ParseOutputDeviceData(edid, manufacturer_id, nullptr,
90 human_readable_name, nullptr, nullptr);
93 } // namespace
95 bool GetDisplayId(XID output_id,
96 uint8_t output_index,
97 int64_t* display_id_out) {
98 std::vector<uint8_t> edid;
99 if (!GetEDIDProperty(output_id, &edid))
100 return false;
102 bool result =
103 GetDisplayIdFromEDID(edid, output_index, display_id_out, nullptr);
104 return result;
107 std::string GetDisplayName(RROutput output) {
108 std::string display_name;
109 GetOutputDeviceData(output, nullptr, &display_name);
110 return display_name;
113 bool GetOutputOverscanFlag(RROutput output, bool* flag) {
114 std::vector<uint8_t> edid;
115 if (!GetEDIDProperty(output, &edid))
116 return false;
118 bool found = ParseOutputOverscanFlag(edid, flag);
119 return found;
122 } // namespace ui