diff options
Diffstat (limited to 'src/gamma-drm.c')
-rw-r--r-- | src/gamma-drm.c | 256 |
1 files changed, 10 insertions, 246 deletions
diff --git a/src/gamma-drm.c b/src/gamma-drm.c index 1713024..f5aef31 100644 --- a/src/gamma-drm.c +++ b/src/gamma-drm.c @@ -19,196 +19,11 @@ */ #include "common.h" -#include <xf86drm.h> -#include <xf86drmMode.h> - -#ifndef O_CLOEXEC -# define O_CLOEXEC 02000000 -#endif - - -struct drm_crtc_state { - int crtc_num; - int crtc_id; - int gamma_size; - uint16_t *r_gamma; - uint16_t *g_gamma; - uint16_t *b_gamma; -}; - - -struct gamma_state { - int card_num; - int crtc_num; - int fd; - drmModeRes *res; - struct drm_crtc_state *crtcs; -}; - static int drm_create(struct gamma_state **state_out) { - struct gamma_state *state; - state = *state_out = emalloc(sizeof(**state_out)); - state->card_num = 0; - state->crtc_num = -1; - state->fd = -1; - state->res = NULL; - state->crtcs = NULL; - return 0; -} - - -static int -drm_start(struct gamma_state *state) -{ - /* Acquire access to a graphics card. */ - char pathname[sizeof(DRM_DIR_NAME"")-1U + sizeof(DRM_DEV_NAME"")-1U + 3U * sizeof(int) + 2U]; - int crtc_count; - struct drm_crtc_state *crtcs; - - sprintf(pathname, DRM_DEV_NAME, DRM_DIR_NAME, state->card_num); - - state->fd = open(pathname, O_RDWR | O_CLOEXEC); - if (state->fd < 0) { - /* TODO check if access permissions, normally root or membership of the video group is required. */ - weprintf(_("Failed to open DRM device `%s': %s."), pathname, strerror(errno)); - return -1; - } - - /* Acquire mode resources. */ - state->res = drmModeGetResources(state->fd); - if (state->res == NULL) { - weprintf(_("Failed to get DRM mode resources.")); - close(state->fd); - state->fd = -1; - return -1; - } - - /* Create entries for selected CRTCs. */ - crtc_count = state->res->count_crtcs; - if (state->crtc_num >= 0) { - if (state->crtc_num >= crtc_count) { - if (crtc_count > 1) - weprintf(_("CRTC %i does not exist, valid CRTCs are [0, %i]."), state->crtc_num, crtc_count-1); - else - weprintf(_("CRTC %i does not exist, only CRTC 0 exists."), state->crtc_num); - close(state->fd); - state->fd = -1; - drmModeFreeResources(state->res); - state->res = NULL; - return -1; - } - - state->crtcs = malloc(2 * sizeof(struct drm_crtc_state)); - state->crtcs[1].crtc_num = -1; - - state->crtcs->crtc_num = state->crtc_num; - state->crtcs->crtc_id = -1; - state->crtcs->gamma_size = -1; - state->crtcs->r_gamma = NULL; - state->crtcs->g_gamma = NULL; - state->crtcs->b_gamma = NULL; - } else { - int crtc_num; - state->crtcs = malloc((crtc_count + 1) * sizeof(struct drm_crtc_state)); - state->crtcs[crtc_count].crtc_num = -1; - for (crtc_num = 0; crtc_num < crtc_count; crtc_num++) { - state->crtcs[crtc_num].crtc_num = crtc_num; - state->crtcs[crtc_num].crtc_id = -1; - state->crtcs[crtc_num].gamma_size = -1; - state->crtcs[crtc_num].r_gamma = NULL; - state->crtcs[crtc_num].g_gamma = NULL; - state->crtcs[crtc_num].b_gamma = NULL; - } - } - - /* Load CRTC information and gamma ramps. */ - crtcs = state->crtcs; - for (; crtcs->crtc_num >= 0; crtcs++) { - drmModeCrtc *crtc_info; - crtcs->crtc_id = state->res->crtcs[crtcs->crtc_num]; - crtc_info = drmModeGetCrtc(state->fd, crtcs->crtc_id); - if (crtc_info == NULL) { - weprintf(_("CRTC %i lost, skipping"), crtcs->crtc_num); - continue; - } - crtcs->gamma_size = crtc_info->gamma_size; - drmModeFreeCrtc(crtc_info); - if (crtcs->gamma_size <= 1) { - weprintf(_("Could not get gamma ramp size for CRTC %i on graphics card" - " %i, ignoring device."), crtcs->crtc_num, state->card_num); - continue; - } - /* Valgrind complains about us reading uninitialize memory if we just use malloc. */ - crtcs->r_gamma = calloc(3 * crtcs->gamma_size, sizeof(uint16_t)); - crtcs->g_gamma = crtcs->r_gamma + crtcs->gamma_size; - crtcs->b_gamma = crtcs->g_gamma + crtcs->gamma_size; - if (crtcs->r_gamma) { - int r = drmModeCrtcGetGamma(state->fd, crtcs->crtc_id, crtcs->gamma_size, - crtcs->r_gamma, crtcs->g_gamma, crtcs->b_gamma); - if (r < 0) { - weprintf(_("DRM could not read gamma ramps on CRTC %i on graphics card" - " %i, ignoring device."), crtcs->crtc_num, state->card_num); - free(crtcs->r_gamma); - crtcs->r_gamma = NULL; - } - } else { - weprintf("malloc:"); - drmModeFreeResources(state->res); - state->res = NULL; - close(state->fd); - state->fd = -1; - while (crtcs-- != state->crtcs) - free(crtcs->r_gamma); - free(state->crtcs); - state->crtcs = NULL; - return -1; - } - } - - return 0; -} - - -static void -drm_restore(struct gamma_state *state) -{ - struct drm_crtc_state *crtcs = state->crtcs; - while (crtcs->crtc_num >= 0) { - if (crtcs->r_gamma) { - drmModeCrtcSetGamma(state->fd, crtcs->crtc_id, crtcs->gamma_size, - crtcs->r_gamma, crtcs->g_gamma, crtcs->b_gamma); - } - crtcs++; - } -} - - -static void -drm_free(struct gamma_state *state) -{ - if (state->crtcs) { - struct drm_crtc_state *crtcs = state->crtcs; - while (crtcs->crtc_num >= 0) { - free(crtcs->r_gamma); - crtcs->crtc_num = -1; - crtcs++; - } - free(state->crtcs); - state->crtcs = NULL; - } - if (state->res) { - drmModeFreeResources(state->res); - state->res = NULL; - } - if (state->fd >= 0) { - close(state->fd); - state->fd = -1; - } - - free(state); + return direct_create(state_out, LIBGAMMA_METHOD_LINUX_DRM, "drm"); } @@ -218,10 +33,9 @@ drm_print_help(FILE *f) fputs(_("Adjust gamma ramps with Direct Rendering Manager.\n"), f); fputs("\n", f); - /* TRANSLATORS: DRM help output - left column must not be translated */ - fputs(_(" card=N\tGraphics card to apply adjustments to\n" - " crtc=N\tCRTC to apply adjustments to\n"), f); /* TODO list is not supported */ + /* TRANSLATORS: DRM help output left column must not be translated */ + fputs(_(" card=N Graphics card to apply adjustments to\n"), f); + fputs(_(" crtc=N List of comma-separated CRTCs to apply adjustments to\n"), f); fputs("\n", f); } @@ -230,68 +44,18 @@ static int drm_set_option(struct gamma_state *state, const char *key, const char *value) { if (!strcasecmp(key, "card")) { - state->card_num = atoi(value); + return direct_set_partitions(state, key, value); } else if (!strcasecmp(key, "crtc")) { - if (!strcasecmp(value, "all")) { - state->crtc_num = -1; - } else { - state->crtc_num = atoi(value); - if (state->crtc_num < 0) { - weprintf(_("CRTC must be a non-negative integer")); - return -1; - } - } + return direct_set_crtcs(state, key, value); } else { weprintf(_("Unknown method parameter: `%s'."), key); return -1; } - - return 0; -} - - -static int -drm_apply(struct gamma_state *state, const struct colour_setting *setting, int preserve) -{ - struct drm_crtc_state *crtcs = state->crtcs; - uint32_t last_gamma_size = 0; - uint16_t *r_gamma = NULL; - uint16_t *g_gamma = NULL; - uint16_t *b_gamma = NULL; - uint16_t value; - uint32_t i, ramp_size; - - (void) preserve; /* TODO */ - - for (; crtcs->crtc_num >= 0; crtcs++) { - if (crtcs->gamma_size <= 1) - continue; - if (crtcs->gamma_size != last_gamma_size) { - if (crtcs->gamma_size > last_gamma_size) { - r_gamma = erealloc(r_gamma, 3 * crtcs->gamma_size * sizeof(uint16_t)); - g_gamma = r_gamma + crtcs->gamma_size; - b_gamma = g_gamma + crtcs->gamma_size; - } - last_gamma_size = crtcs->gamma_size; - } - - /* Initialize gamma ramps to pure state */ - ramp_size = crtcs->gamma_size; - for (i = 0; i < ramp_size; i++) { - value = (uint16_t)((double)i / (ramp_size - 1) * UINT16_MAX); - r_gamma[i] = value; - g_gamma[i] = value; - b_gamma[i] = value; - } - - fill_ramps_u16(r_gamma, g_gamma, b_gamma, crtcs->gamma_size, crtcs->gamma_size, crtcs->gamma_size, setting); - drmModeCrtcSetGamma(state->fd, crtcs->crtc_id, crtcs->gamma_size, r_gamma, g_gamma, b_gamma); - } - - free(r_gamma); - - return 0; } +#define drm_start direct_start +#define drm_apply direct_apply +#define drm_restore direct_restore +#define drm_free direct_free const struct gamma_method drm_gamma_method = GAMMA_METHOD_INIT("drm", 0, 0, drm); |