OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/display/output_util.h" | 5 #include "chromeos/display/output_util.h" |
6 | 6 |
7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
8 #include <X11/extensions/Xrandr.h> | 8 #include <X11/extensions/Xrandr.h> |
9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
10 | 10 |
11 #include "base/hash.h" | |
11 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
13 #include "base/sys_byteorder.h" | 14 #include "base/sys_byteorder.h" |
14 | 15 |
15 namespace chromeos { | 16 namespace chromeos { |
16 namespace { | 17 namespace { |
17 | 18 |
18 // Prefixes for the built-in displays. | 19 // Prefixes for the built-in displays. |
19 const char kInternal_LVDS[] = "LVDS"; | 20 const char kInternal_LVDS[] = "LVDS"; |
20 const char kInternal_eDP[] = "eDP"; | 21 const char kInternal_eDP[] = "eDP"; |
21 | 22 |
22 // Returns 64-bit persistent ID for the specified manufacturer's ID and | 23 // Returns 64-bit persistent ID for the specified manufacturer's ID and |
23 // product_code, and the index of the output it is connected to. | 24 // product_name, and the index of the output it is connected to. |
24 // |output_index| is used to distinguish the displays of the same type. For | 25 // |output_index| is used to distinguish the displays of the same type. For |
25 // example, swapping two identical display between two outputs will not be | 26 // example, swapping two identical display between two outputs will not be |
26 // treated as swap. The 'serial number' field in EDID isn't used here because | 27 // treated as swap. The 'serial number' field in EDID isn't used here because |
27 // it is not guaranteed to have unique number and it may have the same fixed | 28 // it is not guaranteed to have unique number and it may have the same fixed |
28 // value (like 0). | 29 // value (like 0). |
29 int64 GetID(uint16 manufacturer_id, | 30 int64 GetID(uint16 manufacturer_id, |
30 uint16 product_code, | 31 uint32 product_code, |
31 uint8 output_index) { | 32 uint8 output_index) { |
32 return ((static_cast<int64>(manufacturer_id) << 24) | | 33 return ((static_cast<int64>(manufacturer_id) << 40) | |
33 (static_cast<int64>(product_code) << 8) | output_index); | 34 (static_cast<int64>(product_code) << 8) | output_index); |
34 } | 35 } |
35 | 36 |
36 bool IsRandRAvailable() { | 37 bool IsRandRAvailable() { |
37 int randr_version_major = 0; | 38 int randr_version_major = 0; |
38 int randr_version_minor = 0; | 39 int randr_version_minor = 0; |
39 static bool is_randr_available = XRRQueryVersion( | 40 static bool is_randr_available = XRRQueryVersion( |
40 base::MessagePumpAuraX11::GetDefaultXDisplay(), | 41 base::MessagePumpAuraX11::GetDefaultXDisplay(), |
41 &randr_version_major, &randr_version_minor); | 42 &randr_version_major, &randr_version_minor); |
42 return is_randr_available; | 43 return is_randr_available; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 | 115 |
115 std::string GetDisplayName(XID output_id) { | 116 std::string GetDisplayName(XID output_id) { |
116 std::string display_name; | 117 std::string display_name; |
117 GetOutputDeviceData(output_id, NULL, NULL, &display_name); | 118 GetOutputDeviceData(output_id, NULL, NULL, &display_name); |
118 return display_name; | 119 return display_name; |
119 } | 120 } |
120 | 121 |
121 bool GetDisplayId(XID output_id, size_t output_index, int64* display_id_out) { | 122 bool GetDisplayId(XID output_id, size_t output_index, int64* display_id_out) { |
122 uint16 manufacturer_id = 0; | 123 uint16 manufacturer_id = 0; |
123 uint16 product_code = 0; | 124 uint16 product_code = 0; |
124 if (GetOutputDeviceData( | 125 std::string product_name; |
125 output_id, &manufacturer_id, &product_code, NULL) && | 126 |
126 manufacturer_id != 0) { | 127 // GetOutputDeviceData fails if it doesn't have product_name. |
128 GetOutputDeviceData( | |
129 output_id, &manufacturer_id, &product_code, &product_name); | |
130 | |
131 // Generates product specific value from product_name. See crbug.com/240341 | |
132 // for why we prefer product name string instead of product code in EDID. | |
133 uint32 product_specific_code = product_name.empty() ? | |
134 static_cast<uint32>(product_code) : base::Hash(product_name); | |
oshima
2013/05/20 20:29:40
May be we should mask the product_code with 0xFFFF
marcheu
2013/05/20 20:54:43
I think it's fine either way. It's probably also f
Jun Mukai
2013/05/21 01:28:25
Hmm, I'm not sure what's the mask should be... is
oshima
2013/05/21 01:40:00
0xFFFC (sorry it was typo) produces 9844 for 9846/
| |
135 if (manufacturer_id != 0) { | |
127 // An ID based on display's index will be assigned later if this call | 136 // An ID based on display's index will be assigned later if this call |
128 // fails. | 137 // fails. |
129 *display_id_out = GetID(manufacturer_id, product_code, output_index); | 138 *display_id_out = GetID( |
139 manufacturer_id, product_specific_code, output_index); | |
130 return true; | 140 return true; |
131 } | 141 } |
132 return false; | 142 return false; |
133 } | 143 } |
134 | 144 |
135 bool ParseOutputDeviceData(const unsigned char* prop, | 145 bool ParseOutputDeviceData(const unsigned char* prop, |
136 unsigned long nitems, | 146 unsigned long nitems, |
137 uint16* manufacturer_id, | 147 uint16* manufacturer_id, |
138 uint16* product_code, | 148 uint16* product_code, |
139 std::string* human_readable_name) { | 149 std::string* human_readable_name) { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
310 } | 320 } |
311 | 321 |
312 return false; | 322 return false; |
313 } | 323 } |
314 | 324 |
315 bool IsInternalOutputName(const std::string& name) { | 325 bool IsInternalOutputName(const std::string& name) { |
316 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0; | 326 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0; |
317 } | 327 } |
318 | 328 |
319 } // namespace chromeos | 329 } // namespace chromeos |
OLD | NEW |