/** * Get the current gamma ramps of a monitor * * @param connection The identifier for the connection to the card * @param crtc_index The index of the CRTC to read from * @param gamma_size The size a gamma ramp * @param red Storage location for the red gamma ramp * @param green Storage location for the green gamma ramp * @param blue Storage location for the blue gamma ramp * @return Zero on success */ int blueshift_drm_get_gamma_ramps(int connection, int crtc_index, int gamma_size, uint16_t* red, uint16_t* green, uint16_t* blue) { card_connection* card = card_connections + connection; /* We need to initialise it to avoid valgrind warnings */ memset(red, 0, (size_t)gamma_size * sizeof(uint16_t)); memset(green, 0, (size_t)gamma_size * sizeof(uint16_t)); memset(blue, 0, (size_t)gamma_size * sizeof(uint16_t)); return drmModeCrtcGetGamma(card->fd, *(card->res->crtcs + crtc_index), (uint32_t)gamma_size, red, green, blue); }
static int drm_start(drm_state_t *state) { /* Acquire access to a graphics card. */ long maxlen = strlen(DRM_DIR_NAME) + strlen(DRM_DEV_NAME) + 10; char pathname[maxlen]; 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. */ perror("open"); fprintf(stderr, _("Failed to open DRM device: %s\n"), pathname); return -1; } /* Acquire mode resources. */ state->res = drmModeGetResources(state->fd); if (state->res == NULL) { fprintf(stderr, _("Failed to get DRM mode resources\n")); close(state->fd); state->fd = -1; return -1; } /* Create entries for selected CRTCs. */ int crtc_count = state->res->count_crtcs; if (state->crtc_num >= 0) { if (state->crtc_num >= crtc_count) { fprintf(stderr, _("CRTC %d does not exist. "), state->crtc_num); if (crtc_count > 1) { fprintf(stderr, _("Valid CRTCs are [0-%d].\n"), crtc_count-1); } else { fprintf(stderr, _("Only CRTC 0 exists.\n")); } close(state->fd); state->fd = -1; drmModeFreeResources(state->res); state->res = NULL; return -1; } state->crtcs = malloc(2 * sizeof(drm_crtc_state_t)); 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(drm_crtc_state_t)); 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. */ drm_crtc_state_t *crtcs = state->crtcs; for (; crtcs->crtc_num >= 0; crtcs++) { crtcs->crtc_id = state->res->crtcs[crtcs->crtc_num]; drmModeCrtc* crtc_info = drmModeGetCrtc(state->fd, crtcs->crtc_id); if (crtc_info == NULL) { fprintf(stderr, _("CRTC %i lost, skipping\n"), crtcs->crtc_num); continue; } crtcs->gamma_size = crtc_info->gamma_size; drmModeFreeCrtc(crtc_info); if (crtcs->gamma_size <= 1) { fprintf(stderr, _("Could not get gamma ramp size for CRTC %i\n" "on graphics card %i, ignoring device.\n"), 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 != NULL) { int r = drmModeCrtcGetGamma(state->fd, crtcs->crtc_id, crtcs->gamma_size, crtcs->r_gamma, crtcs->g_gamma, crtcs->b_gamma); if (r < 0) { fprintf(stderr, _("DRM could not read gamma ramps on CRTC %i on\n" "graphics card %i, ignoring device.\n"), crtcs->crtc_num, state->card_num); free(crtcs->r_gamma); crtcs->r_gamma = NULL; } } else { perror("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; }