Merge pull request #137 from emersion/gamma_control

Add gamma_control interface
This commit is contained in:
Drew DeVault 2017-09-07 10:18:28 +09:00 committed by GitHub
commit c59ccbde51
10 changed files with 229 additions and 0 deletions

View file

@ -301,6 +301,23 @@ static void wlr_drm_output_swap_buffers(struct wlr_output *_output) {
output->pageflip_pending = true; output->pageflip_pending = true;
} }
static void wlr_drm_output_set_gamma(struct wlr_output *_output,
uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) {
struct wlr_drm_output *output = (struct wlr_drm_output *)_output;
struct wlr_drm_backend *backend =
wl_container_of(output->renderer, backend, renderer);
drmModeCrtcSetGamma(backend->fd, output->crtc->id, size, r, g, b);
}
static uint16_t wlr_drm_output_get_gamma_size(struct wlr_output *_output) {
struct wlr_drm_output *output = (struct wlr_drm_output *)_output;
drmModeCrtc *crtc = output->old_crtc;
if (!crtc) {
return 0;
}
return crtc->gamma_size;
}
void wlr_drm_output_start_renderer(struct wlr_drm_output *output) { void wlr_drm_output_start_renderer(struct wlr_drm_output *output) {
if (output->state != WLR_DRM_OUTPUT_CONNECTED) { if (output->state != WLR_DRM_OUTPUT_CONNECTED) {
return; return;
@ -696,6 +713,8 @@ static struct wlr_output_impl output_impl = {
.destroy = wlr_drm_output_destroy, .destroy = wlr_drm_output_destroy,
.make_current = wlr_drm_output_make_current, .make_current = wlr_drm_output_make_current,
.swap_buffers = wlr_drm_output_swap_buffers, .swap_buffers = wlr_drm_output_swap_buffers,
.set_gamma = wlr_drm_output_set_gamma,
.get_gamma_size = wlr_drm_output_get_gamma_size,
}; };
static int find_id(const void *item, const void *cmp_to) { static int find_id(const void *item, const void *cmp_to) {

View file

@ -18,6 +18,7 @@
#include <wlr/types/wlr_xdg_shell_v6.h> #include <wlr/types/wlr_xdg_shell_v6.h>
#include <wlr/types/wlr_seat.h> #include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_data_device_manager.h> #include <wlr/types/wlr_data_device_manager.h>
#include <wlr/types/wlr_gamma_control.h>
#include "wlr/types/wlr_compositor.h" #include "wlr/types/wlr_compositor.h"
#include <wlr/xwayland.h> #include <wlr/xwayland.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
@ -37,6 +38,7 @@ struct sample_state {
struct wl_resource *focus; struct wl_resource *focus;
struct wl_listener keyboard_bound; struct wl_listener keyboard_bound;
struct wlr_xwayland *xwayland; struct wlr_xwayland *xwayland;
struct wlr_gamma_control_manager *gamma_control_manager;
int keymap_fd; int keymap_fd;
size_t keymap_size; size_t keymap_size;
uint32_t serial; uint32_t serial;
@ -162,6 +164,7 @@ int main() {
state.wl_shell = wlr_wl_shell_create(compositor.display); state.wl_shell = wlr_wl_shell_create(compositor.display);
state.xdg_shell = wlr_xdg_shell_v6_create(compositor.display); state.xdg_shell = wlr_xdg_shell_v6_create(compositor.display);
state.data_device_manager = wlr_data_device_manager_create(compositor.display); state.data_device_manager = wlr_data_device_manager_create(compositor.display);
state.gamma_control_manager = wlr_gamma_control_manager_create(compositor.display);
state.wl_seat = wlr_seat_create(compositor.display, "seat0"); state.wl_seat = wlr_seat_create(compositor.display, "seat0");
state.keyboard_bound.notify = handle_keyboard_bound; state.keyboard_bound.notify = handle_keyboard_bound;
@ -191,6 +194,7 @@ int main() {
wlr_xwayland_destroy(state.xwayland); wlr_xwayland_destroy(state.xwayland);
close(state.keymap_fd); close(state.keymap_fd);
wlr_seat_destroy(state.wl_seat); wlr_seat_destroy(state.wl_seat);
wlr_gamma_control_manager_destroy(state.gamma_control_manager);
wlr_data_device_manager_destroy(state.data_device_manager); wlr_data_device_manager_destroy(state.data_device_manager);
wlr_xdg_shell_v6_destroy(state.xdg_shell); wlr_xdg_shell_v6_destroy(state.xdg_shell);
wlr_wl_shell_destroy(state.wl_shell); wlr_wl_shell_destroy(state.wl_shell);

View file

@ -14,6 +14,9 @@ struct wlr_output_impl {
void (*destroy)(struct wlr_output *output); void (*destroy)(struct wlr_output *output);
void (*make_current)(struct wlr_output *output); void (*make_current)(struct wlr_output *output);
void (*swap_buffers)(struct wlr_output *output); void (*swap_buffers)(struct wlr_output *output);
void (*set_gamma)(struct wlr_output *output,
uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b);
uint16_t (*get_gamma_size)(struct wlr_output *output);
}; };
void wlr_output_init(struct wlr_output *output, const struct wlr_output_impl *impl); void wlr_output_init(struct wlr_output *output, const struct wlr_output_impl *impl);

View file

@ -0,0 +1,21 @@
#ifndef _WLR_GAMMA_CONTROL_H
#define _WLR_GAMMA_CONTROL_H
#include <wayland-server.h>
struct wlr_gamma_control_manager {
struct wl_global *wl_global;
void *data;
};
struct wlr_gamma_control {
struct wl_resource *resource;
struct wl_resource *output;
void* data;
};
struct wlr_gamma_control_manager *wlr_gamma_control_manager_create(struct wl_display *display);
void wlr_gamma_control_manager_destroy(struct wlr_gamma_control_manager *gamma_control_manager);
#endif

View file

@ -64,5 +64,8 @@ void wlr_output_effective_resolution(struct wlr_output *output,
int *width, int *height); int *width, int *height);
void wlr_output_make_current(struct wlr_output *output); void wlr_output_make_current(struct wlr_output *output);
void wlr_output_swap_buffers(struct wlr_output *output); void wlr_output_swap_buffers(struct wlr_output *output);
void wlr_output_set_gamma(struct wlr_output *output,
uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b);
uint16_t wlr_output_get_gamma_size(struct wlr_output *output);
#endif #endif

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="gamma_control">
<copyright>
Copyright © 2015 Giulio camuffo
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
the copyright holders not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
</copyright>
<interface name="gamma_control_manager" version="1">
<request name="destroy" type="destructor"/>
<request name="get_gamma_control">
<arg name="id" type="new_id" interface="gamma_control"/>
<arg name="output" type="object" interface="wl_output"/>
</request>
</interface>
<interface name="gamma_control" version="1">
<enum name="error">
<entry name="invalid_gamma" value="0"/>
</enum>
<request name="destroy" type="destructor"/>
<request name="set_gamma">
<arg name="red" type="array"/>
<arg name="green" type="array"/>
<arg name="blue" type="array"/>
</request>
<request name="reset_gamma"/>
<event name="gamma_size">
<arg name="size" type="uint"/>
</event>
</interface>
</protocol>

View file

@ -22,6 +22,7 @@ wayland_scanner_client = generator(
protocols = [ protocols = [
[wl_protocol_dir, 'unstable/xdg-shell/xdg-shell-unstable-v6.xml'], [wl_protocol_dir, 'unstable/xdg-shell/xdg-shell-unstable-v6.xml'],
'gamma-control.xml'
] ]
client_protocols = [ client_protocols = [

View file

@ -19,6 +19,7 @@ lib_wlr_types = static_library(
'wlr_wl_shell.c', 'wlr_wl_shell.c',
'wlr_compositor.c', 'wlr_compositor.c',
'wlr_box.c', 'wlr_box.c',
'wlr_gamma_control.c',
), ),
include_directories: wlr_inc, include_directories: wlr_inc,
dependencies: [wayland_server, pixman, wlr_protos], dependencies: [wayland_server, pixman, wlr_protos],

106
types/wlr_gamma_control.c Normal file
View file

@ -0,0 +1,106 @@
#include <assert.h>
#include <stdlib.h>
#include <wayland-server.h>
#include <wlr/types/wlr_gamma_control.h>
#include <wlr/types/wlr_output.h>
#include <wlr/util/log.h>
#include "gamma-control-protocol.h"
static void resource_destroy(struct wl_client *client, struct wl_resource *resource) {
wl_resource_destroy(resource);
}
static void gamma_control_destroy(struct wl_resource *resource) {
struct wlr_gamma_control *gamma_control = wl_resource_get_user_data(resource);
free(gamma_control);
}
static void gamma_control_set_gamma(struct wl_client *client,
struct wl_resource *_gamma_control, struct wl_array *red,
struct wl_array *green, struct wl_array *blue) {
if (red->size != green->size || red->size != blue->size) {
wl_resource_post_error(_gamma_control, GAMMA_CONTROL_ERROR_INVALID_GAMMA,
"The gamma ramps don't have the same size");
return;
}
uint16_t *r = (uint16_t *)red->data;
uint16_t *g = (uint16_t *)green->data;
uint16_t *b = (uint16_t *)blue->data;
struct wlr_gamma_control *gamma_control = wl_resource_get_user_data(_gamma_control);
struct wlr_output *output = wl_resource_get_user_data(gamma_control->output);
wlr_output_set_gamma(output, red->size / sizeof(uint16_t), r, g, b);
}
static void gamma_control_reset_gamma(struct wl_client *client,
struct wl_resource *_gamma_control) {
// TODO
}
static const struct gamma_control_interface gamma_control_implementation = {
.destroy = resource_destroy,
.set_gamma = gamma_control_set_gamma,
.reset_gamma = gamma_control_reset_gamma,
};
static void gamma_control_manager_get_gamma_control(struct wl_client *client,
struct wl_resource *_gamma_control_manager, uint32_t id,
struct wl_resource *_output) {
//struct wlr_gamma_control_manager *gamma_control_manager =
// wl_resource_get_user_data(_gamma_control_manager);
struct wlr_output *output = wl_resource_get_user_data(_output);
struct wlr_gamma_control *gamma_control;
if (!(gamma_control = calloc(1, sizeof(struct wlr_gamma_control)))) {
return;
}
gamma_control->output = _output;
gamma_control->resource = wl_resource_create(client,
&gamma_control_interface, wl_resource_get_version(_gamma_control_manager), id);
wlr_log(L_DEBUG, "new gamma_control %p (res %p)", gamma_control, gamma_control->resource);
wl_resource_set_implementation(gamma_control->resource,
&gamma_control_implementation, gamma_control, gamma_control_destroy);
gamma_control_send_gamma_size(gamma_control->resource, wlr_output_get_gamma_size(output));
}
static struct gamma_control_manager_interface gamma_control_manager_impl = {
.get_gamma_control = gamma_control_manager_get_gamma_control,
};
static void gamma_control_manager_bind(struct wl_client *wl_client,
void *_gamma_control_manager, uint32_t version, uint32_t id) {
struct wlr_gamma_control_manager *gamma_control_manager = _gamma_control_manager;
assert(wl_client && gamma_control_manager);
if (version > 1) {
wlr_log(L_ERROR, "Client requested unsupported gamma_control version, disconnecting");
wl_client_destroy(wl_client);
return;
}
struct wl_resource *wl_resource = wl_resource_create(
wl_client, &gamma_control_manager_interface, version, id);
wl_resource_set_implementation(wl_resource, &gamma_control_manager_impl,
gamma_control_manager, NULL);
}
struct wlr_gamma_control_manager *wlr_gamma_control_manager_create(struct wl_display *display) {
struct wlr_gamma_control_manager *gamma_control_manager =
calloc(1, sizeof(struct wlr_gamma_control_manager));
if (!gamma_control_manager) {
return NULL;
}
struct wl_global *wl_global = wl_global_create(display,
&gamma_control_manager_interface, 1, gamma_control_manager, gamma_control_manager_bind);
if (!wl_global) {
free(gamma_control_manager);
return NULL;
}
gamma_control_manager->wl_global = wl_global;
return gamma_control_manager;
}
void wlr_gamma_control_manager_destroy(struct wlr_gamma_control_manager *gamma_control_manager) {
if (!gamma_control_manager) {
return;
}
// TODO: this segfault (wl_display->registry_resource_list is not init)
// wl_global_destroy(gamma_control_manager->wl_global);
free(gamma_control_manager);
}

View file

@ -223,3 +223,17 @@ void wlr_output_swap_buffers(struct wlr_output *output) {
output->impl->swap_buffers(output); output->impl->swap_buffers(output);
} }
void wlr_output_set_gamma(struct wlr_output *output,
uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) {
if (output->impl->set_gamma) {
output->impl->set_gamma(output, size, r, g, b);
}
}
uint16_t wlr_output_get_gamma_size(struct wlr_output *output) {
if (!output->impl->get_gamma_size) {
return 0;
}
return output->impl->get_gamma_size(output);
}