summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authordnicoara@chromium.org <dnicoara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-25 20:12:14 +0000
committerdnicoara@chromium.org <dnicoara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-25 20:12:14 +0000
commitf9b77696792c95cc9b2ffb04154c9eb4bb0ad479 (patch)
tree38019679a2f71ec7f1f97f59e80f9c64cbad3ea4 /ui
parent2c7f2031a7a062c31a76de1f1bc54b5c06961e3d (diff)
downloadchromium_src-f9b77696792c95cc9b2ffb04154c9eb4bb0ad479.zip
chromium_src-f9b77696792c95cc9b2ffb04154c9eb4bb0ad479.tar.gz
chromium_src-f9b77696792c95cc9b2ffb04154c9eb4bb0ad479.tar.bz2
Refactor EDID parsing utilities and consolidate them under ui/display/chromeos
This refactoring splits EDID parsing to generic parsing and Xrandr helpers. I'm also consolidating EDID parsing under ui/display/chromeos since this is the only place it is used. BUG=333413 Review URL: https://codereview.chromium.org/196413010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@259316 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/display/chromeos/x11/display_snapshot_x11.cc2
-rw-r--r--ui/display/chromeos/x11/display_util.cc161
-rw-r--r--ui/display/chromeos/x11/display_util.h37
-rw-r--r--ui/display/chromeos/x11/display_util_x11.cc41
-rw-r--r--ui/display/chromeos/x11/display_util_x11.h24
-rw-r--r--ui/display/chromeos/x11/display_util_x11_unittest.cc42
-rw-r--r--ui/display/chromeos/x11/native_display_delegate_x11.cc7
-rw-r--r--ui/display/display.gyp8
-rw-r--r--ui/display/display_unittests.gypi5
-rw-r--r--ui/display/edid_parser.cc208
-rw-r--r--ui/display/edid_parser.h41
-rw-r--r--ui/display/edid_parser_unittest.cc (renamed from ui/display/chromeos/x11/display_util_unittest.cc)146
-rw-r--r--ui/display/x11/edid_parser_x11.cc121
-rw-r--r--ui/display/x11/edid_parser_x11.h48
-rw-r--r--ui/views/DEPS1
-rw-r--r--ui/views/views.gyp5
-rw-r--r--ui/views/widget/desktop_aura/desktop_screen_x11.cc4
17 files changed, 657 insertions, 244 deletions
diff --git a/ui/display/chromeos/x11/display_snapshot_x11.cc b/ui/display/chromeos/x11/display_snapshot_x11.cc
index 366a1f3..9228a07 100644
--- a/ui/display/chromeos/x11/display_snapshot_x11.cc
+++ b/ui/display/chromeos/x11/display_snapshot_x11.cc
@@ -6,7 +6,7 @@
#include "base/strings/stringprintf.h"
#include "ui/display/chromeos/x11/display_mode_x11.h"
-#include "ui/display/chromeos/x11/display_util.h"
+#include "ui/display/x11/edid_parser_x11.h"
namespace ui {
diff --git a/ui/display/chromeos/x11/display_util.cc b/ui/display/chromeos/x11/display_util.cc
deleted file mode 100644
index 107d8be..0000000
--- a/ui/display/chromeos/x11/display_util.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// 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/chromeos/x11/display_util.h"
-
-#include <X11/extensions/Xrandr.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-
-#include "base/macros.h"
-#include "base/strings/string_util.h"
-#include "base/x11/edid_parser_x11.h"
-
-namespace ui {
-
-namespace {
-
-struct OutputTypeMapping {
- // Prefix of output name.
- std::string name;
- OutputType type;
-};
-
-const OutputTypeMapping kOutputTypeMapping[] = {
- {"LVDS", OUTPUT_TYPE_INTERNAL},
- {"eDP", OUTPUT_TYPE_INTERNAL},
- {"DSI", OUTPUT_TYPE_INTERNAL},
- {"VGA", OUTPUT_TYPE_VGA},
- {"HDMI", OUTPUT_TYPE_HDMI},
- {"DVI", OUTPUT_TYPE_DVI},
- {"DP", OUTPUT_TYPE_DISPLAYPORT}
-};
-
-// 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.
-// NULL can be passed for unwanted output parameters.
-bool GetOutputDeviceData(XID output,
- uint16* manufacturer_id,
- std::string* human_readable_name) {
- unsigned long nitems = 0;
- unsigned char* prop = NULL;
- if (!base::GetEDIDProperty(output, &nitems, &prop))
- return false;
-
- bool result = base::ParseOutputDeviceData(
- prop, nitems, manufacturer_id, human_readable_name);
- XFree(prop);
- return result;
-}
-
-} // namespace
-
-OutputType GetOutputTypeFromName(const std::string& name) {
- for (unsigned int i = 0; i < arraysize(kOutputTypeMapping); ++i) {
- if (name.find(kOutputTypeMapping[i].name) == 0) {
- return kOutputTypeMapping[i].type;
- }
- }
-
- return OUTPUT_TYPE_UNKNOWN;
-}
-
-std::string GetDisplayName(RROutput output) {
- std::string display_name;
- GetOutputDeviceData(output, NULL, &display_name);
- return display_name;
-}
-
-bool GetOutputOverscanFlag(RROutput output, bool* flag) {
- unsigned long nitems = 0;
- unsigned char* prop = NULL;
- if (!base::GetEDIDProperty(output, &nitems, &prop))
- return false;
-
- bool found = ParseOutputOverscanFlag(prop, nitems, flag);
- XFree(prop);
- return found;
-}
-
-bool ParseOutputOverscanFlag(const unsigned char* prop,
- unsigned long nitems,
- bool* flag) {
- // See http://en.wikipedia.org/wiki/Extended_display_identification_data
- // for the extension format of EDID. Also see EIA/CEA-861 spec for
- // the format of the extensions and how video capability is encoded.
- // - byte 0: tag. should be 02h.
- // - byte 1: revision. only cares revision 3 (03h).
- // - byte 4-: data block.
- const unsigned int kExtensionBase = 128;
- const unsigned int kExtensionSize = 128;
- const unsigned int kNumExtensionsOffset = 126;
- const unsigned int kDataBlockOffset = 4;
- const unsigned char kCEAExtensionTag = '\x02';
- const unsigned char kExpectedExtensionRevision = '\x03';
- const unsigned char kExtendedTag = 7;
- const unsigned char kExtendedVideoCapabilityTag = 0;
- const unsigned int kPTOverscan = 4;
- const unsigned int kITOverscan = 2;
- const unsigned int kCEOverscan = 0;
-
- if (nitems <= kNumExtensionsOffset)
- return false;
-
- unsigned char num_extensions = prop[kNumExtensionsOffset];
-
- for (size_t i = 0; i < num_extensions; ++i) {
- // Skip parsing the whole extension if size is not enough.
- if (nitems < kExtensionBase + (i + 1) * kExtensionSize)
- break;
-
- const unsigned char* extension = prop + kExtensionBase + i * kExtensionSize;
- unsigned char tag = extension[0];
- unsigned char revision = extension[1];
- if (tag != kCEAExtensionTag || revision != kExpectedExtensionRevision)
- continue;
-
- unsigned char timing_descriptors_start =
- std::min(extension[2], static_cast<unsigned char>(kExtensionSize));
- const unsigned char* data_block = extension + kDataBlockOffset;
- while (data_block < extension + timing_descriptors_start) {
- // A data block is encoded as:
- // - byte 1 high 3 bits: tag. '07' for extended tags.
- // - byte 1 remaining bits: the length of data block.
- // - byte 2: the extended tag. '0' for video capability.
- // - byte 3: the capability.
- unsigned char tag = data_block[0] >> 5;
- unsigned char payload_length = data_block[0] & 0x1f;
- if (static_cast<unsigned long>(data_block + payload_length - prop) >
- nitems)
- break;
-
- if (tag != kExtendedTag || payload_length < 2) {
- data_block += payload_length + 1;
- continue;
- }
-
- unsigned char extended_tag_code = data_block[1];
- if (extended_tag_code != kExtendedVideoCapabilityTag) {
- data_block += payload_length + 1;
- continue;
- }
-
- // The difference between preferred, IT, and CE video formats
- // doesn't matter. Sets |flag| to true if any of these flags are true.
- if ((data_block[2] & (1 << kPTOverscan)) ||
- (data_block[2] & (1 << kITOverscan)) ||
- (data_block[2] & (1 << kCEOverscan))) {
- *flag = true;
- } else {
- *flag = false;
- }
- return true;
- }
- }
-
- return false;
-}
-
-} // namespace ui
diff --git a/ui/display/chromeos/x11/display_util.h b/ui/display/chromeos/x11/display_util.h
deleted file mode 100644
index 33d9545..0000000
--- a/ui/display/chromeos/x11/display_util.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-#ifndef UI_DISPLAY_CHROMEOS_DISPLAY_UTIL_H_
-#define UI_DISPLAY_CHROMEOS_DISPLAY_UTIL_H_
-
-#include <string>
-
-#include "ui/display/display_constants.h"
-#include "ui/display/display_export.h"
-
-typedef unsigned long RROutput;
-
-namespace ui {
-
-// Returns the OutputType by matching known type prefixes to |name|. Returns
-// OUTPUT_TYPE_UNKNOWN if no valid match.
-DISPLAY_EXPORT OutputType GetOutputTypeFromName(const std::string& name);
-
-// Generate the human readable string from EDID obtained from |output|.
-DISPLAY_EXPORT std::string GetDisplayName(RROutput output);
-
-// Gets the overscan flag from |output| and stores to |flag|. Returns true if
-// the flag is found. Otherwise returns false and doesn't touch |flag|. The
-// output will produce overscan if |flag| is set to true, but the output may
-// still produce overscan even though it returns true and |flag| is set to
-// false.
-DISPLAY_EXPORT bool GetOutputOverscanFlag(RROutput output, bool* flag);
-
-DISPLAY_EXPORT bool ParseOutputOverscanFlag(const unsigned char* prop,
- unsigned long nitems,
- bool* flag);
-
-} // namespace ui
-
-#endif // UI_DISPLAY_CHROMEOS_DISPLAY_UTIL_H_
diff --git a/ui/display/chromeos/x11/display_util_x11.cc b/ui/display/chromeos/x11/display_util_x11.cc
new file mode 100644
index 0000000..f5a4f27
--- /dev/null
+++ b/ui/display/chromeos/x11/display_util_x11.cc
@@ -0,0 +1,41 @@
+// 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/chromeos/x11/display_util_x11.h"
+
+#include "base/macros.h"
+
+namespace ui {
+
+namespace {
+
+struct OutputTypeMapping {
+ // Prefix of output name.
+ const char* name;
+ OutputType type;
+};
+
+const OutputTypeMapping kOutputTypeMapping[] = {
+ {"LVDS", OUTPUT_TYPE_INTERNAL},
+ {"eDP", OUTPUT_TYPE_INTERNAL},
+ {"DSI", OUTPUT_TYPE_INTERNAL},
+ {"VGA", OUTPUT_TYPE_VGA},
+ {"HDMI", OUTPUT_TYPE_HDMI},
+ {"DVI", OUTPUT_TYPE_DVI},
+ {"DP", OUTPUT_TYPE_DISPLAYPORT}
+};
+
+} // namespace
+
+OutputType GetOutputTypeFromName(const std::string& name) {
+ for (unsigned int i = 0; i < arraysize(kOutputTypeMapping); ++i) {
+ if (name.find(kOutputTypeMapping[i].name) == 0) {
+ return kOutputTypeMapping[i].type;
+ }
+ }
+
+ return OUTPUT_TYPE_UNKNOWN;
+}
+
+} // namespace ui
diff --git a/ui/display/chromeos/x11/display_util_x11.h b/ui/display/chromeos/x11/display_util_x11.h
new file mode 100644
index 0000000..c8a7837
--- /dev/null
+++ b/ui/display/chromeos/x11/display_util_x11.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef UI_DISPLAY_CHROMEOS_DISPLAY_UTIL_X11_H_
+#define UI_DISPLAY_CHROMEOS_DISPLAY_UTIL_X11_H_
+
+#include <string>
+
+#include "ui/display/display_constants.h"
+#include "ui/display/display_export.h"
+
+typedef unsigned long XID;
+typedef XID RROutput;
+
+namespace ui {
+
+// Returns the OutputType by matching known type prefixes to |name|. Returns
+// OUTPUT_TYPE_UNKNOWN if no valid match.
+DISPLAY_EXPORT OutputType GetOutputTypeFromName(const std::string& name);
+
+} // namespace ui
+
+#endif // UI_DISPLAY_CHROMEOS_DISPLAY_UTIL_X11_H_
diff --git a/ui/display/chromeos/x11/display_util_x11_unittest.cc b/ui/display/chromeos/x11/display_util_x11_unittest.cc
new file mode 100644
index 0000000..e178f7f
--- /dev/null
+++ b/ui/display/chromeos/x11/display_util_x11_unittest.cc
@@ -0,0 +1,42 @@
+// 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/chromeos/x11/display_util_x11.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ui {
+
+TEST(DisplayUtilX11Test, GetOutputTypeFromName) {
+ EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("LVDS"));
+ EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("eDP"));
+ EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("DSI"));
+ EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("LVDSxx"));
+ EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("eDPzz"));
+ EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("DSIyy"));
+
+ EXPECT_EQ(OUTPUT_TYPE_VGA, GetOutputTypeFromName("VGA"));
+ EXPECT_EQ(OUTPUT_TYPE_VGA, GetOutputTypeFromName("VGAxx"));
+ EXPECT_EQ(OUTPUT_TYPE_HDMI, GetOutputTypeFromName("HDMI"));
+ EXPECT_EQ(OUTPUT_TYPE_HDMI, GetOutputTypeFromName("HDMIyy"));
+ EXPECT_EQ(OUTPUT_TYPE_DVI, GetOutputTypeFromName("DVI"));
+ EXPECT_EQ(OUTPUT_TYPE_DVI, GetOutputTypeFromName("DVIzz"));
+ EXPECT_EQ(OUTPUT_TYPE_DISPLAYPORT, GetOutputTypeFromName("DP"));
+ EXPECT_EQ(OUTPUT_TYPE_DISPLAYPORT, GetOutputTypeFromName("DPww"));
+
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("xyz"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("abcLVDS"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("cdeeDP"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("abcDSI"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("LVD"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("eD"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("DS"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("VG"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("HDM"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("DV"));
+ EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("D"));
+}
+
+} // namespace ui
diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.cc b/ui/display/chromeos/x11/native_display_delegate_x11.cc
index b56146e..e4bfbfc 100644
--- a/ui/display/chromeos/x11/native_display_delegate_x11.cc
+++ b/ui/display/chromeos/x11/native_display_delegate_x11.cc
@@ -16,12 +16,12 @@
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_pump_x11.h"
#include "base/stl_util.h"
-#include "base/x11/edid_parser_x11.h"
#include "ui/display/chromeos/native_display_observer.h"
#include "ui/display/chromeos/x11/display_mode_x11.h"
#include "ui/display/chromeos/x11/display_snapshot_x11.h"
-#include "ui/display/chromeos/x11/display_util.h"
+#include "ui/display/chromeos/x11/display_util_x11.h"
#include "ui/display/chromeos/x11/native_display_event_dispatcher_x11.h"
+#include "ui/display/x11/edid_parser_x11.h"
#include "ui/gfx/x/x11_error_tracker.h"
namespace ui {
@@ -343,7 +343,8 @@ DisplaySnapshotX11* NativeDisplayDelegateX11::InitDisplaySnapshot(
RRCrtc* last_used_crtc,
int index) {
int64_t display_id = 0;
- bool has_display_id = base::GetDisplayId(id, index, &display_id);
+ bool has_display_id = GetDisplayId(
+ id, static_cast<uint8>(index), &display_id);
OutputType type = GetOutputTypeFromName(info->name);
if (type == OUTPUT_TYPE_UNKNOWN)
diff --git a/ui/display/display.gyp b/ui/display/display.gyp
index 5f766ac..d11fa4f 100644
--- a/ui/display/display.gyp
+++ b/ui/display/display.gyp
@@ -27,12 +27,12 @@
'chromeos/native_display_observer.h',
'chromeos/output_configurator.cc',
'chromeos/output_configurator.h',
- 'chromeos/x11/display_util.cc',
- 'chromeos/x11/display_util.h',
'chromeos/x11/display_mode_x11.cc',
'chromeos/x11/display_mode_x11.h',
'chromeos/x11/display_snapshot_x11.cc',
'chromeos/x11/display_snapshot_x11.h',
+ 'chromeos/x11/display_util_x11.cc',
+ 'chromeos/x11/display_util_x11.h',
'chromeos/x11/native_display_delegate_x11.cc',
'chromeos/x11/native_display_delegate_x11.h',
'chromeos/x11/native_display_event_dispatcher_x11.cc',
@@ -41,6 +41,10 @@
'chromeos/x11/touchscreen_delegate_x11.h',
'display_constants.h',
'display_export.h',
+ 'edid_parser.cc',
+ 'edid_parser.h',
+ 'x11/edid_parser_x11.cc',
+ 'x11/edid_parser_x11.h',
],
'conditions': [
['use_x11 == 1', {
diff --git a/ui/display/display_unittests.gypi b/ui/display/display_unittests.gypi
index 6597bb9..591bde5 100644
--- a/ui/display/display_unittests.gypi
+++ b/ui/display/display_unittests.gypi
@@ -8,11 +8,13 @@
'dependencies': [
'../base/base.gyp:test_support_base',
'../testing/gtest.gyp:gtest',
+ '../ui/display/display.gyp:display',
'../ui/gfx/gfx.gyp:gfx_geometry',
],
'sources': [
+ 'edid_parser_unittest.cc',
'chromeos/output_configurator_unittest.cc',
- 'chromeos/x11/display_util_unittest.cc',
+ 'chromeos/x11/display_util_x11_unittest.cc',
'chromeos/x11/native_display_event_dispatcher_x11_unittest.cc',
],
'conditions': [
@@ -21,7 +23,6 @@
# not like empty libraries.
['chromeos == 1', {
'dependencies': [
- '../ui/display/display.gyp:display',
'../ui/display/display.gyp:display_test_util',
],
}],
diff --git a/ui/display/edid_parser.cc b/ui/display/edid_parser.cc
new file mode 100644
index 0000000..0660bdb
--- /dev/null
+++ b/ui/display/edid_parser.cc
@@ -0,0 +1,208 @@
+// 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/edid_parser.h"
+
+#include <algorithm>
+
+#include "base/hash.h"
+#include "base/strings/string_util.h"
+#include "base/sys_byteorder.h"
+
+namespace ui {
+
+namespace {
+
+// Returns 64-bit persistent ID for the specified manufacturer's ID and
+// product_code_hash, and the index of the output it is connected to.
+// |output_index| is used to distinguish the displays of the same type. For
+// example, swapping two identical display between two outputs will not be
+// treated as swap. The 'serial number' field in EDID isn't used here because
+// it is not guaranteed to have unique number and it may have the same fixed
+// value (like 0).
+int64 GetID(uint16 manufacturer_id,
+ uint32 product_code_hash,
+ uint8 output_index) {
+ return ((static_cast<int64>(manufacturer_id) << 40) |
+ (static_cast<int64>(product_code_hash) << 8) | output_index);
+}
+
+} // namespace
+
+bool GetDisplayIdFromEDID(const unsigned char* prop,
+ unsigned long nitems,
+ uint8 output_index,
+ int64* display_id_out) {
+ uint16 manufacturer_id = 0;
+ std::string product_name;
+
+ // ParseOutputDeviceData fails if it doesn't have product_name.
+ ParseOutputDeviceData(prop, nitems, &manufacturer_id, &product_name);
+
+ // Generates product specific value from product_name instead of product code.
+ // See crbug.com/240341
+ uint32 product_code_hash = product_name.empty() ?
+ 0 : base::Hash(product_name);
+ if (manufacturer_id != 0) {
+ // An ID based on display's index will be assigned later if this call
+ // fails.
+ *display_id_out = GetID(
+ manufacturer_id, product_code_hash, output_index);
+ return true;
+ }
+ return false;
+}
+
+bool ParseOutputDeviceData(const unsigned char* prop,
+ unsigned long nitems,
+ uint16* manufacturer_id,
+ std::string* human_readable_name) {
+ // See http://en.wikipedia.org/wiki/Extended_display_identification_data
+ // for the details of EDID data format. We use the following data:
+ // bytes 8-9: manufacturer EISA ID, in big-endian
+ // bytes 54-125: four descriptors (18-bytes each) which may contain
+ // the display name.
+ const unsigned int kManufacturerOffset = 8;
+ const unsigned int kManufacturerLength = 2;
+ const unsigned int kDescriptorOffset = 54;
+ const unsigned int kNumDescriptors = 4;
+ const unsigned int kDescriptorLength = 18;
+ // The specifier types.
+ const unsigned char kMonitorNameDescriptor = 0xfc;
+
+ if (manufacturer_id) {
+ if (nitems < kManufacturerOffset + kManufacturerLength) {
+ LOG(ERROR) << "too short EDID data: manifacturer id";
+ return false;
+ }
+
+ *manufacturer_id =
+ *reinterpret_cast<const uint16*>(prop + kManufacturerOffset);
+#if defined(ARCH_CPU_LITTLE_ENDIAN)
+ *manufacturer_id = base::ByteSwap(*manufacturer_id);
+#endif
+ }
+
+ if (!human_readable_name)
+ return true;
+
+ human_readable_name->clear();
+ for (unsigned int i = 0; i < kNumDescriptors; ++i) {
+ if (nitems < kDescriptorOffset + (i + 1) * kDescriptorLength)
+ break;
+
+ const unsigned char* desc_buf =
+ prop + kDescriptorOffset + i * kDescriptorLength;
+ // If the descriptor contains the display name, it has the following
+ // structure:
+ // bytes 0-2, 4: \0
+ // byte 3: descriptor type, defined above.
+ // bytes 5-17: text data, ending with \r, padding with spaces
+ // we should check bytes 0-2 and 4, since it may have other values in
+ // case that the descriptor contains other type of data.
+ if (desc_buf[0] == 0 && desc_buf[1] == 0 && desc_buf[2] == 0 &&
+ desc_buf[4] == 0) {
+ if (desc_buf[3] == kMonitorNameDescriptor) {
+ std::string found_name(
+ reinterpret_cast<const char*>(desc_buf + 5), kDescriptorLength - 5);
+ base::TrimWhitespaceASCII(
+ found_name, base::TRIM_TRAILING, human_readable_name);
+ break;
+ }
+ }
+ }
+
+ // Verify if the |human_readable_name| consists of printable characters only.
+ for (size_t i = 0; i < human_readable_name->size(); ++i) {
+ char c = (*human_readable_name)[i];
+ if (!isascii(c) || !isprint(c)) {
+ human_readable_name->clear();
+ LOG(ERROR) << "invalid EDID: human unreadable char in name";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ParseOutputOverscanFlag(const unsigned char* prop,
+ unsigned long nitems,
+ bool* flag) {
+ // See http://en.wikipedia.org/wiki/Extended_display_identification_data
+ // for the extension format of EDID. Also see EIA/CEA-861 spec for
+ // the format of the extensions and how video capability is encoded.
+ // - byte 0: tag. should be 02h.
+ // - byte 1: revision. only cares revision 3 (03h).
+ // - byte 4-: data block.
+ const unsigned int kExtensionBase = 128;
+ const unsigned int kExtensionSize = 128;
+ const unsigned int kNumExtensionsOffset = 126;
+ const unsigned int kDataBlockOffset = 4;
+ const unsigned char kCEAExtensionTag = '\x02';
+ const unsigned char kExpectedExtensionRevision = '\x03';
+ const unsigned char kExtendedTag = 7;
+ const unsigned char kExtendedVideoCapabilityTag = 0;
+ const unsigned int kPTOverscan = 4;
+ const unsigned int kITOverscan = 2;
+ const unsigned int kCEOverscan = 0;
+
+ if (nitems <= kNumExtensionsOffset)
+ return false;
+
+ unsigned char num_extensions = prop[kNumExtensionsOffset];
+
+ for (size_t i = 0; i < num_extensions; ++i) {
+ // Skip parsing the whole extension if size is not enough.
+ if (nitems < kExtensionBase + (i + 1) * kExtensionSize)
+ break;
+
+ const unsigned char* extension = prop + kExtensionBase + i * kExtensionSize;
+ unsigned char tag = extension[0];
+ unsigned char revision = extension[1];
+ if (tag != kCEAExtensionTag || revision != kExpectedExtensionRevision)
+ continue;
+
+ unsigned char timing_descriptors_start =
+ std::min(extension[2], static_cast<unsigned char>(kExtensionSize));
+ const unsigned char* data_block = extension + kDataBlockOffset;
+ while (data_block < extension + timing_descriptors_start) {
+ // A data block is encoded as:
+ // - byte 1 high 3 bits: tag. '07' for extended tags.
+ // - byte 1 remaining bits: the length of data block.
+ // - byte 2: the extended tag. '0' for video capability.
+ // - byte 3: the capability.
+ unsigned char tag = data_block[0] >> 5;
+ unsigned char payload_length = data_block[0] & 0x1f;
+ if (static_cast<unsigned long>(data_block + payload_length - prop) >
+ nitems)
+ break;
+
+ if (tag != kExtendedTag || payload_length < 2) {
+ data_block += payload_length + 1;
+ continue;
+ }
+
+ unsigned char extended_tag_code = data_block[1];
+ if (extended_tag_code != kExtendedVideoCapabilityTag) {
+ data_block += payload_length + 1;
+ continue;
+ }
+
+ // The difference between preferred, IT, and CE video formats
+ // doesn't matter. Sets |flag| to true if any of these flags are true.
+ if ((data_block[2] & (1 << kPTOverscan)) ||
+ (data_block[2] & (1 << kITOverscan)) ||
+ (data_block[2] & (1 << kCEOverscan))) {
+ *flag = true;
+ } else {
+ *flag = false;
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace ui
diff --git a/ui/display/edid_parser.h b/ui/display/edid_parser.h
new file mode 100644
index 0000000..38361cd
--- /dev/null
+++ b/ui/display/edid_parser.h
@@ -0,0 +1,41 @@
+// 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.
+
+#ifndef UI_DISPLAY_EDID_PARSER_H_
+#define UI_DISPLAY_EDID_PARSER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "ui/display/display_export.h"
+
+// EDID (Extended Display Identification Data) is a format for monitor
+// metadata. This provides a parser for the data.
+
+namespace ui {
+
+// Generates the display id for the pair of |prop| with |nitems| length and
+// |index|, and store in |display_id_out|. Returns true if the display id is
+// successfully generated, or false otherwise.
+DISPLAY_EXPORT bool GetDisplayIdFromEDID(const unsigned char* prop,
+ unsigned long nitems,
+ uint8 index,
+ int64* display_id_out);
+
+// Parses |prop| as EDID data and stores extracted data into |manufacturer_id|
+// and |human_readable_name| and returns true. NULL can be passed for unwanted
+// output parameters. Some devices (especially internal displays) may not have
+// the field for |human_readable_name|, and it will return true in that case.
+DISPLAY_EXPORT bool ParseOutputDeviceData(const unsigned char* prop,
+ unsigned long nitems,
+ uint16* manufacturer_id,
+ std::string* human_readable_name);
+
+DISPLAY_EXPORT bool ParseOutputOverscanFlag(const unsigned char* prop,
+ unsigned long nitems,
+ bool* flag);
+
+} // namespace ui
+
+#endif // UI_DISPLAY_EDID_PARSER_H_
diff --git a/ui/display/chromeos/x11/display_util_unittest.cc b/ui/display/edid_parser_unittest.cc
index 03a6af5..8026df6 100644
--- a/ui/display/chromeos/x11/display_util_unittest.cc
+++ b/ui/display/edid_parser_unittest.cc
@@ -2,13 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/display/chromeos/x11/display_util.h"
+#include "ui/display/edid_parser.h"
#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include <X11/extensions/Xrandr.h>
-
namespace ui {
namespace {
@@ -57,7 +55,7 @@ const unsigned char kOverscanDisplay[] =
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc6";
// The EDID info misdetecting overscan once. see crbug.com/226318
-const unsigned char kMisdetecedDisplay[] =
+const unsigned char kMisdetectedDisplay[] =
"\x00\xff\xff\xff\xff\xff\xff\x00\x10\xac\x64\x40\x4c\x30\x30\x32"
"\x0c\x15\x01\x03\x80\x40\x28\x78\xea\x8d\x85\xad\x4f\x35\xb1\x25"
"\x0e\x50\x54\xa5\x4b\x00\x71\x4f\x81\x00\x81\x80\xd1\x00\xa9\x40"
@@ -75,9 +73,29 @@ const unsigned char kMisdetecedDisplay[] =
"\x0a\xd0\x8a\x20\xe0\x2d\x10\x10\x3e\x96\x00\x81\x91\x21\x00\x00"
"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94";
+const unsigned char kLP2565A[] =
+ "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x22\xF0\x76\x26\x01\x01\x01\x01"
+ "\x02\x12\x01\x03\x80\x34\x21\x78\xEE\xEF\x95\xA3\x54\x4C\x9B\x26"
+ "\x0F\x50\x54\xA5\x6B\x80\x81\x40\x81\x80\x81\x99\x71\x00\xA9\x00"
+ "\xA9\x40\xB3\x00\xD1\x00\x28\x3C\x80\xA0\x70\xB0\x23\x40\x30\x20"
+ "\x36\x00\x07\x44\x21\x00\x00\x1A\x00\x00\x00\xFD\x00\x30\x55\x1E"
+ "\x5E\x11\x00\x0A\x20\x20\x20\x20\x20\x20\x00\x00\x00\xFC\x00\x48"
+ "\x50\x20\x4C\x50\x32\x34\x36\x35\x0A\x20\x20\x20\x00\x00\x00\xFF"
+ "\x00\x43\x4E\x4B\x38\x30\x32\x30\x34\x48\x4D\x0A\x20\x20\x00\xA4";
+
+const unsigned char kLP2565B[] =
+ "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x22\xF0\x75\x26\x01\x01\x01\x01"
+ "\x02\x12\x01\x03\x6E\x34\x21\x78\xEE\xEF\x95\xA3\x54\x4C\x9B\x26"
+ "\x0F\x50\x54\xA5\x6B\x80\x81\x40\x71\x00\xA9\x00\xA9\x40\xA9\x4F"
+ "\xB3\x00\xD1\xC0\xD1\x00\x28\x3C\x80\xA0\x70\xB0\x23\x40\x30\x20"
+ "\x36\x00\x07\x44\x21\x00\x00\x1A\x00\x00\x00\xFD\x00\x30\x55\x1E"
+ "\x5E\x15\x00\x0A\x20\x20\x20\x20\x20\x20\x00\x00\x00\xFC\x00\x48"
+ "\x50\x20\x4C\x50\x32\x34\x36\x35\x0A\x20\x20\x20\x00\x00\x00\xFF"
+ "\x00\x43\x4E\x4B\x38\x30\x32\x30\x34\x48\x4D\x0A\x20\x20\x00\x45";
+
} // namespace
-TEST(DisplayUtilTest, ParseOverscanFlag) {
+TEST(EDIDParserTest, ParseOverscanFlag) {
bool flag = false;
EXPECT_FALSE(
ParseOutputOverscanFlag(kNormalDisplay, charsize(kNormalDisplay), &flag));
@@ -93,7 +111,7 @@ TEST(DisplayUtilTest, ParseOverscanFlag) {
flag = false;
EXPECT_FALSE(ParseOutputOverscanFlag(
- kMisdetecedDisplay, charsize(kMisdetecedDisplay), &flag));
+ kMisdetectedDisplay, charsize(kMisdetectedDisplay), &flag));
flag = false;
// Copy |kOverscanDisplay| and set flags to false in it. The overscan flags
@@ -109,7 +127,7 @@ TEST(DisplayUtilTest, ParseOverscanFlag) {
EXPECT_FALSE(flag);
}
-TEST(DisplayUtilTest, ParseBrokenOverscanData) {
+TEST(EDIDParserTest, ParseBrokenOverscanData) {
// Do not fill valid data here because it anyway fails to parse the data.
scoped_ptr<unsigned char[]> data(new unsigned char[126]);
bool flag = false;
@@ -124,34 +142,90 @@ TEST(DisplayUtilTest, ParseBrokenOverscanData) {
EXPECT_FALSE(ParseOutputOverscanFlag(data.get(), 150, &flag));
}
-TEST(DisplayUtilTest, GetOutputTypeFromName) {
- EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("LVDS"));
- EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("eDP"));
- EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("DSI"));
- EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("LVDSxx"));
- EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("eDPzz"));
- EXPECT_EQ(OUTPUT_TYPE_INTERNAL, GetOutputTypeFromName("DSIyy"));
-
- EXPECT_EQ(OUTPUT_TYPE_VGA, GetOutputTypeFromName("VGA"));
- EXPECT_EQ(OUTPUT_TYPE_VGA, GetOutputTypeFromName("VGAxx"));
- EXPECT_EQ(OUTPUT_TYPE_HDMI, GetOutputTypeFromName("HDMI"));
- EXPECT_EQ(OUTPUT_TYPE_HDMI, GetOutputTypeFromName("HDMIyy"));
- EXPECT_EQ(OUTPUT_TYPE_DVI, GetOutputTypeFromName("DVI"));
- EXPECT_EQ(OUTPUT_TYPE_DVI, GetOutputTypeFromName("DVIzz"));
- EXPECT_EQ(OUTPUT_TYPE_DISPLAYPORT, GetOutputTypeFromName("DP"));
- EXPECT_EQ(OUTPUT_TYPE_DISPLAYPORT, GetOutputTypeFromName("DPww"));
-
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("xyz"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("abcLVDS"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("cdeeDP"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("abcDSI"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("LVD"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("eD"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("DS"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("VG"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("HDM"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("DV"));
- EXPECT_EQ(OUTPUT_TYPE_UNKNOWN, GetOutputTypeFromName("D"));
+TEST(EDIDParserTest, ParseEDID) {
+ uint16 manufacturer_id = 0;
+ std::string human_readable_name;
+ EXPECT_TRUE(ParseOutputDeviceData(
+ kNormalDisplay, charsize(kNormalDisplay),
+ &manufacturer_id, &human_readable_name));
+ EXPECT_EQ(0x22f0u, manufacturer_id);
+ EXPECT_EQ("HP ZR30w", human_readable_name);
+
+ manufacturer_id = 0;
+ human_readable_name.clear();
+ EXPECT_TRUE(ParseOutputDeviceData(
+ kInternalDisplay, charsize(kInternalDisplay),
+ &manufacturer_id, NULL));
+ EXPECT_EQ(0x4ca3u, manufacturer_id);
+ EXPECT_EQ("", human_readable_name);
+
+ // Internal display doesn't have name.
+ EXPECT_TRUE(ParseOutputDeviceData(
+ kInternalDisplay, charsize(kInternalDisplay),
+ NULL, &human_readable_name));
+ EXPECT_TRUE(human_readable_name.empty());
+
+ manufacturer_id = 0;
+ human_readable_name.clear();
+ EXPECT_TRUE(ParseOutputDeviceData(
+ kOverscanDisplay, charsize(kOverscanDisplay),
+ &manufacturer_id, &human_readable_name));
+ EXPECT_EQ(0x4c2du, manufacturer_id);
+ EXPECT_EQ("SAMSUNG", human_readable_name);
+}
+
+TEST(EDIDParserTest, ParseBrokenEDID) {
+ uint16 manufacturer_id = 0;
+ std::string human_readable_name;
+
+ // length == 0
+ EXPECT_FALSE(ParseOutputDeviceData(
+ kNormalDisplay, 0,
+ &manufacturer_id, &human_readable_name));
+
+ // name is broken. Copying kNormalDisplay and substitute its name data by
+ // some control code.
+ std::string display_data(
+ reinterpret_cast<const char*>(kNormalDisplay), charsize(kNormalDisplay));
+
+ // display's name data is embedded in byte 95-107 in this specific example.
+ // Fix here too when the contents of kNormalDisplay is altered.
+ display_data[97] = '\x1b';
+ EXPECT_FALSE(ParseOutputDeviceData(
+ reinterpret_cast<const unsigned char*>(display_data.data()),
+ display_data.size(),
+ &manufacturer_id, &human_readable_name));
+
+ // If |human_readable_name| isn't specified, it skips parsing the name.
+ manufacturer_id = 0;
+ EXPECT_TRUE(ParseOutputDeviceData(
+ reinterpret_cast<const unsigned char*>(display_data.data()),
+ display_data.size(),
+ &manufacturer_id, NULL));
+ EXPECT_EQ(0x22f0u, manufacturer_id);
+}
+
+TEST(EDIDParserTest, GetDisplayId) {
+ // EDID of kLP2565A and B are slightly different but actually the same device.
+ int64 id1 = -1;
+ int64 id2 = -1;
+ EXPECT_TRUE(GetDisplayIdFromEDID(kLP2565A, charsize(kLP2565A), 0, &id1));
+ EXPECT_TRUE(GetDisplayIdFromEDID(kLP2565B, charsize(kLP2565B), 0, &id2));
+ EXPECT_EQ(id1, id2);
+ EXPECT_NE(-1, id1);
+}
+
+TEST(EDIDParserTest, GetDisplayIdFromInternal) {
+ int64 id = -1;
+ EXPECT_TRUE(GetDisplayIdFromEDID(
+ kInternalDisplay, charsize(kInternalDisplay), 0, &id));
+ EXPECT_NE(-1, id);
+}
+
+TEST(EDIDParserTest, GetDisplayIdFailure) {
+ int64 id = -1;
+ EXPECT_FALSE(GetDisplayIdFromEDID(NULL, 0, 0, &id));
+ EXPECT_EQ(-1, id);
}
-} // namespace ui
+} // namespace ui
diff --git a/ui/display/x11/edid_parser_x11.cc b/ui/display/x11/edid_parser_x11.cc
new file mode 100644
index 0000000..146c5a7
--- /dev/null
+++ b/ui/display/x11/edid_parser_x11.cc
@@ -0,0 +1,121 @@
+// 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/x11/edid_parser_x11.h"
+
+#include <X11/extensions/Xrandr.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_util.h"
+#include "ui/display/edid_parser.h"
+
+namespace ui {
+
+namespace {
+
+// 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.
+// NULL can be passed for unwanted output parameters.
+bool GetOutputDeviceData(XID output,
+ uint16* manufacturer_id,
+ std::string* human_readable_name) {
+ unsigned long nitems = 0;
+ unsigned char* prop = NULL;
+ if (!GetEDIDProperty(output, &nitems, &prop))
+ return false;
+
+ bool result = ParseOutputDeviceData(
+ prop, nitems, manufacturer_id, human_readable_name);
+ XFree(prop);
+ return result;
+}
+
+bool IsRandRAvailable() {
+ int randr_version_major = 0;
+ int randr_version_minor = 0;
+ static bool is_randr_available = XRRQueryVersion(
+ base::MessagePumpX11::GetDefaultXDisplay(),
+ &randr_version_major, &randr_version_minor);
+ return is_randr_available;
+}
+
+} // namespace
+
+bool GetEDIDProperty(XID output, unsigned long* nitems, unsigned char** prop) {
+ if (!IsRandRAvailable())
+ return false;
+
+ Display* display = base::MessagePumpX11::GetDefaultXDisplay();
+
+ static Atom edid_property = XInternAtom(
+ base::MessagePumpX11::GetDefaultXDisplay(),
+ RR_PROPERTY_RANDR_EDID, false);
+
+ bool has_edid_property = false;
+ int num_properties = 0;
+ Atom* properties = XRRListOutputProperties(display, output, &num_properties);
+ for (int i = 0; i < num_properties; ++i) {
+ if (properties[i] == edid_property) {
+ has_edid_property = true;
+ break;
+ }
+ }
+ XFree(properties);
+ if (!has_edid_property)
+ return false;
+
+ Atom actual_type;
+ int actual_format;
+ unsigned long bytes_after;
+ 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);
+ return true;
+}
+
+bool GetDisplayId(XID output_id, uint8 output_index, int64* display_id_out) {
+ unsigned long nitems = 0;
+ unsigned char* prop = NULL;
+ if (!GetEDIDProperty(output_id, &nitems, &prop))
+ return false;
+
+ bool result =
+ GetDisplayIdFromEDID(prop, nitems, output_index, display_id_out);
+ XFree(prop);
+ return result;
+}
+
+std::string GetDisplayName(RROutput output) {
+ std::string display_name;
+ GetOutputDeviceData(output, NULL, &display_name);
+ return display_name;
+}
+
+bool GetOutputOverscanFlag(RROutput output, bool* flag) {
+ unsigned long nitems = 0;
+ unsigned char* prop = NULL;
+ if (!GetEDIDProperty(output, &nitems, &prop))
+ return false;
+
+ bool found = ParseOutputOverscanFlag(prop, nitems, flag);
+ XFree(prop);
+ return found;
+}
+
+} // namespace ui
diff --git a/ui/display/x11/edid_parser_x11.h b/ui/display/x11/edid_parser_x11.h
new file mode 100644
index 0000000..730baae
--- /dev/null
+++ b/ui/display/x11/edid_parser_x11.h
@@ -0,0 +1,48 @@
+// 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.
+
+#ifndef UI_DISPLAY_X11_EDID_PARSER_X11_H_
+#define UI_DISPLAY_X11_EDID_PARSER_X11_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "ui/display/display_constants.h"
+#include "ui/display/display_export.h"
+
+typedef unsigned long XID;
+typedef XID RROutput;
+
+// Xrandr utility functions to help get EDID information.
+
+namespace ui {
+
+// Get the EDID data from the |output| and stores to |prop|. |nitem| will store
+// the number of characters |prop| will have. It doesn't take the ownership of
+// |prop|, so caller must release it by XFree().
+// Returns true if EDID property is successfully obtained. Otherwise returns
+// false and does not touch |prop| and |nitems|.
+DISPLAY_EXPORT bool GetEDIDProperty(XID output,
+ unsigned long* nitems,
+ unsigned char** prop);
+
+// Gets the EDID data from |output| and generates the display id through
+// |GetDisplayIdFromEDID|.
+DISPLAY_EXPORT bool GetDisplayId(XID output,
+ uint8 index,
+ int64* display_id_out);
+
+// Generate the human readable string from EDID obtained from |output|.
+DISPLAY_EXPORT std::string GetDisplayName(RROutput output);
+
+// Gets the overscan flag from |output| and stores to |flag|. Returns true if
+// the flag is found. Otherwise returns false and doesn't touch |flag|. The
+// output will produce overscan if |flag| is set to true, but the output may
+// still produce overscan even though it returns true and |flag| is set to
+// false.
+DISPLAY_EXPORT bool GetOutputOverscanFlag(RROutput output, bool* flag);
+
+} // namespace ui
+
+#endif // UI_DISPLAY_X11_EDID_PARSER_X11_H_
diff --git a/ui/views/DEPS b/ui/views/DEPS
index 065ceac..b29fbd8 100644
--- a/ui/views/DEPS
+++ b/ui/views/DEPS
@@ -8,6 +8,7 @@ include_rules = [
"+ui/aura",
"+ui/base",
"+ui/compositor",
+ "+ui/display",
"+ui/events",
"+ui/gfx",
"+ui/gl/gl_surface.h", # To initialize GL for tests.
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index a099de7..7295a4a 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -433,6 +433,11 @@
'bubble/tray_bubble_view.h',
],
}],
+ ['chromeos==0 and use_x11==1', {
+ 'dependencies': [
+ '../display/display.gyp:display',
+ ],
+ }],
['OS=="linux" and chromeos==0', {
'dependencies': [
'../shell_dialogs/shell_dialogs.gyp:shell_dialogs',
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
index f5a6a7f..970d86c 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -12,12 +12,12 @@
#include "base/debug/trace_event.h"
#include "base/logging.h"
-#include "base/x11/edid_parser_x11.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/layout.h"
#include "ui/base/x/x11_util.h"
+#include "ui/display/x11/edid_parser_x11.h"
#include "ui/gfx/display.h"
#include "ui/gfx/display_observer.h"
#include "ui/gfx/native_widget_types.h"
@@ -376,7 +376,7 @@ std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
output_info->crtc);
int64 display_id = -1;
- if (!base::GetDisplayId(output_id, i, &display_id)) {
+ if (!ui::GetDisplayId(output_id, static_cast<uint8>(i), &display_id)) {
// It isn't ideal, but if we can't parse the EDID data, fallback on the
// display number.
display_id = i;