1From d1bdc9f19f5d941f1205561dea8116576bb8148f Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Fri, 2 Apr 2021 09:49:09 +0800
4Subject: [PATCH 18/93] libinput-seat: Improve input device and output
5 associating
6
7An input device can associate with an output using udev rules's
8WL_OUTPUT property, for example:
9ATTRS{idVendor}=="0eef", ATTRS{idProduct}=="0001", ENV{WL_OUTPUT}="HDMI-A-1"
10
11An input device can be added into a wl_seat using udev rules's WL_SEAT
12property, for example:
13ATTRS{idVendor}=="0eef", ATTRS{idProduct}=="0001", ENV{WL_SEAT}="seat1"
14
15An output can associate with a wl_seat using seat entry in weston.ini's
16output section, for example:
17[output]
18name=HDMI-A-1
19seat=seat1
20
21Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
22---
23 libweston/backend-drm/drm.c |   1 +
24 libweston/libinput-seat.c   | 117 +++++++++++++++++++++++-------------
25 libweston/libinput-seat.h   |   5 +-
26 3 files changed, 79 insertions(+), 44 deletions(-)
27
28diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c
29index ec7e9be..fc035b9 100644
30--- a/libweston/backend-drm/drm.c
31+++ b/libweston/backend-drm/drm.c
32@@ -1681,6 +1681,7 @@ setup_output_seat_constraint(struct drm_backend *b,
33 			return;
34
35 		seat->base.output = output;
36+		seat->has_output = true;
37
38 		pointer = weston_seat_get_pointer(&seat->base);
39 		if (pointer)
40diff --git a/libweston/libinput-seat.c b/libweston/libinput-seat.c
41index a9c7d6f..57ff181 100644
42--- a/libweston/libinput-seat.c
43+++ b/libweston/libinput-seat.c
44@@ -89,12 +89,54 @@ output_find_by_head_name(struct weston_compositor *compositor,
45 	return NULL;
46 }
47
48+static void
49+udev_seat_update_output(struct udev_seat *seat)
50+{
51+	struct weston_compositor *c = seat->base.compositor;
52+	struct weston_output *found, *prefered = NULL;
53+	struct evdev_device *device;
54+
55+	if (seat->has_output) {
56+		if (weston_output_valid(seat->base.output))
57+			prefered = seat->base.output;
58+		else
59+			/* The seat's output been removed */
60+			seat->base.output = NULL;
61+	} else {
62+		struct weston_output *output;
63+
64+		/* default assignment to an arbitrary output */
65+		wl_list_for_each(output, &c->output_list, link) {
66+			if (weston_output_valid(output)) {
67+				prefered = output;
68+				break;
69+			}
70+		}
71+	}
72+
73+	wl_list_for_each(device, &seat->devices_list, link) {
74+		/* If we find any input device without an associated output
75+		 * or an output name to associate with, just tie it with the
76+		 * output we got here - the default assignment.
77+		 */
78+		if (!device->output_name) {
79+			evdev_device_set_output(device, prefered);
80+			continue;
81+		}
82+
83+		/* Update all devices' output associations, may they gain or
84+		 * lose it.
85+		 */
86+		found = output_find_by_head_name(c, device->output_name);
87+		evdev_device_set_output(device, found);
88+	}
89+}
90+
91 static int
92 device_added(struct udev_input *input, struct libinput_device *libinput_device)
93 {
94 	struct weston_compositor *c;
95 	struct evdev_device *device;
96-	struct weston_output *output;
97 	const char *output_name;
98 	struct weston_seat *seat;
99 	struct udev_seat *udev_seat;
100@@ -128,16 +170,10 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device)
101 				     &pointer->y);
102
103 	output_name = libinput_device_get_output_name(libinput_device);
104-	if (output_name) {
105+	if (output_name)
106 		device->output_name = strdup(output_name);
107-		output = output_find_by_head_name(c, output_name);
108-		evdev_device_set_output(device, output);
109-	} else if (!wl_list_empty(&c->output_list)) {
110-		/* default assignment to an arbitrary output */
111-		output = container_of(c->output_list.next,
112-				      struct weston_output, link);
113-		evdev_device_set_output(device, output);
114-	}
115+
116+	udev_seat_update_output(udev_seat);
117
118 	if (!input->suspended) {
119 		weston_seat_repick(seat);
120@@ -403,40 +439,27 @@ udev_seat_led_update(struct weston_seat *seat_base, enum weston_led leds)
121 }
122
123 static void
124-udev_seat_output_changed(struct udev_seat *seat, struct weston_output *output)
125+notify_output_created(struct wl_listener *listener, void *data)
126 {
127-	struct evdev_device *device;
128-	struct weston_output *found;
129-
130-	wl_list_for_each(device, &seat->devices_list, link) {
131-		/* If we find any input device without an associated output
132-		 * or an output name to associate with, just tie it with the
133-		 * output we got here - the default assignment.
134-		 */
135-		if (!device->output_name) {
136-			if (!device->output)
137-				evdev_device_set_output(device, output);
138-
139-			continue;
140-		}
141-
142-		/* Update all devices' output associations, may they gain or
143-		 * lose it.
144-		 */
145-		found = output_find_by_head_name(output->compositor,
146-						 device->output_name);
147-		evdev_device_set_output(device, found);
148-	}
149+	struct udev_seat *seat = container_of(listener, struct udev_seat,
150+					      output_created_listener);
151+	udev_seat_update_output(seat);
152 }
153
154 static void
155-notify_output_create(struct wl_listener *listener, void *data)
156+notify_output_moved(struct wl_listener *listener, void *data)
157 {
158 	struct udev_seat *seat = container_of(listener, struct udev_seat,
159-					      output_create_listener);
160-	struct weston_output *output = data;
161+					      output_moved_listener);
162+	udev_seat_update_output(seat);
163+}
164
165-	udev_seat_output_changed(seat, output);
166+static void
167+notify_output_destroyed(struct wl_listener *listener, void *data)
168+{
169+	struct udev_seat *seat = container_of(listener, struct udev_seat,
170+					      output_destroyed_listener);
171+	udev_seat_update_output(seat);
172 }
173
174 static void
175@@ -444,9 +467,7 @@ notify_output_heads_changed(struct wl_listener *listener, void *data)
176 {
177 	struct udev_seat *seat = container_of(listener, struct udev_seat,
178 					      output_heads_listener);
179-	struct weston_output *output = data;
180-
181-	udev_seat_output_changed(seat, output);
182+	udev_seat_update_output(seat);
183 }
184
185 static struct udev_seat *
186@@ -462,9 +483,17 @@ udev_seat_create(struct udev_input *input, const char *seat_name)
187 	weston_seat_init(&seat->base, c, seat_name);
188 	seat->base.led_update = udev_seat_led_update;
189
190-	seat->output_create_listener.notify = notify_output_create;
191+	seat->output_created_listener.notify = notify_output_created;
192 	wl_signal_add(&c->output_created_signal,
193-		      &seat->output_create_listener);
194+		      &seat->output_created_listener);
195+
196+	seat->output_destroyed_listener.notify = notify_output_destroyed;
197+	wl_signal_add(&c->output_destroyed_signal,
198+		      &seat->output_destroyed_listener);
199+
200+	seat->output_moved_listener.notify = notify_output_moved;
201+	wl_signal_add(&c->output_moved_signal,
202+		      &seat->output_moved_listener);
203
204 	seat->output_heads_listener.notify = notify_output_heads_changed;
205 	wl_signal_add(&c->output_heads_changed_signal,
206@@ -486,7 +515,9 @@ udev_seat_destroy(struct udev_seat *seat)
207
208 	udev_seat_remove_devices(seat);
209 	weston_seat_release(&seat->base);
210-	wl_list_remove(&seat->output_create_listener.link);
211+	wl_list_remove(&seat->output_created_listener.link);
212+	wl_list_remove(&seat->output_destroyed_listener.link);
213+	wl_list_remove(&seat->output_moved_listener.link);
214 	wl_list_remove(&seat->output_heads_listener.link);
215 	free(seat);
216 }
217diff --git a/libweston/libinput-seat.h b/libweston/libinput-seat.h
218index 315980d..636636f 100644
219--- a/libweston/libinput-seat.h
220+++ b/libweston/libinput-seat.h
221@@ -37,8 +37,11 @@ struct libinput_device;
222
223 struct udev_seat {
224 	struct weston_seat base;
225+	bool has_output;
226 	struct wl_list devices_list;
227-	struct wl_listener output_create_listener;
228+	struct wl_listener output_created_listener;
229+	struct wl_listener output_destroyed_listener;
230+	struct wl_listener output_moved_listener;
231 	struct wl_listener output_heads_listener;
232 };
233
234--
2352.20.1
236
237