Index: chromeos/display/real_output_configurator_delegate.cc |
diff --git a/chromeos/display/real_output_configurator_delegate.cc b/chromeos/display/real_output_configurator_delegate.cc |
index fd7d7b003090596ef1570f64add2a2df0755d12b..5bb4757e3b7b2288037f78d802230c4874126350 100644 |
--- a/chromeos/display/real_output_configurator_delegate.cc |
+++ b/chromeos/display/real_output_configurator_delegate.cc |
@@ -18,6 +18,7 @@ |
#include "base/logging.h" |
#include "base/message_loop/message_pump_x11.h" |
#include "base/x11/edid_parser_x11.h" |
+#include "base/x11/x11_error_tracker.h" |
#include "chromeos/dbus/dbus_thread_manager.h" |
#include "chromeos/dbus/power_manager_client.h" |
#include "chromeos/display/output_util.h" |
@@ -31,6 +32,17 @@ const float kMmInInch = 25.4; |
const float kDpi96 = 96.0; |
const float kPixelsToMmScale = kMmInInch / kDpi96; |
+// Prefixes of output name |
+const char kOutputName_VGA[] = "VGA"; |
+const char kOutputName_HDMI[] = "HDMI"; |
+const char kOutputName_DVI[] = "DVI"; |
+const char kOutputName_DisplayPort[] = "DP"; |
+ |
+const char kContentProtectionAtomName[] = "Content Protection"; |
+const char kProtectionUndesiredAtomName[] = "Undesired"; |
+const char kProtectionDesiredAtomName[] = "Desired"; |
+const char kProtectionEnabledAtomName[] = "Enabled"; |
+ |
bool IsInternalOutput(const XRROutputInfo* output_info) { |
return IsInternalOutputName(std::string(output_info->name)); |
} |
@@ -304,9 +316,101 @@ RealOutputConfiguratorDelegate::InitOutputSnapshot( |
LOG(WARNING) << "Unable to find XRRModeInfo for mode " << mode; |
} |
+ std::string name(info->name); |
+ if (output.is_internal) { |
+ output.type = OUTPUT_TYPE_INTERNAL; |
+ } else if (name.find(kOutputName_VGA) == 0) { |
+ output.type = OUTPUT_TYPE_VGA; |
+ } else if (name.find(kOutputName_HDMI) == 0) { |
+ output.type = OUTPUT_TYPE_HDMI; |
+ } else if (name.find(kOutputName_DVI) == 0) { |
+ output.type = OUTPUT_TYPE_DVI; |
+ } else if (name.find(kOutputName_DisplayPort) == 0) { |
+ output.type = OUTPUT_TYPE_DISPLAYPORT; |
+ } else { |
+ LOG(ERROR) << "Unknown link type: " << name; |
+ output.type = OUTPUT_TYPE_UNKNOWN; |
+ } |
+ |
return output; |
} |
+bool RealOutputConfiguratorDelegate::GetHDCPState(RROutput id, |
+ HDCPState* state) { |
+ unsigned char* values = NULL; |
+ int actual_format = 0; |
+ unsigned long nitems = 0; |
+ unsigned long bytes_after = 0; |
+ Atom actual_type = None; |
+ int success = 0; |
+ // TODO(kcwu): Use X11AtomCache to save round trip time of XInternAtom. |
+ Atom prop = XInternAtom(display_, kContentProtectionAtomName, False); |
+ |
+ bool ok = true; |
+ // TODO(kcwu): Move this to x11_util (similar method calls in this file and |
+ // output_util.cc) |
+ success = XRRGetOutputProperty(display_, id, prop, 0, 100, False, |
+ False, AnyPropertyType, &actual_type, |
+ &actual_format, &nitems, &bytes_after, |
+ &values); |
+ if (actual_type == None) { |
+ LOG(ERROR) << "Property '" << kContentProtectionAtomName |
+ << "' does not exist"; |
+ ok = false; |
+ } else if (success == Success && actual_type == XA_ATOM && |
+ actual_format == 32 && nitems == 1) { |
+ Atom value = reinterpret_cast<Atom*>(values)[0]; |
+ if (value == XInternAtom(display_, kProtectionUndesiredAtomName, False)) { |
+ *state = HDCP_STATE_UNDESIRED; |
+ } else if (value == XInternAtom(display_, kProtectionDesiredAtomName, |
+ False)) { |
+ *state = HDCP_STATE_DESIRED; |
+ } else if (value == XInternAtom(display_, kProtectionEnabledAtomName, |
+ False)) { |
+ *state = HDCP_STATE_ENABLED; |
+ } else { |
+ LOG(ERROR) << "Unknown " << kContentProtectionAtomName << " value: " |
+ << value; |
+ ok = false; |
+ } |
+ } else { |
+ LOG(ERROR) << "XRRGetOutputProperty failed"; |
+ ok = false; |
+ } |
+ if (values) |
+ XFree(values); |
+ |
+ VLOG(3) << "HDCP state: " << ok << "," << *state; |
+ return ok; |
+} |
+ |
+bool RealOutputConfiguratorDelegate::SetHDCPState(RROutput id, |
+ HDCPState state) { |
+ Atom name = XInternAtom(display_, kContentProtectionAtomName, False); |
+ Atom value = None; |
+ switch (state) { |
+ case HDCP_STATE_UNDESIRED: |
+ value = XInternAtom(display_, kProtectionUndesiredAtomName, False); |
+ break; |
+ case HDCP_STATE_DESIRED: |
+ value = XInternAtom(display_, kProtectionDesiredAtomName, False); |
+ break; |
+ default: |
+ NOTREACHED() << "Invalid HDCP state: " << state; |
+ return false; |
+ } |
+ base::X11ErrorTracker err_tracker; |
+ unsigned char* data = reinterpret_cast<unsigned char*>(&value); |
+ XRRChangeOutputProperty(display_, id, name, XA_ATOM, 32, |
+ PropModeReplace, data, 1); |
+ if (err_tracker.FoundNewError()) { |
+ LOG(ERROR) << "XRRChangeOutputProperty failed"; |
+ return false; |
+ } else { |
+ return true; |
+ } |
+} |
+ |
void RealOutputConfiguratorDelegate::DestroyUnusedCrtcs( |
const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { |
CHECK(screen_) << "Server not grabbed"; |