summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-04-18 11:52:51 +0200
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-04-18 11:58:52 +0200
commit6974c0c3a00912185c58237f8ec2f7a822629929 (patch)
tree841caf633303c0515f2b896b1ce5123b48589ee3
parent962fac0c9f51464c97d742c10d753c44fc6a6318 (diff)
wfdport: Support display data formats
-rw-r--r--src/wfdapi.c47
-rw-r--r--src/wfdport.c65
-rw-r--r--src/wfdport.h11
3 files changed, 112 insertions, 11 deletions
diff --git a/src/wfdapi.c b/src/wfdapi.c
index 75fd1c6..6c1ffae 100644
--- a/src/wfdapi.c
+++ b/src/wfdapi.c
@@ -751,23 +751,52 @@ wfdBindPipelineToPort(WFDDevice device_handle,
}
WFD_API_CALL WFDint WFD_APIENTRY
-wfdGetDisplayDataFormats(WFDDevice device,
- WFDPort port,
+wfdGetDisplayDataFormats(WFDDevice device_handle,
+ WFDPort port_handle,
WFDDisplayDataFormat *format,
- WFDint formatCount) WFD_APIEXIT
+ WFDint format_count) WFD_APIEXIT
{
- return 0;
-}
+ struct wfd_device *device;
+ struct wfd_port *port;
+ device = wf_handle_get_object(device_handle, DEVICE_HANDLE);
+ if (device == NULL)
+ return 0;
+ wfd_device_set_error(device, WFD_ERROR_NONE);
+
+ port = wf_handle_get_object(port_handle, PORT_HANDLE);
+ if (port == NULL) {
+ wfd_device_set_error(device, WFD_ERROR_BAD_HANDLE);
+ return 0;
+ }
+
+ return wfd_port_get_display_data_formats(device, port,
+ format, format_count);
+}
WFD_API_CALL WFDint WFD_APIENTRY
-wfdGetDisplayData(WFDDevice device,
- WFDPort port,
+wfdGetDisplayData(WFDDevice device_handle,
+ WFDPort port_handle,
WFDDisplayDataFormat format,
WFDuint8 *data,
- WFDint dataCount) WFD_APIEXIT
+ WFDint data_count) WFD_APIEXIT
{
- return 0;
+ struct wfd_device *device;
+ struct wfd_port *port;
+
+ device = wf_handle_get_object(device_handle, DEVICE_HANDLE);
+ if (device == NULL)
+ return 0;
+ wfd_device_set_error(device, WFD_ERROR_NONE);
+
+ port = wf_handle_get_object(port_handle, PORT_HANDLE);
+ if (port == NULL) {
+ wfd_device_set_error(device, WFD_ERROR_BAD_HANDLE);
+ return 0;
+ }
+
+ return wfd_port_get_display_data(device, port, format,
+ data, data_count);
}
/* ============================================================================= */
diff --git a/src/wfdport.c b/src/wfdport.c
index 9222d27..c65ed1d 100644
--- a/src/wfdport.c
+++ b/src/wfdport.c
@@ -50,6 +50,8 @@ struct wfd_port {
uint32_t dpms_enum_id;
WFDint power_mode;
+
+ uint32_t edid_enum_id;
};
WFDint
@@ -169,6 +171,7 @@ wfd_port_create(struct wfd_device *device,
drmModeFreeEncoder(encoder);
}
+ port->edid_enum_id = 0;
port->dpms_enum_id = 0;
for (i = 0; i < port->connector->count_props; ++i) {
prop = drmModeGetProperty(drm_fd, port->connector->props[i]);
@@ -178,8 +181,9 @@ wfd_port_create(struct wfd_device *device,
if (prop->flags && DRM_MODE_PROP_ENUM &&
strcmp(prop->name, "DPMS") == 0) {
port->dpms_enum_id = port->connector->props[i];
- drmModeFreeProperty(prop);
- break;
+ } else if (prop->flags && DRM_MODE_PROP_BLOB &&
+ strcmp(prop->name, "EDID") == 0) {
+ port->edid_enum_id = port->connector->props[i];
}
drmModeFreeProperty(prop);
@@ -496,6 +500,63 @@ wfd_port_mode_get_attribi(struct wfd_device *device,
}
int
+wfd_port_get_display_data_formats(struct wfd_device *device,
+ struct wfd_port *port,
+ WFDDisplayDataFormat *format,
+ WFDint format_count)
+{
+ if (format == NULL)
+ return 1;
+
+ if (format_count >= 1 && port->edid_enum_id != 0) {
+ format[0] = WFD_DISPLAY_DATA_FORMAT_EDID_V1;
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+wfd_port_get_display_data(struct wfd_device *device,
+ struct wfd_port *port,
+ WFDDisplayDataFormat format,
+ WFDuint8 *data, WFDint data_count)
+{
+ int fd = wfd_device_get_fd(device);
+ drmModePropertyBlobPtr edid_blob;
+ int num;
+
+ if (port->edid_enum_id == 0) {
+ wfd_device_set_error(device, WFD_ERROR_ILLEGAL_ARGUMENT);
+ return 0;
+ }
+
+ switch (format) {
+ case WFD_DISPLAY_DATA_FORMAT_EDID_V1:
+ break;
+ case WFD_DISPLAY_DATA_FORMAT_EDID_V2:
+ case WFD_DISPLAY_DATA_FORMAT_DISPLAYID:
+ default:
+ wfd_device_set_error(device, WFD_ERROR_ILLEGAL_ARGUMENT);
+ return 0;
+ }
+
+ edid_blob = drmModeGetPropertyBlob(fd, port->edid_enum_id);
+
+ num = edid_blob->length;
+
+ if (data != NULL) {
+ if (data_count < num)
+ num = data_count;
+ memcpy(data, edid_blob->data, num);
+ }
+
+ drmModeFreePropertyBlob(edid_blob);
+
+ return num;
+}
+
+int
wfd_port_commit(struct wfd_device *device,
struct wfd_port *port)
{
diff --git a/src/wfdport.h b/src/wfdport.h
index 1aac67d..6e488f0 100644
--- a/src/wfdport.h
+++ b/src/wfdport.h
@@ -95,6 +95,17 @@ wfd_port_mode_get_attribi(struct wfd_device *device,
WFDPortModeAttrib attrib);
int
+wfd_port_get_display_data_formats(struct wfd_device *device,
+ struct wfd_port *port,
+ WFDDisplayDataFormat *format,
+ WFDint format_count);
+int
+wfd_port_get_display_data(struct wfd_device *device,
+ struct wfd_port *port,
+ WFDDisplayDataFormat format,
+ WFDuint8 *data, WFDint data_count);
+
+int
wfd_port_bind_pipeline(struct wfd_device *device,
struct wfd_port *port,
struct wfd_pipeline *pipeline);