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, &region_if, reg, NULL);
90 }
91