summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-04-18 14:33:24 +0200
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-04-20 17:52:43 +0200
commit540e39248d3818fd41204072d55c1fdd3b49c546 (patch)
treebd8ab6e1f17626d249331ddebb657b8d63860f46
parentf59bf5441af713327418118dc537103804a681f7 (diff)
wfdport: Support WFD_PORT_GAMMA
-rw-r--r--src/Makefile.am2
-rw-r--r--src/wfdapi.c39
-rw-r--r--src/wfdport.c89
-rw-r--r--src/wfdport.h9
4 files changed, 133 insertions, 6 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6c89155..0a9e36f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,7 +10,7 @@ noinst_HEADERS = \
wfdevent.h
-libWFD_la_LIBADD = $(OWFDRM_LIBS)
+libWFD_la_LIBADD = $(OWFDRM_LIBS) -lm
libWFD_la_SOURCES = \
wfdapi.c \
wfhandle.c \
diff --git a/src/wfdapi.c b/src/wfdapi.c
index 5479310..d565b15 100644
--- a/src/wfdapi.c
+++ b/src/wfdapi.c
@@ -589,11 +589,25 @@ wfdGetPortAttribi(WFDDevice device_handle,
}
WFD_API_CALL WFDfloat WFD_APIENTRY
-wfdGetPortAttribf(WFDDevice device,
- WFDPort port,
+wfdGetPortAttribf(WFDDevice device_handle,
+ WFDPort port_handle,
WFDPortConfigAttrib attrib) 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_attribf(device, port, attrib);
}
@@ -682,11 +696,26 @@ wfdSetPortAttribi(WFDDevice device_handle,
WFD_API_CALL void WFD_APIENTRY
-wfdSetPortAttribf(WFDDevice device,
- WFDPort port,
+wfdSetPortAttribf(WFDDevice device_handle,
+ WFDPort port_handle,
WFDPortConfigAttrib attrib,
WFDfloat value) WFD_APIEXIT
{
+ struct wfd_device *device;
+ struct wfd_port *port;
+
+ device = wf_handle_get_object(device_handle, DEVICE_HANDLE);
+ if (device == NULL)
+ return;
+ 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;
+ }
+
+ wfd_port_set_attribf(device, port, attrib, value);
}
diff --git a/src/wfdport.c b/src/wfdport.c
index c94a32c..d95dbcb 100644
--- a/src/wfdport.c
+++ b/src/wfdport.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
+#include <math.h>
#include "wfhandle.h"
#include "wfdport.h"
@@ -54,6 +55,9 @@ struct wfd_port {
WFDint power_mode;
uint32_t edid_enum_id;
+
+ float gamma;
+ float gamma_range[2];
};
WFDint
@@ -193,6 +197,9 @@ wfd_port_create(struct wfd_device *device,
port->mode = NULL;
port->mode_handle = WFD_INVALID_HANDLE;
+ port->gamma = 1.0;
+ port->gamma_range[0] = 0.1;
+ port->gamma_range[1] = 10.0;
return port;
}
@@ -304,6 +311,22 @@ wfd_port_get_attribi(struct wfd_device *device,
return 0;
}
+WFDfloat
+wfd_port_get_attribf(struct wfd_device *device,
+ struct wfd_port *port,
+ WFDPortConfigAttrib attribute)
+{
+ switch (attribute) {
+ case WFD_PORT_GAMMA:
+ return port->gamma;
+ default:
+ wfd_device_set_error(device, WFD_ERROR_BAD_ATTRIBUTE);
+ break;
+ }
+
+ return 0.0;
+}
+
static void
wfd_port_get_bindable_pipelines(struct wfd_device *device,
struct wfd_port *port,
@@ -382,6 +405,11 @@ wfd_port_get_attribfv(struct wfd_device *device,
return;
value[0] = value[1] = value[2] = 0.0;
break;
+ case WFD_PORT_GAMMA_RANGE:
+ if (count != 2)
+ return;
+ value[0] = port->gamma_range[0];
+ value[1] = port->gamma_range[1];
default:
wfd_device_set_error(device, WFD_ERROR_BAD_ATTRIBUTE);
break;
@@ -431,6 +459,28 @@ wfd_port_set_attribi(struct wfd_device *device,
}
void
+wfd_port_set_attribf(struct wfd_device *device,
+ struct wfd_port *port,
+ WFDPortConfigAttrib attribute,
+ WFDfloat value)
+{
+ switch (attribute) {
+ case WFD_PORT_GAMMA:
+ if (value < port->gamma_range[0] ||
+ value > port->gamma_range[1]) {
+ wfd_device_set_error(device,
+ WFD_ERROR_ILLEGAL_ARGUMENT);
+ return;
+ }
+
+ port->gamma = value;
+ default:
+ wfd_device_set_error(device, WFD_ERROR_BAD_ATTRIBUTE);
+ break;
+ }
+}
+
+void
wfd_port_set_attribiv(struct wfd_device *device,
struct wfd_port *port,
WFDPortConfigAttrib attribute,
@@ -632,6 +682,43 @@ wfd_port_get_display_data(struct wfd_device *device,
return num;
}
+static inline double
+dmin(double a, double b)
+{
+ return a < b ? a : b;
+}
+
+static void
+wfd_port_commit_gamma(struct wfd_device *device,
+ struct wfd_port *port)
+{
+ int fd = wfd_device_get_fd(device);
+ uint16_t *gamma;
+ uint16_t *red, *green, *blue;
+ int i, size = 256;
+
+ gamma = malloc(3 * size * sizeof *gamma);
+ if (gamma == NULL)
+ return;
+
+ for (i = 0; i < size; ++i) {
+ if (port->gamma == 1.0) {
+ gamma[i] = (i << 8) + i;
+ continue;
+ }
+
+ gamma[i] = dmin(pow((double)i/(double)(size-1), port->gamma),
+ 1.0) * 65535.0;
+ }
+
+ red = green = blue = gamma;
+
+ drmModeCrtcSetGamma(fd, port->connector->connector_id,
+ size, red, green, blue);
+ free(gamma);
+}
+
+
int
wfd_port_commit(struct wfd_device *device,
struct wfd_port *port)
@@ -688,6 +775,8 @@ wfd_port_commit(struct wfd_device *device,
return ret;
}
+ wfd_port_commit_gamma(device, port);
+
return ret;
}
diff --git a/src/wfdport.h b/src/wfdport.h
index eaaedc9..28a24b1 100644
--- a/src/wfdport.h
+++ b/src/wfdport.h
@@ -48,6 +48,10 @@ WFDint
wfd_port_get_attribi(struct wfd_device *device,
struct wfd_port *port,
WFDPortConfigAttrib attribute);
+WFDfloat
+wfd_port_get_attribf(struct wfd_device *device,
+ struct wfd_port *port,
+ WFDPortConfigAttrib attribute);
void
wfd_port_get_attribiv(struct wfd_device *device,
struct wfd_port *port,
@@ -67,6 +71,11 @@ wfd_port_set_attribi(struct wfd_device *device,
WFDPortConfigAttrib attribute,
WFDint value);
void
+wfd_port_set_attribf(struct wfd_device *device,
+ struct wfd_port *port,
+ WFDPortConfigAttrib attribute,
+ WFDfloat value);
+void
wfd_port_set_attribiv(struct wfd_device *device,
struct wfd_port *port,
WFDPortConfigAttrib attribute,