1*4882a593SmuzhiyunFrom d1bdc9f19f5d941f1205561dea8116576bb8148f 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 18/93] 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 ec7e9be..fc035b9 100644 30*4882a593Smuzhiyun--- a/libweston/backend-drm/drm.c 31*4882a593Smuzhiyun+++ b/libweston/backend-drm/drm.c 32*4882a593Smuzhiyun@@ -1681,6 +1681,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