AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause2
* Run the actual host and teardown, replacing only the headless backend's3
* unsupported LUT operations with persistent synthetic hardware state. */4
#define _GNU_SOURCE5
#define wlr_output_get_gamma_size lifecycle_gamma_size6
#define wlr_output_test_state lifecycle_test_state7
#define wlr_output_commit_state lifecycle_commit_state8
#define wlr_scene_output_build_state lifecycle_build_state9
#include "../src/c/host.c"10
#undef wlr_output_get_gamma_size11
#undef wlr_output_test_state12
#undef wlr_output_commit_state13
#undef wlr_scene_output_build_state14
#include <assert.h>15
#include <sys/mman.h>16
#include <sys/wait.h>17
extern bool wlr_output_test_state(struct wlr_output *,const struct wlr_output_state *);18
extern bool wlr_output_commit_state(struct wlr_output *,const struct wlr_output_state *);19
extern bool wlr_scene_output_build_state(struct wlr_scene_output *,struct wlr_output_state *,20
const struct wlr_scene_output_state_options *);21
struct hardware {22
atomic_uint size,blue,start_resets,exit_resets;23
};24
static struct hardware *hardware;25
size_t lifecycle_gamma_size(struct wlr_output *output) { (void)output; return 256; }26
bool lifecycle_test_state(struct wlr_output *output,const struct wlr_output_state *state) {27
struct wlr_output_state plain=*state;28
plain.committed &= ~WLR_OUTPUT_STATE_GAMMA_LUT;29
return wlr_output_test_state(output,&plain);30
}31
bool lifecycle_build_state(struct wlr_scene_output *scene,struct wlr_output_state *state,32
const struct wlr_scene_output_state_options *options) {33
uint32_t gamma=state->committed&WLR_OUTPUT_STATE_GAMMA_LUT;34
state->committed &= ~WLR_OUTPUT_STATE_GAMMA_LUT;35
bool ok=wlr_scene_output_build_state(scene,state,options);36
state->committed |= gamma;37
return ok;38
}39
bool lifecycle_commit_state(struct wlr_output *output,const struct wlr_output_state *state) {40
struct wlr_output_state plain=*state;41
plain.committed &= ~WLR_OUTPUT_STATE_GAMMA_LUT;42
bool ok=wlr_output_commit_state(output,&plain);43
if(ok && (state->committed&WLR_OUTPUT_STATE_GAMMA_LUT)) {44
atomic_store(&hardware->blue,state->gamma_lut_size ? state->gamma_lut[3*state->gamma_lut_size-1] : 65535);45
atomic_store(&hardware->size,state->gamma_lut_size);46
if(!state->gamma_lut_size) {47
if(wm_state()==4) atomic_fetch_add(&hardware->exit_resets,1);48
else atomic_fetch_add(&hardware->start_resets,1);49
}50
}51
return ok;52
}53
static void session(bool crash) {54
unsigned resets=atomic_load(&hardware->start_resets);55
assert(wm_options(128,5000) && wm_start());56
uint64_t until=now_ms()+10000,id=0;57
while(wm_state()!=2 || !id || atomic_load(&hardware->start_resets)==resets) {58
struct wm_message event;59
while(wm_next(&event)) if(event.word[0]==2 && !id) {60
id=event.word[1];61
int64_t settings[]={id,1,0,0,1000,0,-1,1280,720,60000};62
assert(wm_submit(2,1,settings,10));63
}64
if(now_ms()>=until) fprintf(stderr,"GAMMA_START_DIAGNOSTIC state=%d id=%llu resets=%u size=%u\n",65
wm_state(),(unsigned long long)id,atomic_load(&hardware->start_resets),atomic_load(&hardware->size));66
assert((now_ms()<until) && "GAMMA_LIFECYCLE_STARTUP_RESET");67
usleep(1000);68
}69
assert((atomic_load(&hardware->size)==0 && atomic_load(&hardware->blue)==65535) &&70
"GAMMA_LIFECYCLE_INHERITED_RESET");71
int64_t words[2+3*256]={id,256};72
for(size_t c=0;c<3;c++) for(size_t i=0;i<256;i++)73
words[2+c*256+i]=i*(c==0 ? 50000 : c==1 ? 35000 : 20000)/255;74
assert(wm_submit(16,1,words,2+3*256));75
while(atomic_load(&hardware->size)!=256) {76
assert((now_ms()<until) && "GAMMA_LIFECYCLE_WARM_APPLIED");77
usleep(1000);78
}79
if(crash) _exit(0); /* Skip all native teardown; hardware survives below. */80
unsigned exits=atomic_load(&hardware->exit_resets);81
struct wm_message stop={.word={1}};82
assert(wm_send(&stop));83
while(wm_state()!=3) {84
assert((now_ms()<until) && "GAMMA_LIFECYCLE_STOPPED");85
usleep(1000);86
}87
assert(wm_join());88
assert((atomic_load(&hardware->size)==0 && atomic_load(&hardware->blue)==65535 &&89
atomic_load(&hardware->exit_resets)==exits+1) && "GAMMA_LIFECYCLE_EXIT_RESET");90
}91
int main(void) {92
char directory[]="/tmp/sigil-gamma-lifecycle.XXXXXX";93
assert(mkdtemp(directory));94
assert(setenv("XDG_RUNTIME_DIR",directory,1)==0);95
assert(setenv("WLR_BACKENDS","headless",1)==0);96
assert(setenv("WLR_RENDERER","pixman",1)==0);97
assert(setenv("WLR_HEADLESS_OUTPUTS","1",1)==0);98
unsetenv("WAYLAND_DISPLAY"); unsetenv("DISPLAY");99
hardware=mmap(NULL,sizeof(*hardware),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);100
assert(hardware!=MAP_FAILED);101
atomic_init(&hardware->size,256); atomic_init(&hardware->blue,20000);102
atomic_init(&hardware->start_resets,0); atomic_init(&hardware->exit_resets,0);103
for(int arm=0;arm<3;arm++) {104
pid_t child=fork(); assert(child>=0);105
if(!child) { session(arm==1); _exit(0); }106
int status; assert(waitpid(child,&status,0)==child);107
assert((WIFEXITED(status) && WEXITSTATUS(status)==0) && "GAMMA_LIFECYCLE_CHILD");108
if(arm==1) assert((atomic_load(&hardware->size)==256 && atomic_load(&hardware->blue)==20000) &&109
"GAMMA_LIFECYCLE_CRASH_PRESERVES_HARDWARE");110
}111
puts("GAMMA_LIFECYCLE=PASS clean-exit crash-inherited-ramp fresh-start-neutral");112
munmap(hardware,sizeof(*hardware));113
for(int index=0;index<4;index++) {114
char path[128];115
snprintf(path,sizeof(path),"%s/wayland-%d",directory,index); unlink(path);116
snprintf(path,sizeof(path),"%s/wayland-%d.lock",directory,index); unlink(path);117
}118
assert(rmdir(directory)==0);119
return 0;120
}