File: wlr_primary_selection.c

package info (click to toggle)
wlroots 0.19.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,592 kB
  • sloc: ansic: 75,766; xml: 2,739; sh: 33; makefile: 23
file content (105 lines) | stat: -rw-r--r-- 3,110 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <assert.h>
#include <stdlib.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/util/log.h>

void wlr_primary_selection_source_init(
		struct wlr_primary_selection_source *source,
		const struct wlr_primary_selection_source_impl *impl) {
	assert(impl->send);
	*source = (struct wlr_primary_selection_source){
		.impl = impl,
	};
	wl_array_init(&source->mime_types);

	wl_signal_init(&source->events.destroy);
}

void wlr_primary_selection_source_destroy(
		struct wlr_primary_selection_source *source) {
	if (source == NULL) {
		return;
	}

	wl_signal_emit_mutable(&source->events.destroy, source);

	assert(wl_list_empty(&source->events.destroy.listener_list));

	char **p;
	wl_array_for_each(p, &source->mime_types) {
		free(*p);
	}
	wl_array_release(&source->mime_types);

	if (source->impl->destroy) {
		source->impl->destroy(source);
	} else {
		free(source);
	}
}

void wlr_primary_selection_source_send(
		struct wlr_primary_selection_source *source, const char *mime_type,
		int32_t fd) {
	source->impl->send(source, mime_type, fd);
}


void wlr_seat_request_set_primary_selection(struct wlr_seat *seat,
		struct wlr_seat_client *client,
		struct wlr_primary_selection_source *source, uint32_t serial) {
	if (client && !wlr_seat_client_validate_event_serial(client, serial)) {
		wlr_log(WLR_DEBUG, "Rejecting set_primary_selection request, "
			"serial %"PRIu32" was never given to client", serial);
		return;
	}

	if (seat->primary_selection_source &&
			serial - seat->primary_selection_serial > UINT32_MAX / 2) {
		wlr_log(WLR_DEBUG, "Rejecting set_primary_selection request, "
			"serial indicates superseded (%"PRIu32" < %"PRIu32")",
			serial, seat->primary_selection_serial);
		return;
	}

	struct wlr_seat_request_set_primary_selection_event event = {
		.source = source,
		.serial = serial,
	};
	wl_signal_emit_mutable(&seat->events.request_set_primary_selection, &event);
}

static void seat_handle_primary_selection_source_destroy(
		struct wl_listener *listener, void *data) {
	struct wlr_seat *seat =
		wl_container_of(listener, seat, primary_selection_source_destroy);
	wl_list_remove(&seat->primary_selection_source_destroy.link);
	seat->primary_selection_source = NULL;
	wl_signal_emit_mutable(&seat->events.set_primary_selection, seat);
}

void wlr_seat_set_primary_selection(struct wlr_seat *seat,
		struct wlr_primary_selection_source *source, uint32_t serial) {
	if (seat->primary_selection_source == source) {
		seat->primary_selection_serial = serial;
		return;
	}

	if (seat->primary_selection_source != NULL) {
		wl_list_remove(&seat->primary_selection_source_destroy.link);
		wlr_primary_selection_source_destroy(seat->primary_selection_source);
		seat->primary_selection_source = NULL;
	}

	seat->primary_selection_source = source;
	seat->primary_selection_serial = serial;

	if (source != NULL) {
		seat->primary_selection_source_destroy.notify =
			seat_handle_primary_selection_source_destroy;
		wl_signal_add(&source->events.destroy,
			&seat->primary_selection_source_destroy);
	}

	wl_signal_emit_mutable(&seat->events.set_primary_selection, seat);
}