AtlatestRepositorysigil-wm

sigil-wm / tree / testgamma-client.c

1/* SPDX-License-Identifier: BSD-3-Clause
2 * 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"
12struct gamma_output { struct wl_output *output; struct zwlr_gamma_control_v1 *control; uint32_t size; };
13static struct gamma_output outputs[64];
14static size_t count;
15static struct zwlr_gamma_control_manager_v1 *manager;
16static 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;
21static 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;
24static const struct wl_output_listener output_listener={.geometry=geometry,.mode=mode};
25static 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 }
35static void removed(void *data,struct wl_registry *registry,uint32_t name) {
36 (void)data; (void)registry; (void)name;
38static const struct wl_registry_listener registry_listener={.global=global,.global_remove=removed};
39static void gamma_size(void *data,struct zwlr_gamma_control_v1 *control,uint32_t size) {
40 (void)control; ((struct gamma_output *)data)->size=size;
42static void gamma_failed(void *data,struct zwlr_gamma_control_v1 *control) {
43 (void)control; ((struct gamma_output *)data)->size=0;
45static const struct zwlr_gamma_control_v1_listener gamma_listener={.gamma_size=gamma_size,.failed=gamma_failed};
46static void require(bool value,const char *message) {
47 if(!value) { fprintf(stderr,"gamma-client: %s\n",message); exit(1); }
49int 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,&registry_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;