From b7865b732dc41e861496c5bff5d1a1254e927807 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 4 Jan 2017 03:49:33 -0500 Subject: [PATCH] Add gamma control API --- include/wlc/wlc.h | 6 ++++++ src/compositor/output.c | 27 +++++++++++++++++++++++++++ src/compositor/output.h | 1 + src/platform/backend/backend.h | 2 ++ src/platform/backend/drm.c | 16 ++++++++++++++++ 5 files changed, 52 insertions(+) diff --git a/include/wlc/wlc.h b/include/wlc/wlc.h index 1d170853..541f305d 100644 --- a/include/wlc/wlc.h +++ b/include/wlc/wlc.h @@ -280,6 +280,12 @@ bool wlc_output_get_sleep(wlc_handle output); /** Wake up / sleep. */ void wlc_output_set_sleep(wlc_handle output, bool sleep); +/** Set gamma. R, G, and B are color ramp arrays of size elements. */ +void wlc_output_set_gamma(wlc_handle output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b); + +/** Get gamma size */ +uint16_t wlc_output_get_gamma_size(wlc_handle output); + /** * Get real resolution. * Resolution applied by either wlc_output_set_resolution call or initially. diff --git a/src/compositor/output.c b/src/compositor/output.c index f64639eb..1ec4b5af 100644 --- a/src/compositor/output.c +++ b/src/compositor/output.c @@ -817,6 +817,16 @@ wlc_output_set_sleep_ptr(struct wlc_output *output, bool sleep) } } +void +wlc_output_set_gamma_ptr(struct wlc_output *output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) +{ + if (!output) + return; + + if (output->bsurface.api.set_gamma) + output->bsurface.api.set_gamma(&output->bsurface, size, r, g, b); +} + void wlc_output_set_mask_ptr(struct wlc_output *output, uint32_t mask) { @@ -913,6 +923,23 @@ wlc_output_set_sleep(wlc_handle output, bool sleep) wlc_output_set_sleep_ptr(convert_from_wlc_handle(output, "output"), sleep); } +WLC_API void +wlc_output_set_gamma(wlc_handle output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) +{ + wlc_output_set_gamma_ptr(convert_from_wlc_handle(output, "output"), size, r, g, b); +} + +WLC_API uint16_t +wlc_output_get_gamma_size(wlc_handle output) +{ + struct wlc_output *_output = convert_from_wlc_handle(output, "output"); + + if (!_output || _output->bsurface.api.get_gamma_size) + return 0; + + return _output->bsurface.api.get_gamma_size(&_output->bsurface); +} + WLC_API uint32_t wlc_output_get_mask(wlc_handle output) { diff --git a/src/compositor/output.h b/src/compositor/output.h index b26aeae9..d546ffbc 100644 --- a/src/compositor/output.h +++ b/src/compositor/output.h @@ -105,6 +105,7 @@ WLC_NONULL bool wlc_output(struct wlc_output *output); void wlc_output_focus_ptr(struct wlc_output *output); void wlc_output_set_sleep_ptr(struct wlc_output *output, bool sleep); +void wlc_output_set_gamma_ptr(struct wlc_output *output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b); WLC_NONULLV(2) bool wlc_output_set_resolution_ptr(struct wlc_output *output, const struct wlc_size *resolution, uint32_t scale); void wlc_output_set_mask_ptr(struct wlc_output *output, uint32_t mask); WLC_NONULLV(2) void wlc_output_get_pixels_ptr(struct wlc_output *output, bool (*pixels)(const struct wlc_size *size, uint8_t *rgba, void *arg), void *arg); diff --git a/src/platform/backend/backend.h b/src/platform/backend/backend.h index ec270bb3..6eb8efa3 100644 --- a/src/platform/backend/backend.h +++ b/src/platform/backend/backend.h @@ -17,6 +17,8 @@ struct wlc_backend_surface { WLC_NONULL void (*terminate)(struct wlc_backend_surface *surface); WLC_NONULL void (*sleep)(struct wlc_backend_surface *surface, bool sleep); WLC_NONULL bool (*page_flip)(struct wlc_backend_surface *surface); + WLC_NONULL void (*set_gamma)(struct wlc_backend_surface *bsurface, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b); + WLC_NONULL uint16_t (*get_gamma_size)(struct wlc_backend_surface *bsurface); } api; }; diff --git a/src/platform/backend/drm.c b/src/platform/backend/drm.c index 79491022..3e3c420a 100644 --- a/src/platform/backend/drm.c +++ b/src/platform/backend/drm.c @@ -190,6 +190,20 @@ surface_sleep(struct wlc_backend_surface *bsurface, bool sleep) } } +static void +set_gamma(struct wlc_backend_surface *bsurface, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) +{ + struct drm_surface *dsurface = bsurface->internal; + drmModeCrtcSetGamma(drm.fd, dsurface->crtc->crtc_id, size, r, g, b); +} + +static uint16_t +get_gamma_size(struct wlc_backend_surface *bsurface) +{ + struct drm_surface *dsurface = bsurface->internal; + return dsurface->crtc->gamma_size; +} + static void surface_release(struct wlc_backend_surface *bsurface) { @@ -232,6 +246,8 @@ add_output(struct gbm_device *device, struct gbm_surface *surface, struct drm_ou bsurface.window = (EGLNativeWindowType)surface; bsurface.api.sleep = surface_sleep; bsurface.api.page_flip = page_flip; + bsurface.api.set_gamma = set_gamma; + bsurface.api.get_gamma_size = get_gamma_size; struct wlc_output_event ev = { .add = { &bsurface, &info->info }, .type = WLC_OUTPUT_EVENT_ADD }; wl_signal_emit(&wlc_system_signals()->output, &ev);