Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(509)

Side by Side Diff: ui/base/x/x11_util.cc

Issue 11725005: Checks the possibility of overscans from EDID extension data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« ui/base/x/x11_util.h ('K') | « ui/base/x/x11_util.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // This file defines utility functions for X11 (Linux only). This code has been 5 // This file defines utility functions for X11 (Linux only). This code has been
6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support 6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support
7 // remains woefully incomplete. 7 // remains woefully incomplete.
8 8
9 #include "ui/base/x/x11_util.h" 9 #include "ui/base/x/x11_util.h"
10 10
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 324 }
325 325
326 bool IsShapeAvailable() { 326 bool IsShapeAvailable() {
327 int dummy; 327 int dummy;
328 static bool is_shape_available = 328 static bool is_shape_available =
329 XShapeQueryExtension(ui::GetXDisplay(), &dummy, &dummy); 329 XShapeQueryExtension(ui::GetXDisplay(), &dummy, &dummy);
330 return is_shape_available; 330 return is_shape_available;
331 331
332 } 332 }
333 333
334 bool GetEDIDProperty(XID output, unsigned long* nitems, unsigned char* prop) {
Daniel Erat 2013/01/03 19:04:19 nit: add a comment stating that the caller must fr
Jun Mukai 2013/01/03 21:37:37 Done.
335 if (!IsRandRAvailable())
336 return false;
337
338 static Atom edid_property = GetAtom(RR_PROPERTY_RANDR_EDID);
339
340 Display* display = GetXDisplay();
341
342 bool has_edid_property = false;
343 int num_properties = 0;
344 Atom* properties = XRRListOutputProperties(display, output, &num_properties);
345 for (int i = 0; i < num_properties; ++i) {
346 if (properties[i] == edid_property) {
347 has_edid_property = true;
348 break;
349 }
350 }
351 XFree(properties);
352 if (!has_edid_property)
353 return false;
354
355 Atom actual_type;
356 int actual_format;
357 unsigned long bytes_after;
358 XRRGetOutputProperty(display,
359 output,
360 edid_property,
361 0, // offset
362 128, // length
363 false, // _delete
364 false, // pending
365 AnyPropertyType, // req_type
366 &actual_type,
367 &actual_format,
368 nitems,
369 &bytes_after,
370 &prop);
371 DCHECK_EQ(XA_INTEGER, actual_type);
372 DCHECK_EQ(8, actual_format);
373 return true;
374 }
375
334 } // namespace 376 } // namespace
335 377
336 bool XDisplayExists() { 378 bool XDisplayExists() {
337 return (GetXDisplay() != NULL); 379 return (GetXDisplay() != NULL);
338 } 380 }
339 381
340 Display* GetXDisplay() { 382 Display* GetXDisplay() {
341 return base::MessagePumpForUI::GetDefaultXDisplay(); 383 return base::MessagePumpForUI::GetDefaultXDisplay();
342 } 384 }
343 385
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 for (int i = 0; i < screen_resources->noutput; ++i) 1283 for (int i = 0; i < screen_resources->noutput; ++i)
1242 outputs->push_back(screen_resources->outputs[i]); 1284 outputs->push_back(screen_resources->outputs[i]);
1243 XRRFreeScreenResources(screen_resources); 1285 XRRFreeScreenResources(screen_resources);
1244 return true; 1286 return true;
1245 } 1287 }
1246 1288
1247 bool GetOutputDeviceData(XID output, 1289 bool GetOutputDeviceData(XID output,
1248 uint16* manufacturer_id, 1290 uint16* manufacturer_id,
1249 uint32* serial_number, 1291 uint32* serial_number,
1250 std::string* human_readable_name) { 1292 std::string* human_readable_name) {
1251 if (!IsRandRAvailable()) 1293 unsigned long nitems = 0;
1294 unsigned char *prop = NULL;
1295 if (!GetEDIDProperty(output, &nitems, prop))
sadrul 2013/01/03 19:08:32 This doesn't actually set the value of |prop|, doe
Jun Mukai 2013/01/03 21:37:37 aww, right. Fixed.
1252 return false; 1296 return false;
1253 1297
1254 static Atom edid_property = GetAtom(RR_PROPERTY_RANDR_EDID);
1255
1256 Display* display = GetXDisplay();
1257
1258 bool has_edid_property = false;
1259 int num_properties = 0;
1260 Atom* properties = XRRListOutputProperties(display, output, &num_properties);
1261 for (int i = 0; i < num_properties; ++i) {
1262 if (properties[i] == edid_property) {
1263 has_edid_property = true;
1264 break;
1265 }
1266 }
1267 XFree(properties);
1268 if (!has_edid_property)
1269 return false;
1270
1271 Atom actual_type;
1272 int actual_format;
1273 unsigned long nitems;
1274 unsigned long bytes_after;
1275 unsigned char *prop;
1276 XRRGetOutputProperty(display,
1277 output,
1278 edid_property,
1279 0, // offset
1280 128, // length
1281 false, // _delete
1282 false, // pending
1283 AnyPropertyType, // req_type
1284 &actual_type,
1285 &actual_format,
1286 &nitems,
1287 &bytes_after,
1288 &prop);
1289 DCHECK_EQ(XA_INTEGER, actual_type);
1290 DCHECK_EQ(8, actual_format);
1291
1292 // See http://en.wikipedia.org/wiki/Extended_display_identification_data 1298 // See http://en.wikipedia.org/wiki/Extended_display_identification_data
1293 // for the details of EDID data format. We use the following data: 1299 // for the details of EDID data format. We use the following data:
1294 // bytes 8-9: manufacturer EISA ID, in big-endian 1300 // bytes 8-9: manufacturer EISA ID, in big-endian
1295 // bytes 12-15: represents serial number, in little-endian 1301 // bytes 12-15: represents serial number, in little-endian
1296 // bytes 54-125: four descriptors (18-bytes each) which may contain 1302 // bytes 54-125: four descriptors (18-bytes each) which may contain
1297 // the display name. 1303 // the display name.
1298 const unsigned int kManufacturerOffset = 8; 1304 const unsigned int kManufacturerOffset = 8;
1299 const unsigned int kManufacturerLength = 2; 1305 const unsigned int kManufacturerLength = 2;
1300 const unsigned int kSerialNumberOffset = 12; 1306 const unsigned int kSerialNumberOffset = 12;
1301 const unsigned int kSerialNumberLength = 4; 1307 const unsigned int kSerialNumberLength = 4;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1365 char c = (*human_readable_name)[i]; 1371 char c = (*human_readable_name)[i];
1366 if (!isascii(c) || !isprint(c)) { 1372 if (!isascii(c) || !isprint(c)) {
1367 human_readable_name->clear(); 1373 human_readable_name->clear();
1368 return false; 1374 return false;
1369 } 1375 }
1370 } 1376 }
1371 1377
1372 return true; 1378 return true;
1373 } 1379 }
1374 1380
1381 bool GetOutputOverscanFlag(XID output) {
Daniel Erat 2013/01/03 19:04:19 since this code does a lot of tricky byte-reading,
Jun Mukai 2013/01/03 21:37:37 Added.
1382 unsigned long nitems = 0;
1383 unsigned char *prop = NULL;
1384 if (!GetEDIDProperty(output, &nitems, prop))
1385 return false;
1386
1387 const unsigned int kNumExtensionsOffset = 126;
1388 if (nitems < kNumExtensionsOffset) {
1389 XFree(prop);
1390 return false;
1391 }
1392
1393 // See http://en.wikipedia.org/wiki/Extended_display_identification_data
1394 // for the extension format of EDID. Also see
1395 // http://blogimg.chinaunix.net/blog/upfile2/090903185737.pdf pg.87-
1396 // for the format of the extensions and how video capability is encoded.
1397 // - byte 0: tag. should be 02h.
1398 // - byte 1: revision. only cares revision 3 (03h).
1399 // - byte 4-: data block.
1400 const unsigned int kExtensionBase = 128;
1401 const unsigned int kExtensionSize = 128;
1402 const unsigned int kDataBlockOffset = 4;
1403 const unsigned char kCEAExtensionTag = '\x02';
1404 const unsigned char kExpectedExtensionRevision = '\x03';
1405 const unsigned char kExtendedTag = 7;
1406 const unsigned char kExtendedVideoCapabilityTag = 0;
1407 const unsigned int kPTOverscan = 4;
1408 const unsigned int kITOverscan = 2;
1409 const unsigned int kCEOverscan = 0;
1410
1411 unsigned char num_extensions = prop[kNumExtensionsOffset];
1412 bool result = false;
1413 bool found = false;
1414
1415 for (size_t i = 0; i < num_extensions && !found; ++i) {
1416 unsigned char* extension = prop + kExtensionBase + i * kExtensionSize;
1417 unsigned char tag = extension[0];
1418 unsigned char revision = extension[1];
1419 if (tag != kCEAExtensionTag || revision != kExpectedExtensionRevision)
1420 continue;
1421
1422 unsigned char timing_descriptors_start = extension[2];
1423 unsigned char* data_block = extension + kDataBlockOffset;
1424 while (data_block < extension + timing_descriptors_start) {
1425 // a data block is encoded as:
1426 // - byte 1 high 3 bits: tag. '07' for extended tags.
1427 // - byte 1 remaining bits: the length of data block.
1428 // - byte 2: the extended tag. '0' for video capability.
1429 // - byte 3: the capability.
1430 unsigned char tag = data_block[0] >> 5;
1431 unsigned char payload_length = data_block[0] & 0x1f;
1432 if (tag != kExtendedTag && payload_length < 2) {
1433 data_block += payload_length + 1;
1434 continue;
1435 }
1436
1437 unsigned char extended_tag_code = data_block[1];
1438 // Here doesn't care the difference between preferred video format /
Daniel Erat 2013/01/03 19:04:19 nit: reword this to something like: // The differ
Jun Mukai 2013/01/03 21:37:37 Sorry, the comment location was wrong. Moved to th
1439 // IT video format / CE video format, since it just checks the
1440 // possibility.
1441 if (extended_tag_code != kExtendedVideoCapabilityTag) {
1442 data_block += payload_length;
1443 continue;
1444 }
1445
1446 found = true;
1447 if ((data_block[2] & (1 << kPTOverscan)) ||
1448 (data_block[2] & (1 << kITOverscan)) ||
1449 (data_block[2] & (1 << kCEOverscan))) {
1450 result = true;
1451 }
1452 break;
1453 }
1454 }
1455
1456 XFree(prop);
1457 return result;
1458 }
1459
1375 std::vector<std::string> GetDisplayNames(const std::vector<XID>& output_ids) { 1460 std::vector<std::string> GetDisplayNames(const std::vector<XID>& output_ids) {
1376 std::vector<std::string> names; 1461 std::vector<std::string> names;
1377 for (size_t i = 0; i < output_ids.size(); ++i) { 1462 for (size_t i = 0; i < output_ids.size(); ++i) {
1378 std::string display_name; 1463 std::string display_name;
1379 if (GetOutputDeviceData(output_ids[i], NULL, NULL, &display_name)) 1464 if (GetOutputDeviceData(output_ids[i], NULL, NULL, &display_name))
1380 names.push_back(display_name); 1465 names.push_back(display_name);
1381 } 1466 }
1382 return names; 1467 return names;
1383 } 1468 }
1384 1469
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1721 << "request_code " << static_cast<int>(error_event.request_code) << ", " 1806 << "request_code " << static_cast<int>(error_event.request_code) << ", "
1722 << "minor_code " << static_cast<int>(error_event.minor_code) 1807 << "minor_code " << static_cast<int>(error_event.minor_code)
1723 << " (" << request_str << ")"; 1808 << " (" << request_str << ")";
1724 } 1809 }
1725 1810
1726 // ---------------------------------------------------------------------------- 1811 // ----------------------------------------------------------------------------
1727 // End of x11_util_internal.h 1812 // End of x11_util_internal.h
1728 1813
1729 1814
1730 } // namespace ui 1815 } // namespace ui
OLDNEW
« ui/base/x/x11_util.h ('K') | « ui/base/x/x11_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698