aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/drmgamma.c54
-rw-r--r--src/drmgamma.h40
2 files changed, 92 insertions, 2 deletions
diff --git a/src/drmgamma.c b/src/drmgamma.c
index 16a3006..e0dcbfb 100644
--- a/src/drmgamma.c
+++ b/src/drmgamma.c
@@ -162,9 +162,14 @@ int drm_crtc_open(size_t index, drm_card_t* restrict card, drm_crtc_t* restrict
{
drmModePropertyRes* restrict prop;
drmModePropertyBlobRes* restrict blob;
+ drmModeCrtc* restrict info;
size_t i;
+ int old_errno;
- crtc->edid = NULL;
+ crtc->edid = NULL;
+ crtc->red = NULL;
+ crtc->green = NULL;
+ crtc->blue = NULL;
crtc->id = card->res->crtcs[index];
crtc->card = card;
@@ -179,6 +184,19 @@ int drm_crtc_open(size_t index, drm_card_t* restrict card, drm_crtc_t* restrict
crtc->connected = crtc->connector->connection == DRM_MODE_CONNECTED;
+ info = drmModeGetCrtc(card->fd, crtc->id);
+ if (info == NULL)
+ return -1;
+ crtc->gamma_stops = (size_t)(info->gamma_size);
+ drmModeFreeCrtc(info);
+
+ /* `calloc` is for some reason required when reading the gamma ramps. */
+ crtc->red = calloc(3 * crtc->gamma_stops, sizeof(uint16_t));
+ if (crtc->red == NULL)
+ return -1;
+ crtc->green = crtc->red + crtc->gamma_stops;
+ crtc->blue = crtc->green + crtc->gamma_stops;
+
for (i = 0; i < crtc->connector->count_props; i++)
{
size_t j;
@@ -199,8 +217,11 @@ int drm_crtc_open(size_t index, drm_card_t* restrict card, drm_crtc_t* restrict
crtc->edid = malloc((blob->length * 2 + 1) * sizeof(char));
if (crtc->edid == NULL)
{
+ old_errno = errno;
drmModeFreePropertyBlob(blob);
drmModeFreeProperty(prop);
+ free(crtc->red), crtc->red = NULL;
+ errno = old_errno;
return -1;
}
for (j = 0; j < blob->length; j++)
@@ -231,5 +252,36 @@ int drm_crtc_open(size_t index, drm_card_t* restrict card, drm_crtc_t* restrict
void drm_crtc_close(drm_crtc_t* restrict crtc)
{
free(crtc->edid), crtc->edid = NULL;
+ free(crtc->red), crtc->red = NULL;
+}
+
+
+/**
+ * Read the gamma ramps for a CRT controller
+ *
+ * @param crtc CRT controller information
+ * @return Zero on success, -1 on error
+ */
+int drm_get_gamma(drm_crtc_t* restrict crtc)
+{
+ int r;
+ r = drmModeCrtcGetGamma(crtc->card->fd, crtc->id, crtc->gamma_stops,
+ crtc->red, crtc->green, crtc->blue);
+ return -!!r;
+}
+
+
+/**
+ * Apply gamma ramps for a CRT controller
+ *
+ * @param crtc CRT controller information
+ * @return Zero on success, -1 on error
+ */
+int drm_set_gamma(drm_crtc_t* restrict crtc)
+{
+ int r;
+ r = drmModeCrtcSetGamma(crtc->card->fd, crtc->id, crtc->gamma_stops,
+ crtc->red, crtc->green, crtc->blue);
+ return -!!r;
}
diff --git a/src/drmgamma.h b/src/drmgamma.h
index efc7ec2..e82159d 100644
--- a/src/drmgamma.h
+++ b/src/drmgamma.h
@@ -61,6 +61,7 @@ typedef struct drm_card
} drm_card_t;
+
/**
* CRT controller information
*/
@@ -94,11 +95,32 @@ typedef struct drm_crtc
/**
* The CRT's EDID, hexadecimally encoded
*/
- char* edid;
+ char* restrict edid;
+
+ /**
+ * The number of stops on the gamma ramps
+ */
+ size_t gamma_stops;
+
+ /**
+ * The gamma ramp for the red channel
+ */
+ uint16_t* restrict red;
+
+ /**
+ * The gamma ramp for the green channel
+ */
+ uint16_t* restrict green;
+
+ /**
+ * The gamma ramp for the blue channel
+ */
+ uint16_t* restrict blue;
} drm_crtc_t;
+
/**
* Figure out how many graphics cards there are on the system
*
@@ -139,6 +161,22 @@ int drm_crtc_open(size_t index, drm_card_t* restrict card, drm_crtc_t* restrict
*/
void drm_crtc_close(drm_crtc_t* restrict crtc);
+/**
+ * Read the gamma ramps for a CRT controller
+ *
+ * @param crtc CRT controller information
+ * @return Zero on success, -1 on error
+ */
+int drm_get_gamma(drm_crtc_t* restrict crtc);
+
+/**
+ * Apply gamma ramps for a CRT controller
+ *
+ * @param crtc CRT controller information
+ * @return Zero on success, -1 on error
+ */
+int drm_set_gamma(drm_crtc_t* restrict crtc);
+
#endif