1 #define _POSIX_C_SOURCE 200809L
2 #include <assert.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <wlr/types/wlr_data_control_v1.h>
7 #include <wlr/types/wlr_data_device.h>
8 #include <wlr/types/wlr_primary_selection.h>
9 #include <wlr/util/log.h>
10 #include "util/signal.h"
11 #include "wlr-data-control-unstable-v1-protocol.h"
12 
13 #define DATA_CONTROL_MANAGER_VERSION 2
14 
15 struct data_control_source {
16 	struct wl_resource *resource;
17 	struct wl_array mime_types;
18 	bool finalized;
19 
20 	// Only one of these is non-NULL.
21 	struct wlr_data_source *active_source;
22 	struct wlr_primary_selection_source *active_primary_source;
23 };
24 
25 static const struct zwlr_data_control_source_v1_interface source_impl;
26 
source_from_resource(struct wl_resource * resource)27 static struct data_control_source *source_from_resource(
28 		struct wl_resource *resource) {
29 	assert(wl_resource_instance_of(resource,
30 		&zwlr_data_control_source_v1_interface, &source_impl));
31 	return wl_resource_get_user_data(resource);
32 }
33 
source_handle_offer(struct wl_client * client,struct wl_resource * resource,const char * mime_type)34 static void source_handle_offer(struct wl_client *client,
35 		struct wl_resource *resource, const char *mime_type) {
36 	struct data_control_source *source = source_from_resource(resource);
37 	if (source == NULL) {
38 		return;
39 	}
40 
41 	if (source->finalized) {
42 		wl_resource_post_error(resource,
43 			ZWLR_DATA_CONTROL_SOURCE_V1_ERROR_INVALID_OFFER,
44 			"cannot mutate offer after set_selection or "
45 			"set_primary_selection");
46 		return;
47 	}
48 
49 	const char **mime_type_ptr;
50 	wl_array_for_each(mime_type_ptr, &source->mime_types) {
51 		if (strcmp(*mime_type_ptr, mime_type) == 0) {
52 			wlr_log(WLR_DEBUG, "Ignoring duplicate MIME type offer %s",
53 				mime_type);
54 			return;
55 		}
56 	}
57 
58 	char *dup_mime_type = strdup(mime_type);
59 	if (dup_mime_type == NULL) {
60 		wl_resource_post_no_memory(resource);
61 		return;
62 	}
63 
64 	char **p = wl_array_add(&source->mime_types, sizeof(char *));
65 	if (p == NULL) {
66 		free(dup_mime_type);
67 		wl_resource_post_no_memory(resource);
68 		return;
69 	}
70 
71 	*p = dup_mime_type;
72 }
73 
source_handle_destroy(struct wl_client * client,struct wl_resource * resource)74 static void source_handle_destroy(struct wl_client *client,
75 		struct wl_resource *resource) {
76 	wl_resource_destroy(resource);
77 }
78 
79 static const struct zwlr_data_control_source_v1_interface source_impl = {
80 	.offer = source_handle_offer,
81 	.destroy = source_handle_destroy,
82 };
83 
data_control_source_destroy(struct data_control_source * source)84 static void data_control_source_destroy(struct data_control_source *source) {
85 	if (source == NULL) {
86 		return;
87 	}
88 
89 	char **p;
90 	wl_array_for_each(p, &source->mime_types) {
91 		free(*p);
92 	}
93 	wl_array_release(&source->mime_types);
94 
95 	// Prevent destructors below from calling this recursively.
96 	wl_resource_set_user_data(source->resource, NULL);
97 
98 	if (source->active_source != NULL) {
99 		wlr_data_source_destroy(source->active_source);
100 	} else if (source->active_primary_source != NULL) {
101 		wlr_primary_selection_source_destroy(
102 			source->active_primary_source);
103 	}
104 
105 	free(source);
106 }
107 
source_handle_resource_destroy(struct wl_resource * resource)108 static void source_handle_resource_destroy(struct wl_resource *resource) {
109 	struct data_control_source *source = source_from_resource(resource);
110 	data_control_source_destroy(source);
111 }
112 
113 
114 struct client_data_source {
115 	struct wlr_data_source source;
116 	struct wl_resource *resource;
117 };
118 
119 static const struct wlr_data_source_impl client_source_impl;
120 
121 static struct client_data_source *
client_data_source_from_source(struct wlr_data_source * wlr_source)122 		client_data_source_from_source(struct wlr_data_source *wlr_source) {
123 	assert(wlr_source->impl == &client_source_impl);
124 	return (struct client_data_source *)wlr_source;
125 }
126 
client_source_send(struct wlr_data_source * wlr_source,const char * mime_type,int fd)127 static void client_source_send(struct wlr_data_source *wlr_source,
128 		const char *mime_type, int fd) {
129 	struct client_data_source *source =
130 		client_data_source_from_source(wlr_source);
131 	zwlr_data_control_source_v1_send_send(source->resource, mime_type, fd);
132 	close(fd);
133 }
134 
client_source_destroy(struct wlr_data_source * wlr_source)135 static void client_source_destroy(struct wlr_data_source *wlr_source) {
136 	struct client_data_source *client_source =
137 		client_data_source_from_source(wlr_source);
138 	struct data_control_source *source =
139 		source_from_resource(client_source->resource);
140 	free(client_source);
141 
142 	if (source == NULL) {
143 		return;
144 	}
145 
146 	source->active_source = NULL;
147 
148 	zwlr_data_control_source_v1_send_cancelled(source->resource);
149 	data_control_source_destroy(source);
150 }
151 
152 static const struct wlr_data_source_impl client_source_impl = {
153 	.send = client_source_send,
154 	.destroy = client_source_destroy,
155 };
156 
157 
158 struct client_primary_selection_source {
159 	struct wlr_primary_selection_source source;
160 	struct wl_resource *resource;
161 };
162 
163 static const struct wlr_primary_selection_source_impl
164 client_primary_selection_source_impl;
165 
166 static struct client_primary_selection_source *
client_primary_selection_source_from_source(struct wlr_primary_selection_source * wlr_source)167 		client_primary_selection_source_from_source(
168 			struct wlr_primary_selection_source *wlr_source) {
169 	assert(wlr_source->impl == &client_primary_selection_source_impl);
170 	return (struct client_primary_selection_source *)wlr_source;
171 }
172 
client_primary_selection_source_send(struct wlr_primary_selection_source * wlr_source,const char * mime_type,int fd)173 static void client_primary_selection_source_send(
174 		struct wlr_primary_selection_source *wlr_source,
175 		const char *mime_type, int fd) {
176 	struct client_primary_selection_source *source =
177 		client_primary_selection_source_from_source(wlr_source);
178 	zwlr_data_control_source_v1_send_send(source->resource, mime_type, fd);
179 	close(fd);
180 }
181 
client_primary_selection_source_destroy(struct wlr_primary_selection_source * wlr_source)182 static void client_primary_selection_source_destroy(
183 		struct wlr_primary_selection_source *wlr_source) {
184 	struct client_primary_selection_source *client_source =
185 		client_primary_selection_source_from_source(wlr_source);
186 	struct data_control_source *source =
187 		source_from_resource(client_source->resource);
188 	free(client_source);
189 
190 	if (source == NULL) {
191 		return;
192 	}
193 
194 	source->active_primary_source = NULL;
195 
196 	zwlr_data_control_source_v1_send_cancelled(source->resource);
197 	data_control_source_destroy(source);
198 }
199 
200 static const struct wlr_primary_selection_source_impl
201 client_primary_selection_source_impl = {
202 	.send = client_primary_selection_source_send,
203 	.destroy = client_primary_selection_source_destroy,
204 };
205 
206 
207 struct data_offer {
208 	struct wl_resource *resource;
209 	struct wlr_data_control_device_v1 *device;
210 	bool is_primary;
211 };
212 
data_offer_destroy(struct data_offer * offer)213 static void data_offer_destroy(struct data_offer *offer) {
214 	if (offer == NULL) {
215 		return;
216 	}
217 
218 	struct wlr_data_control_device_v1 *device = offer->device;
219 	if (device != NULL) {
220 		if (offer->is_primary) {
221 			device->primary_selection_offer_resource = NULL;
222 		} else {
223 			device->selection_offer_resource = NULL;
224 		}
225 	}
226 
227 	wl_resource_set_user_data(offer->resource, NULL);
228 	free(offer);
229 }
230 
231 static const struct zwlr_data_control_offer_v1_interface offer_impl;
232 
data_offer_from_offer_resource(struct wl_resource * resource)233 static struct data_offer *data_offer_from_offer_resource(
234 		struct wl_resource *resource) {
235 	assert(wl_resource_instance_of(resource,
236 		&zwlr_data_control_offer_v1_interface, &offer_impl));
237 	return wl_resource_get_user_data(resource);
238 }
239 
offer_handle_receive(struct wl_client * client,struct wl_resource * resource,const char * mime_type,int fd)240 static void offer_handle_receive(struct wl_client *client,
241 		struct wl_resource *resource, const char *mime_type, int fd) {
242 	struct data_offer *offer = data_offer_from_offer_resource(resource);
243 	if (offer == NULL) {
244 		close(fd);
245 		return;
246 	}
247 
248 	struct wlr_data_control_device_v1 *device = offer->device;
249 	if (device == NULL) {
250 		close(fd);
251 		return;
252 	}
253 
254 	if (offer->is_primary) {
255 		if (device->seat->primary_selection_source == NULL) {
256 			close(fd);
257 			return;
258 		}
259 		wlr_primary_selection_source_send(
260 			device->seat->primary_selection_source,
261 			mime_type, fd);
262 	} else {
263 		if (device->seat->selection_source == NULL) {
264 			close(fd);
265 			return;
266 		}
267 		wlr_data_source_send(device->seat->selection_source, mime_type, fd);
268 	}
269 }
270 
offer_handle_destroy(struct wl_client * client,struct wl_resource * resource)271 static void offer_handle_destroy(struct wl_client *client,
272 		struct wl_resource *resource) {
273 	wl_resource_destroy(resource);
274 }
275 
276 static const struct zwlr_data_control_offer_v1_interface offer_impl = {
277 	.receive = offer_handle_receive,
278 	.destroy = offer_handle_destroy,
279 };
280 
offer_handle_resource_destroy(struct wl_resource * resource)281 static void offer_handle_resource_destroy(struct wl_resource *resource) {
282 	struct data_offer *offer = data_offer_from_offer_resource(resource);
283 	data_offer_destroy(offer);
284 }
285 
create_offer(struct wlr_data_control_device_v1 * device,struct wl_array * mime_types,bool is_primary)286 static struct wl_resource *create_offer(struct wlr_data_control_device_v1 *device,
287 		struct wl_array *mime_types, bool is_primary) {
288 	struct wl_client *client = wl_resource_get_client(device->resource);
289 
290 	struct data_offer *offer = calloc(1, sizeof(struct data_offer));
291 	if (offer == NULL) {
292 		wl_client_post_no_memory(client);
293 		return NULL;
294 	}
295 
296 	offer->device = device;
297 	offer->is_primary = is_primary;
298 
299 	uint32_t version = wl_resource_get_version(device->resource);
300 	struct wl_resource *resource = wl_resource_create(client,
301 		&zwlr_data_control_offer_v1_interface, version, 0);
302 	if (resource == NULL) {
303 		free(offer);
304 		return NULL;
305 	}
306 
307 	offer->resource = resource;
308 
309 	wl_resource_set_implementation(resource, &offer_impl, offer,
310 		offer_handle_resource_destroy);
311 
312 	zwlr_data_control_device_v1_send_data_offer(device->resource, resource);
313 
314 	char **p;
315 	wl_array_for_each(p, mime_types) {
316 		zwlr_data_control_offer_v1_send_offer(resource, *p);
317 	}
318 
319 	return resource;
320 }
321 
322 
323 static const struct zwlr_data_control_device_v1_interface control_impl;
324 
control_from_resource(struct wl_resource * resource)325 static struct wlr_data_control_device_v1 *control_from_resource(
326 		struct wl_resource *resource) {
327 	assert(wl_resource_instance_of(resource,
328 		&zwlr_data_control_device_v1_interface, &control_impl));
329 	return wl_resource_get_user_data(resource);
330 }
331 
control_handle_set_selection(struct wl_client * client,struct wl_resource * control_resource,struct wl_resource * source_resource)332 static void control_handle_set_selection(struct wl_client *client,
333 		struct wl_resource *control_resource,
334 		struct wl_resource *source_resource) {
335 	struct wlr_data_control_device_v1 *device =
336 		control_from_resource(control_resource);
337 	if (device == NULL) {
338 		return;
339 	}
340 
341 	struct data_control_source *source = NULL;
342 	if (source_resource != NULL) {
343 		source = source_from_resource(source_resource);
344 	}
345 
346 	if (source == NULL) {
347 		wlr_seat_request_set_selection(device->seat, NULL, NULL,
348 			wl_display_next_serial(device->seat->display));
349 
350 		return;
351 	}
352 
353 	if (source->active_source != NULL ||
354 			source->active_primary_source != NULL) {
355 		wl_resource_post_error(control_resource,
356 			ZWLR_DATA_CONTROL_DEVICE_V1_ERROR_USED_SOURCE,
357 			"cannot use a data source in set_selection or "
358 			"set_primary_selection more than once");
359 
360 		return;
361 	}
362 
363 	struct client_data_source *client_source =
364 		calloc(1, sizeof(struct client_data_source));
365 	if (client_source == NULL) {
366 		wl_client_post_no_memory(client);
367 		return;
368 	}
369 	client_source->resource = source_resource;
370 
371 	struct wlr_data_source *wlr_source = &client_source->source;
372 	wlr_data_source_init(wlr_source, &client_source_impl);
373 	source->active_source = wlr_source;
374 
375 	wl_array_release(&wlr_source->mime_types);
376 	wlr_source->mime_types = source->mime_types;
377 	wl_array_init(&source->mime_types);
378 
379 	source->finalized = true;
380 
381 	wlr_seat_request_set_selection(device->seat, NULL, wlr_source,
382 		wl_display_next_serial(device->seat->display));
383 }
384 
control_handle_set_primary_selection(struct wl_client * client,struct wl_resource * control_resource,struct wl_resource * source_resource)385 static void control_handle_set_primary_selection(struct wl_client *client,
386 		struct wl_resource *control_resource,
387 		struct wl_resource *source_resource) {
388 	struct wlr_data_control_device_v1 *device =
389 		control_from_resource(control_resource);
390 	if (device == NULL) {
391 		return;
392 	}
393 
394 	struct data_control_source *source = NULL;
395 	if (source_resource != NULL) {
396 		source = source_from_resource(source_resource);
397 	}
398 
399 	if (source == NULL) {
400 		wlr_seat_request_set_primary_selection(device->seat, NULL, NULL,
401 			wl_display_next_serial(device->seat->display));
402 
403 		return;
404 	}
405 
406 	if (source->active_source != NULL ||
407 			source->active_primary_source != NULL) {
408 		wl_resource_post_error(control_resource,
409 			ZWLR_DATA_CONTROL_DEVICE_V1_ERROR_USED_SOURCE,
410 			"cannot use a data source in set_selection or "
411 			"set_primary_selection more than once");
412 
413 		return;
414 	}
415 
416 	struct client_primary_selection_source *client_source =
417 		calloc(1, sizeof(struct client_primary_selection_source));
418 	if (client_source == NULL) {
419 		wl_client_post_no_memory(client);
420 		return;
421 	}
422 	client_source->resource = source_resource;
423 
424 	struct wlr_primary_selection_source *wlr_source = &client_source->source;
425 	wlr_primary_selection_source_init(wlr_source, &client_primary_selection_source_impl);
426 	source->active_primary_source = wlr_source;
427 
428 	wl_array_release(&wlr_source->mime_types);
429 	wlr_source->mime_types = source->mime_types;
430 	wl_array_init(&source->mime_types);
431 
432 	source->finalized = true;
433 
434 	wlr_seat_request_set_primary_selection(device->seat, NULL, wlr_source,
435 		wl_display_next_serial(device->seat->display));
436 }
437 
control_handle_destroy(struct wl_client * client,struct wl_resource * control_resource)438 static void control_handle_destroy(struct wl_client *client,
439 		struct wl_resource *control_resource) {
440 	wl_resource_destroy(control_resource);
441 }
442 
443 static const struct zwlr_data_control_device_v1_interface control_impl = {
444 	.set_selection = control_handle_set_selection,
445 	.set_primary_selection = control_handle_set_primary_selection,
446 	.destroy = control_handle_destroy,
447 };
448 
control_send_selection(struct wlr_data_control_device_v1 * device)449 static void control_send_selection(struct wlr_data_control_device_v1 *device) {
450 	struct wlr_data_source *source = device->seat->selection_source;
451 
452 	if (device->selection_offer_resource != NULL) {
453 		// Make the offer inert
454 		struct data_offer *offer = data_offer_from_offer_resource(
455 			device->selection_offer_resource);
456 		data_offer_destroy(offer);
457 	}
458 
459 	device->selection_offer_resource = NULL;
460 	if (source != NULL) {
461 		device->selection_offer_resource =
462 			create_offer(device, &source->mime_types, false);
463 		if (device->selection_offer_resource == NULL) {
464 			wl_resource_post_no_memory(device->resource);
465 			return;
466 		}
467 	}
468 
469 	zwlr_data_control_device_v1_send_selection(device->resource,
470 		device->selection_offer_resource);
471 }
472 
control_send_primary_selection(struct wlr_data_control_device_v1 * device)473 static void control_send_primary_selection(
474 		struct wlr_data_control_device_v1 *device) {
475 	uint32_t version = wl_resource_get_version(device->resource);
476 	if (version < ZWLR_DATA_CONTROL_DEVICE_V1_PRIMARY_SELECTION_SINCE_VERSION) {
477 		return;
478 	}
479 
480 	struct wlr_primary_selection_source *source =
481 		device->seat->primary_selection_source;
482 
483 	if (device->primary_selection_offer_resource != NULL) {
484 		// Make the offer inert
485 		struct data_offer *offer = data_offer_from_offer_resource(
486 			device->primary_selection_offer_resource);
487 		data_offer_destroy(offer);
488 	}
489 
490 	device->primary_selection_offer_resource = NULL;
491 	if (source != NULL) {
492 		device->primary_selection_offer_resource =
493 			create_offer(device, &source->mime_types, true);
494 		if (device->primary_selection_offer_resource == NULL) {
495 			wl_resource_post_no_memory(device->resource);
496 			return;
497 		}
498 	}
499 
500 	zwlr_data_control_device_v1_send_primary_selection(device->resource,
501 		device->primary_selection_offer_resource);
502 }
503 
control_handle_resource_destroy(struct wl_resource * resource)504 static void control_handle_resource_destroy(struct wl_resource *resource) {
505 	struct wlr_data_control_device_v1 *device = control_from_resource(resource);
506 	wlr_data_control_device_v1_destroy(device);
507 }
508 
control_handle_seat_destroy(struct wl_listener * listener,void * data)509 static void control_handle_seat_destroy(struct wl_listener *listener,
510 		void *data) {
511 	struct wlr_data_control_device_v1 *device =
512 		wl_container_of(listener, device, seat_destroy);
513 	wlr_data_control_device_v1_destroy(device);
514 }
515 
control_handle_seat_set_selection(struct wl_listener * listener,void * data)516 static void control_handle_seat_set_selection(struct wl_listener *listener,
517 		void *data) {
518 	struct wlr_data_control_device_v1 *device =
519 		wl_container_of(listener, device, seat_set_selection);
520 	control_send_selection(device);
521 }
522 
control_handle_seat_set_primary_selection(struct wl_listener * listener,void * data)523 static void control_handle_seat_set_primary_selection(
524 		struct wl_listener *listener,
525 		void *data) {
526 	struct wlr_data_control_device_v1 *device =
527 		wl_container_of(listener, device, seat_set_primary_selection);
528 	control_send_primary_selection(device);
529 }
530 
wlr_data_control_device_v1_destroy(struct wlr_data_control_device_v1 * device)531 void wlr_data_control_device_v1_destroy(struct wlr_data_control_device_v1 *device) {
532 	if (device == NULL) {
533 		return;
534 	}
535 	zwlr_data_control_device_v1_send_finished(device->resource);
536 	// Make the resources inert
537 	wl_resource_set_user_data(device->resource, NULL);
538 	if (device->selection_offer_resource != NULL) {
539 		struct data_offer *offer = data_offer_from_offer_resource(
540 			device->selection_offer_resource);
541 		data_offer_destroy(offer);
542 	}
543 	if (device->primary_selection_offer_resource != NULL) {
544 		struct data_offer *offer = data_offer_from_offer_resource(
545 			device->primary_selection_offer_resource);
546 		data_offer_destroy(offer);
547 	}
548 	wl_list_remove(&device->seat_destroy.link);
549 	wl_list_remove(&device->seat_set_selection.link);
550 	wl_list_remove(&device->seat_set_primary_selection.link);
551 	wl_list_remove(&device->link);
552 	free(device);
553 }
554 
555 
556 static const struct zwlr_data_control_manager_v1_interface manager_impl;
557 
manager_from_resource(struct wl_resource * resource)558 static struct wlr_data_control_manager_v1 *manager_from_resource(
559 		struct wl_resource *resource) {
560 	assert(wl_resource_instance_of(resource,
561 		&zwlr_data_control_manager_v1_interface, &manager_impl));
562 	return wl_resource_get_user_data(resource);
563 }
564 
manager_handle_create_data_source(struct wl_client * client,struct wl_resource * manager_resource,uint32_t id)565 static void manager_handle_create_data_source(struct wl_client *client,
566 		struct wl_resource *manager_resource, uint32_t id) {
567 	struct data_control_source *source =
568 		calloc(1, sizeof(struct data_control_source));
569 	if (source == NULL) {
570 		wl_resource_post_no_memory(manager_resource);
571 		return;
572 	}
573 
574 	wl_array_init(&source->mime_types);
575 
576 	uint32_t version = wl_resource_get_version(manager_resource);
577 	source->resource = wl_resource_create(client,
578 		&zwlr_data_control_source_v1_interface, version, id);
579 	if (source->resource == NULL) {
580 		wl_resource_post_no_memory(manager_resource);
581 		wl_array_release(&source->mime_types);
582 		free(source);
583 		return;
584 	}
585 	wl_resource_set_implementation(source->resource, &source_impl, source,
586 		source_handle_resource_destroy);
587 }
588 
manager_handle_get_data_device(struct wl_client * client,struct wl_resource * manager_resource,uint32_t id,struct wl_resource * seat_resource)589 static void manager_handle_get_data_device(struct wl_client *client,
590 		struct wl_resource *manager_resource, uint32_t id,
591 		struct wl_resource *seat_resource) {
592 	struct wlr_data_control_manager_v1 *manager =
593 		manager_from_resource(manager_resource);
594 	struct wlr_seat_client *seat_client =
595 		wlr_seat_client_from_resource(seat_resource);
596 
597 	struct wlr_data_control_device_v1 *device =
598 		calloc(1, sizeof(struct wlr_data_control_device_v1));
599 	if (device == NULL) {
600 		wl_resource_post_no_memory(manager_resource);
601 		return;
602 	}
603 	device->manager = manager;
604 	device->seat = seat_client->seat;
605 
606 	uint32_t version = wl_resource_get_version(manager_resource);
607 	device->resource = wl_resource_create(client,
608 		&zwlr_data_control_device_v1_interface, version, id);
609 	if (device->resource == NULL) {
610 		wl_resource_post_no_memory(manager_resource);
611 		free(device);
612 		return;
613 	}
614 	wl_resource_set_implementation(device->resource, &control_impl, device,
615 		control_handle_resource_destroy);
616 	struct wl_resource *resource = device->resource;
617 
618 	device->seat_destroy.notify = control_handle_seat_destroy;
619 	wl_signal_add(&device->seat->events.destroy, &device->seat_destroy);
620 
621 	device->seat_set_selection.notify = control_handle_seat_set_selection;
622 	wl_signal_add(&device->seat->events.set_selection,
623 		&device->seat_set_selection);
624 
625 	device->seat_set_primary_selection.notify =
626 		control_handle_seat_set_primary_selection;
627 	wl_signal_add(&device->seat->events.set_primary_selection,
628 		&device->seat_set_primary_selection);
629 
630 	wl_list_insert(&manager->devices, &device->link);
631 	wlr_signal_emit_safe(&manager->events.new_device, device);
632 
633 	// At this point maybe the compositor decided to destroy the device. If
634 	// it's the case then the resource will be inert.
635 	device = control_from_resource(resource);
636 	if (device != NULL) {
637 		control_send_selection(device);
638 		control_send_primary_selection(device);
639 	}
640 }
641 
manager_handle_destroy(struct wl_client * client,struct wl_resource * manager_resource)642 static void manager_handle_destroy(struct wl_client *client,
643 		struct wl_resource *manager_resource) {
644 	wl_resource_destroy(manager_resource);
645 }
646 
647 static const struct zwlr_data_control_manager_v1_interface manager_impl = {
648 	.create_data_source = manager_handle_create_data_source,
649 	.get_data_device = manager_handle_get_data_device,
650 	.destroy = manager_handle_destroy,
651 };
652 
manager_bind(struct wl_client * client,void * data,uint32_t version,uint32_t id)653 static void manager_bind(struct wl_client *client, void *data, uint32_t version,
654 		uint32_t id) {
655 	struct wlr_data_control_manager_v1 *manager = data;
656 
657 	struct wl_resource *resource = wl_resource_create(client,
658 		&zwlr_data_control_manager_v1_interface, version, id);
659 	if (resource == NULL) {
660 		wl_client_post_no_memory(client);
661 		return;
662 	}
663 	wl_resource_set_implementation(resource, &manager_impl, manager, NULL);
664 }
665 
handle_display_destroy(struct wl_listener * listener,void * data)666 static void handle_display_destroy(struct wl_listener *listener, void *data) {
667 	struct wlr_data_control_manager_v1 *manager =
668 		wl_container_of(listener, manager, display_destroy);
669 	wlr_signal_emit_safe(&manager->events.destroy, manager);
670 	wl_list_remove(&manager->display_destroy.link);
671 	wl_global_destroy(manager->global);
672 	free(manager);
673 }
674 
wlr_data_control_manager_v1_create(struct wl_display * display)675 struct wlr_data_control_manager_v1 *wlr_data_control_manager_v1_create(
676 		struct wl_display *display) {
677 	struct wlr_data_control_manager_v1 *manager =
678 		calloc(1, sizeof(struct wlr_data_control_manager_v1));
679 	if (manager == NULL) {
680 		return NULL;
681 	}
682 	wl_list_init(&manager->devices);
683 	wl_signal_init(&manager->events.destroy);
684 	wl_signal_init(&manager->events.new_device);
685 
686 	manager->global = wl_global_create(display,
687 		&zwlr_data_control_manager_v1_interface,
688 		DATA_CONTROL_MANAGER_VERSION, manager, manager_bind);
689 	if (manager->global == NULL) {
690 		free(manager);
691 		return NULL;
692 	}
693 
694 	manager->display_destroy.notify = handle_display_destroy;
695 	wl_display_add_destroy_listener(display, &manager->display_destroy);
696 
697 	return manager;
698 }
699