Created
June 20, 2017 10:16
-
-
Save sigmaris/03ab16e6bbd52c77b42326ce70b64afc to your computer and use it in GitHub Desktop.
Hack for setting gamma curves using linux KMS API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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