comp_surf_delete(struct wl_resource * res)1 static void comp_surf_delete(struct wl_resource* res)
2 {
3 trace(TRACE_ALLOC,
4 "destroy:compositor surface(%"PRIxPTR")", (uintptr_t)res);
5 /*
6 * note that this already happens in surface destroy
7 * struct comp_surf* surf = wl_resource_get_user_data(res);
8 if (!surf)
9 return;
10
11 destroy_comp_surf(surf);
12 */
13 }
14
comp_surf_create(struct wl_client * client,struct wl_resource * res,uint32_t id)15 static void comp_surf_create(struct wl_client *client,
16 struct wl_resource *res, uint32_t id)
17 {
18 trace(TRACE_ALLOC, "create:compositor surface(%"PRIu32")", id);
19
20 /* If the client doesn't already exist, now is the time we make the first
21 * connection. Then we just accept that the surface is created, and defer
22 * any real management until the surface is promoted to a role we can fwd */
23 struct bridge_client* cl = find_client(client);
24 if (!cl){
25 wl_resource_post_error(res, WL_SHM_ERROR_INVALID_FD, "out of memory\n");
26 return;
27 }
28
29 if (cl->forked)
30 return;
31
32 /* the container for the useless- surface, we'll just hold it until
33 * an actual shell- etc. surface is created */
34 struct comp_surf* new_surf = malloc(sizeof(struct comp_surf));
35 if (!new_surf){
36 wl_resource_post_no_memory(res);
37 free(new_surf);
38 }
39 *new_surf = (struct comp_surf){
40 .client = cl,
41 .tracetag = "compositor",
42 .shm_gl_fail = wl.default_accel_surface,
43 .scale = cl->scale
44 };
45 new_surf->viewport = (struct arcan_event){
46 .category = EVENT_EXTERNAL,
47 .ext.kind = ARCAN_EVENT(VIEWPORT)
48 };
49
50 new_surf->res = wl_resource_create(client,
51 &wl_surface_interface, wl_resource_get_version(res), id);
52
53 /* prepare state trackers for both absolute and relative mouse input */
54 arcan_shmif_mousestate_setup(NULL, false, new_surf->mstate_abs);
55 arcan_shmif_mousestate_setup(NULL, true, new_surf->mstate_rel);
56
57 if (!new_surf->res){
58 wl_resource_post_no_memory(res);
59 free(new_surf);
60 }
61
62 wl_resource_set_implementation(
63 new_surf->res, &surf_if, new_surf, comp_surf_delete);
64
65 if (cl->output)
66 wl_surface_send_enter(new_surf->res, cl->output);
67 }
68
comp_create_reg(struct wl_client * client,struct wl_resource * resource,uint32_t id)69 static void comp_create_reg(struct wl_client *client,
70 struct wl_resource *resource, uint32_t id)
71 {
72 trace(TRACE_REGION, "create:region");
73 struct wl_resource* region = wl_resource_create(client,
74 &wl_region_interface, wl_resource_get_version(resource), id);
75
76 if (!region){
77 wl_resource_post_no_memory(resource);
78 }
79
80 struct surface_region* reg = malloc(sizeof(struct surface_region));
81 *reg = (struct surface_region){0};
82
83 if (!region){
84 wl_resource_post_no_memory(resource);
85 wl_resource_destroy(region);
86 return;
87 }
88
89 wl_resource_set_implementation(region, ®ion_if, reg, NULL);
90 }
91