AtlatestRepositorysigil-wm

sigil-wm / tree / src / cextensions.h

1/* SPDX-License-Identifier: BSD-3-Clause
2 * Protocol facts and explicit setters. Presentation choices stay in Sigil. */
3struct decoration {
4 struct wl_list link;
5 struct server *server;
6 struct wlr_xdg_toplevel_decoration_v1 *native;
7 struct wl_listener request,commit,destroy;
8 uint64_t window,id;
9 int mode;
10};
11static void decoration_request(struct wl_listener *listener,void *data) {
12 (void)data;
13 struct decoration *d=wl_container_of(listener,d,request);
14 EVENT(75,d->window,d->native->requested_mode);
16static void decoration_commit(struct wl_listener *listener,void *data) {
17 (void)data;
18 struct decoration *d=wl_container_of(listener,d,commit);
19 if(d->mode && d->native->toplevel->base->initial_commit)
20 wlr_xdg_toplevel_decoration_v1_set_mode(d->native,d->mode);
22static void decoration_destroy(struct wl_listener *listener,void *data) {
23 (void)data;
24 struct decoration *d=wl_container_of(listener,d,destroy);
25 EVENT(117,d->id);
26 d->server->decoration_count--;
27 atomic_fetch_sub(&bridge.objects,1);
28 wl_list_remove(&d->request.link); wl_list_remove(&d->commit.link);
29 wl_list_remove(&d->destroy.link); wl_list_remove(&d->link); free(d);
31static void new_decoration(struct wl_listener *listener,void *data) {
32 struct server *s=wl_container_of(listener,s,new_decoration);
33 struct wlr_xdg_toplevel_decoration_v1 *native=data;
34 struct view *v;
35 uint64_t id=0;
36 wl_list_for_each(v,&s->views,link) if(v->native==native->toplevel) { id=v->id; break; }
37 if(!id) return;
38 if(s->decoration_count>=256) { wl_resource_destroy(native->resource); return; }
39 struct decoration *d=calloc(1,sizeof(*d));
40 if(!d) return;
41 d->server=s; d->native=native; d->window=id; d->id=++s->next_id;
42 s->decoration_count++; atomic_fetch_add(&bridge.objects,1);
43 wl_list_insert(&s->decorations,&d->link);
44 listen(&native->events.request_mode,&d->request,decoration_request);
45 listen(&native->toplevel->base->surface->events.commit,&d->commit,decoration_commit);
46 listen(&native->events.destroy,&d->destroy,decoration_destroy);
47 EVENT(116,d->id,id,0,0);
48 EVENT(75,id,native->requested_mode);
50static bool set_decoration_mode(struct server *s,uint64_t window,int mode) {
51 if(mode<1 || mode>2) return false;
52 struct decoration *d;
53 wl_list_for_each(d,&s->decorations,link) {
54 if(d->window!=window) continue;
55 bool changed=d->mode!=mode;
56 d->mode=mode;
57 if(changed) EVENT(116,d->id,window,mode,0);
58 if(d->native->toplevel->base->initialized)
59 wlr_xdg_toplevel_decoration_v1_set_mode(d->native,mode);
60 return true;
61 }
62 return false;
64struct inhibitor {
65 struct wl_list link;
66 struct server *server;
67 struct wlr_idle_inhibitor_v1 *native;
68 uint64_t id,window;
69 struct wl_listener destroy;
70};
71static void inhibitor_destroy(struct wl_listener *listener,void *data) {
72 (void)data;
73 struct inhibitor *i=wl_container_of(listener,i,destroy);
74 EVENT(77,i->id);
75 wl_list_remove(&i->destroy.link); wl_list_remove(&i->link);
76 atomic_fetch_sub(&bridge.objects,1);
77 free(i);
79static void refresh_inhibitors(struct server *s) {
80 struct inhibitor *inhibitor;
81 wl_list_for_each(inhibitor,&s->inhibitors,link) {
82 uint64_t window=window_for_surface(s,inhibitor->native->surface);
83 if(window!=inhibitor->window) {
84 inhibitor->window=window;
85 EVENT(76,inhibitor->id,window);
86 }
87 }
89static void new_inhibitor(struct wl_listener *listener,void *data) {
90 struct server *s=wl_container_of(listener,s,new_inhibitor);
91 struct wlr_idle_inhibitor_v1 *native=data;
92 struct inhibitor *inhibitor=calloc(1,sizeof(*inhibitor));
93 if(!inhibitor) return;
94 inhibitor->server=s; inhibitor->id=++s->next_id; inhibitor->native=native;
95 inhibitor->window=window_for_surface(s,native->surface);
96 wl_list_insert(&s->inhibitors,&inhibitor->link);
97 listen(&native->events.destroy,&inhibitor->destroy,inhibitor_destroy);
98 atomic_fetch_add(&bridge.objects,1);
99 EVENT(76,inhibitor->id,inhibitor->window);
101static bool configure_cursor(struct server *s,const int64_t *w,size_t count) {
102 if(count<3 || w[0]<1 || w[0]>512 || w[1]<0 || w[1]>128 || w[2]<0 || w[2]>128 ||
103 count!=3+(size_t)w[1]+(size_t)w[2]) return false;
104 char name[129]={0},theme[129]={0};
105 for(int i=0;i<w[1]+w[2];i++) {
106 if(w[3+i]<32 || w[3+i]>126) return false;
107 if(i<w[1]) name[i]=w[3+i]; else theme[i-w[1]]=w[3+i];
108 }
109 if(!w[1]) { wlr_cursor_unset_image(s->cursor); return true; }
110 struct wlr_xcursor_manager *manager=wlr_xcursor_manager_create(w[2] ? theme : NULL,w[0]);
111 if(!manager) return false;
112 wlr_cursor_set_xcursor(s->cursor,manager,name);
113 if(s->cursor_manager) wlr_xcursor_manager_destroy(s->cursor_manager);
114 s->cursor_manager=manager;
115 return true;