Skip to content

Instantly share code, notes, and snippets.

@sigmaris
Created June 20, 2017 10:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sigmaris/03ab16e6bbd52c77b42326ce70b64afc to your computer and use it in GitHub Desktop.
Save sigmaris/03ab16e6bbd52c77b42326ce70b64afc to your computer and use it in GitHub Desktop.
Hack for setting gamma curves using linux KMS API
LIBDRM_CFLAGS := $(shell pkg-config --cflags libdrm)
LIBDRM_LIBS := $(shell pkg-config --libs libdrm)
.PHONY = all clean
all: setgamma
clean:
rm setgamma *.o
setgamma.o: setgamma.c
gcc -c -o setgamma.o ${LIBDRM_CFLAGS} setgamma.c
setgamma: setgamma.o
gcc -o setgamma ${LIBDRM_LIBS} setgamma.o
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#define MAXBRIGHT 65535
int main(int argc, char** argv) {
int ret;
unsigned int i, v, bright;
int fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
uint32_t saved_conn_id, encoder_id;
drmModeRes *resources = NULL;
drmModeConnector *connector = NULL;
drmModeEncoder *encoder = NULL;
drmModeCrtc *crtc = NULL;
if (argc != 2) {
printf("Usage: %s <brightness 0-%d>\n", argv[0], MAXBRIGHT);
ret = 1;
goto cleanup;
}
if (sscanf(argv[1], "%u", &bright) != 1) {
printf("Error - argument not an integer\n");
ret = 1;
goto cleanup;
}
if (bright > MAXBRIGHT) {
printf("Error - brightness must be 0-%d\n", MAXBRIGHT);
ret = 1;
goto cleanup;
}
/* Find the first available connector with modes */
resources = drmModeGetResources(fd);
if (!resources) {
printf("drmModeGetResources(%d) failed\n", fd);
goto cleanup;
}
for (i = 0; i < resources->count_connectors; i++) {
connector = drmModeGetConnector(fd, resources->connectors[i]);
if (connector == NULL)
continue;
if (connector->connection == DRM_MODE_CONNECTED &&
connector->count_modes > 0) {
printf("Found connector %d with %d modes.\n",
connector->connector_id, connector->count_modes);
saved_conn_id = connector->connector_id;
break;
}
drmModeFreeConnector(connector);
}
if (i == resources->count_connectors) {
printf("No currently active connector found.\n");
goto cleanup;
}
for (i = 0; i < resources->count_encoders; i++) {
encoder = drmModeGetEncoder(fd, resources->encoders[i]);
if (encoder == NULL)
continue;
if (encoder->encoder_id == connector->encoder_id) {
printf("Found encoder %d.\n", encoder->encoder_id);
encoder_id = encoder->encoder_id;
break;
}
drmModeFreeEncoder(encoder);
}
if (i == resources->count_encoders) {
printf("No connected encoder found.\n");
goto cleanup;
}
crtc = drmModeGetCrtc(fd, encoder->crtc_id);
if (crtc == NULL) {
printf("No CRTC found for encoder.\n");
goto cleanup;
}
printf("Found connector ID %d, encoder ID %d, CRTC ID %d.\n", saved_conn_id, encoder_id, encoder->crtc_id);
printf("Gamma size: %d\n", crtc->gamma_size);
uint16_t *red = malloc(sizeof(uint16_t) * crtc->gamma_size);
uint16_t *green = malloc(sizeof(uint16_t) * crtc->gamma_size);
uint16_t *blue = malloc(sizeof(uint16_t) * crtc->gamma_size);
ret = drmModeCrtcGetGamma(fd, encoder->crtc_id, crtc->gamma_size, red, green, blue);
if(ret < 0) {
printf("Error getting gamma: %d\n", ret);
goto cleanup;
}
printf("Previous table:\n");
for (i = 0; i < crtc->gamma_size; i++) {
printf("%5d,%5d,%5d\n", red[i], green[i], blue[i]);
}
for (i = 0; i < crtc->gamma_size; i++) {
v = (i * bright) / (crtc->gamma_size - 1);
red[i] = green[i] = blue[i] = v;
}
ret = drmModeCrtcSetGamma(fd, encoder->crtc_id, crtc->gamma_size, red, green, blue);
if (ret < 0) {
printf("error setting gamma: %d\n", ret);
goto cleanup;
}
printf("Current table\n");
for (i = 0; i < crtc->gamma_size; i++) {
printf("%5d,%5d,%5d\n", red[i], green[i], blue[i]);
}
cleanup:
close(fd);
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment