AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause2
* Exercise native readiness and output placement with real scene/layout nodes.3
* Observe scene commits without rendering a buffer. */4
#define wlr_scene_output_commit fixture_scene_commit5
#define wlr_xdg_surface_for_each_surface fixture_each_surface6
#include "../src/c/host.c"7
#include <assert.h>8
static unsigned commits,callbacks;9
void fixture_each_surface(struct wlr_xdg_surface *surface,10
wlr_surface_iterator_func_t iterator,void *data) {11
(void)surface; (void)iterator; assert(data); callbacks++;12
}13
bool fixture_scene_commit(struct wlr_scene_output *output,14
const struct wlr_scene_output_state_options *options) {15
(void)output; (void)options; commits++; return true;16
}17
static void initialize(struct server *s) {18
wl_list_init(&s->outputs); wl_list_init(&s->views); wl_list_init(&s->pixels);19
wl_list_init(&s->constraints); wl_list_init(&s->keyboards);20
s->display=wl_display_create(); assert(s->display);21
s->scene=wlr_scene_create(); assert(s->scene);22
s->normal=wlr_scene_tree_create(&s->scene->tree); assert(s->normal);23
s->cursor=wlr_cursor_create(); assert(s->cursor);24
s->layout=wlr_output_layout_create(s->display); assert(s->layout);25
s->scene_layout=wlr_scene_attach_output_layout(s->scene,s->layout); assert(s->scene_layout);26
bridge.event_fd=eventfd(0,EFD_NONBLOCK|EFD_CLOEXEC); assert(bridge.event_fd>=0);27
}28
static void finish(struct server *s) {29
wlr_cursor_destroy(s->cursor);30
wlr_scene_node_destroy(&s->scene->tree.node);31
wl_display_destroy(s->display);32
close(bridge.event_fd); free_event_stream();33
}34
static void readiness(void) {35
struct server s={0}; initialize(&s);36
struct wlr_xdg_surface surface={0};37
struct wlr_xdg_toplevel toplevel={.base=&surface};38
struct view view={.id=1,.server=&s,.mapped=true,.native=&toplevel,.serial=24};39
view.tree=wlr_scene_tree_create(s.normal); assert(view.tree);40
wl_list_insert(&s.views,&view.link);41
wlr_scene_node_set_enabled(&view.tree->node,false);42
int64_t words[]={1,1,0,200,1,10,10,300,200,0,0,0,0,0};43
s.plan=malloc(sizeof(words)); assert(s.plan); memcpy(s.plan,words,sizeof(words));44
s.plan_token=100; s.plan_deadline=now_ms()+200;45
surface.current.configure_serial=21;46
check_plan(&s);47
assert(!s.plan && "HIDDEN_PLACEMENT_MUST_NOT_DELAY_PLAN");48
struct wm_message event; assert(pop(&bridge.events,&event));49
assert(event.word[0]==22 && event.word[2]==0);50
words[9]=1;51
s.plan=malloc(sizeof(words)); assert(s.plan); memcpy(s.plan,words,sizeof(words));52
check_plan(&s);53
assert(s.plan && "SHOWN_PLACEMENT_MUST_WAIT_FOR_CONFIGURE");54
surface.current.configure_serial=24;55
check_plan(&s);56
assert(!s.plan && view.tree->node.enabled);57
wl_list_remove(&view.link); finish(&s);58
puts("PLAN_READINESS=PASS hidden-does-not-wait shown-waits-for-commit");59
}60
static void relocation(void) {61
struct server s={0}; initialize(&s);62
s.backend=wlr_headless_backend_create(wl_display_get_event_loop(s.display)); assert(s.backend);63
struct wlr_output *native=wlr_headless_add_output(s.backend,320,240); assert(native);64
assert(wlr_backend_start(s.backend));65
struct wlr_output_state state; wlr_output_state_init(&state);66
wlr_output_state_set_enabled(&state,true);67
assert(wlr_output_commit_state(native,&state));68
wlr_output_state_finish(&state);69
struct output output={.server=&s,.id=1,.native=native,.configured_enabled=true};70
output.scene=wlr_scene_output_create(s.scene,native); assert(output.scene);71
wl_list_insert(&s.outputs,&output.link);72
place_output_state(&s,&output,320,0);73
/* Finish the initial scene, then move the survivor into the removed head's region. */74
s.scene_update_deadline=0;75
output_frame(&output.frame,NULL); unsigned before=commits;76
place_output_state(&s,&output,0,0);77
output_frame(&output.frame,NULL);78
assert(commits==before && "RELOCATED_OUTPUT_MUST_WAIT_FOR_SCENE_PLAN");79
struct wlr_xdg_surface surface={0};80
struct wlr_xdg_toplevel toplevel={.base=&surface};81
struct view view={.id=2,.server=&s,.mapped=true,.native=&toplevel,.serial=24};82
view.tree=wlr_scene_tree_create(s.normal); assert(view.tree);83
wlr_scene_node_set_position(&view.tree->node,320,0);84
wl_list_insert(&s.views,&view.link);85
surface.current.configure_serial=21;86
int64_t words[]={1,1,0,200,2,0,0,300,200,1,0,0,0,0};87
s.plan_token=101; s.plan_deadline=now_ms()+200;88
s.plan=malloc(sizeof(words)); assert(s.plan); memcpy(s.plan,words,sizeof(words));89
check_plan(&s); assert(s.plan);90
output_frame(&output.frame,NULL);91
assert(commits==before && callbacks==1 && "HELD_OUTPUT_MUST_DELIVER_PLAN_CALLBACKS");92
surface.current.configure_serial=24;93
check_plan(&s);94
assert(!s.plan && now_ms()<s.plan_deadline);95
struct wm_message event; assert(pop(&bridge.events,&event));96
assert(event.word[0]==22 && event.word[2]==0);97
output_frame(&output.frame,NULL);98
assert(commits==before+1 && "APPLIED_PLAN_MUST_RELEASE_PRESENTATION");99
place_output_state(&s,&output,0,0);100
assert(!s.scene_update_deadline && "UNCHANGED_POSITION_MUST_NOT_HOLD");101
place_output_state(&s,&output,320,0);102
uint64_t hold=s.scene_update_deadline;103
assert(hold && hold<=now_ms()+200);104
place_output_state(&s,&output,0,0);105
assert(s.scene_update_deadline==hold && "RELOCATION_MUST_NOT_EXTEND_HOLD");106
s.scene_update_deadline=now_ms();107
output_frame(&output.frame,NULL);108
assert(commits==before+2 && "EXPIRED_HOLD_MUST_ALLOW_PRESENTATION");109
wl_list_remove(&view.link);110
wl_list_remove(&output.link);111
wlr_backend_destroy(s.backend); finish(&s);112
puts("OUTPUT_RELOCATION=PASS presentation-held-until-plan configure-callback-progress");113
}114
int main(int argc,char **argv) {115
assert(argc==2);116
if(!strcmp(argv[1],"readiness")) readiness();117
else { assert(!strcmp(argv[1],"relocation")); relocation(); }118
}