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