AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause2
* Complete a neutral gamma request and release it, with sync barriers. */3
#include <errno.h>4
#include <stdbool.h>5
#include <stdint.h>6
#include <stdio.h>7
#include <stdlib.h>8
#include <string.h>9
#include <unistd.h>10
#include <wayland-client.h>11
#include "wlr-gamma-control-unstable-v1-client-protocol.h"12
struct gamma_output { struct wl_output *output; struct zwlr_gamma_control_v1 *control; uint32_t size; };13
static struct gamma_output outputs[64];14
static size_t count;15
static struct zwlr_gamma_control_manager_v1 *manager;16
static void geometry(void *data,struct wl_output *o,int32_t x,int32_t y,int32_t pw,int32_t ph,17
int32_t sub,const char *make,const char *model,int32_t transform) {18
(void)data; (void)o; (void)x; (void)y; (void)pw; (void)ph; (void)sub;19
(void)make; (void)model; (void)transform;20
}21
static void mode(void *data,struct wl_output *o,uint32_t flags,int32_t w,int32_t h,int32_t refresh) {22
(void)data; (void)o; (void)flags; (void)w; (void)h; (void)refresh;23
}24
static const struct wl_output_listener output_listener={.geometry=geometry,.mode=mode};25
static void global(void *data,struct wl_registry *registry,uint32_t name,const char *interface,uint32_t version) {26
(void)data; (void)version;27
if(!strcmp(interface,"zwlr_gamma_control_manager_v1"))28
manager=wl_registry_bind(registry,name,&zwlr_gamma_control_manager_v1_interface,1);29
else if(!strcmp(interface,"wl_output") && count<64) {30
outputs[count].output=wl_registry_bind(registry,name,&wl_output_interface,1);31
wl_output_add_listener(outputs[count].output,&output_listener,NULL);32
count++;33
}34
}35
static void removed(void *data,struct wl_registry *registry,uint32_t name) {36
(void)data; (void)registry; (void)name;37
}38
static const struct wl_registry_listener registry_listener={.global=global,.global_remove=removed};39
static void gamma_size(void *data,struct zwlr_gamma_control_v1 *control,uint32_t size) {40
(void)control; ((struct gamma_output *)data)->size=size;41
}42
static void gamma_failed(void *data,struct zwlr_gamma_control_v1 *control) {43
(void)control; ((struct gamma_output *)data)->size=0;44
}45
static const struct zwlr_gamma_control_v1_listener gamma_listener={.gamma_size=gamma_size,.failed=gamma_failed};46
static void require(bool value,const char *message) {47
if(!value) { fprintf(stderr,"gamma-client: %s\n",message); exit(1); }48
}49
int main(void) {50
struct wl_display *display=wl_display_connect(NULL);51
require(display!=NULL,"connect");52
struct wl_registry *registry=wl_display_get_registry(display);53
wl_registry_add_listener(registry,®istry_listener,NULL);54
require(wl_display_roundtrip(display)>=0 && manager && count,"registry roundtrip");55
for(size_t i=0;i<count;i++) {56
outputs[i].control=zwlr_gamma_control_manager_v1_get_gamma_control(manager,outputs[i].output);57
zwlr_gamma_control_v1_add_listener(outputs[i].control,&gamma_listener,&outputs[i]);58
}59
require(wl_display_roundtrip(display)>=0,"gamma-size roundtrip");60
size_t supported=0;61
for(size_t i=0;i<count;i++) {62
size_t size=outputs[i].size;63
if(!size) continue;64
require(size>=2 && size<=16384,"bounded table");65
supported++;66
uint16_t *ramp=calloc(3*size,sizeof(*ramp));67
require(ramp!=NULL,"allocate ramp");68
for(size_t c=0;c<3;c++) for(size_t j=0;j<size;j++) ramp[c*size+j]=(uint64_t)j*65535/(size-1);69
char path[]="/tmp/sigil-gamma-client.XXXXXX";70
int fd=mkstemp(path); require(fd>=0,"create table"); unlink(path);71
size_t bytes=3*size*sizeof(*ramp),written=0;72
while(written<bytes) {73
ssize_t result=write(fd,(char *)ramp+written,bytes-written);74
if(result<0 && errno==EINTR) continue;75
require(result>0,"write table"); written+=result;76
}77
zwlr_gamma_control_v1_set_gamma(outputs[i].control,fd);78
close(fd); free(ramp);79
}80
require(wl_display_roundtrip(display)>=0,"set-gamma sync roundtrip");81
for(size_t i=0;i<count;i++) zwlr_gamma_control_v1_destroy(outputs[i].control);82
require(wl_display_roundtrip(display)>=0,"release sync roundtrip");83
for(size_t i=0;i<count;i++) wl_output_destroy(outputs[i].output);84
zwlr_gamma_control_manager_v1_destroy(manager); wl_registry_destroy(registry);85
wl_display_disconnect(display);86
printf("GAMMA_ROUNDTRIP=PASS outputs=%zu supported=%zu\n",count,supported);87
return 0;88
}