// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/display/util/x11/edid_parser_x11.h" #include #include #include #include "base/strings/string_util.h" #include "ui/display/util/edid_parser.h" #include "ui/gfx/x/x11_types.h" namespace ui { namespace { bool IsRandRAvailable() { int randr_version_major = 0; int randr_version_minor = 0; static bool is_randr_available = XRRQueryVersion( gfx::GetXDisplay(), &randr_version_major, &randr_version_minor); return is_randr_available; } // Get the EDID data from the |output| and stores to |edid|. // Returns true if EDID property is successfully obtained. Otherwise returns // false and does not touch |edid|. bool GetEDIDProperty(XID output, std::vector* edid) { if (!IsRandRAvailable()) return false; Display* display = gfx::GetXDisplay(); static Atom edid_property = XInternAtom( gfx::GetXDisplay(), RR_PROPERTY_RANDR_EDID, false); bool has_edid_property = false; int num_properties = 0; gfx::XScopedPtr properties( XRRListOutputProperties(display, output, &num_properties)); for (int i = 0; i < num_properties; ++i) { if (properties[i] == edid_property) { has_edid_property = true; break; } } if (!has_edid_property) return false; Atom actual_type; int actual_format; unsigned long bytes_after; unsigned long nitems = 0; unsigned char* prop = nullptr; XRRGetOutputProperty(display, output, edid_property, 0, // offset 128, // length false, // _delete false, // pending AnyPropertyType, // req_type &actual_type, &actual_format, &nitems, &bytes_after, &prop); DCHECK_EQ(XA_INTEGER, actual_type); DCHECK_EQ(8, actual_format); edid->assign(prop, prop + nitems); XFree(prop); return true; } // Gets some useful data from the specified output device, such like // manufacturer's ID, product code, and human readable name. Returns false if it // fails to get those data and doesn't touch manufacturer ID/product code/name. // nullptr can be passed for unwanted output parameters. bool GetOutputDeviceData(XID output, uint16_t* manufacturer_id, std::string* human_readable_name) { std::vector edid; if (!GetEDIDProperty(output, &edid)) return false; return ParseOutputDeviceData(edid, manufacturer_id, nullptr, human_readable_name, nullptr, nullptr); } } // namespace bool GetDisplayId(XID output_id, uint8_t output_index, int64_t* display_id_out) { std::vector edid; if (!GetEDIDProperty(output_id, &edid)) return false; bool result = GetDisplayIdFromEDID(edid, output_index, display_id_out, nullptr); return result; } std::string GetDisplayName(RROutput output) { std::string display_name; GetOutputDeviceData(output, nullptr, &display_name); return display_name; } bool GetOutputOverscanFlag(RROutput output, bool* flag) { std::vector edid; if (!GetEDIDProperty(output, &edid)) return false; bool found = ParseOutputOverscanFlag(edid, flag); return found; } } // namespace ui