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