The X server's autoconfiguration probes each /dev/wsmouseN device and if its WSMOUSEIO_GTYPE ioctl returns something like WSMOUSE_TYPE_TOUCHPAD, xf86-input-ws attaches to that device directly which causes the wsmouse device to detach from the mux. This allows xinput to handle these special devices separately each with their own configuration.
The last part of the X server configuration loop is this: /* Add a default entry catching all other mux elements as "ws" */ wscons_add_pointer(WSCONS_MOUSE_PREFIX, "ws", ATTR_POINTER); For any simple mice like a basic USB one, they will remain in the mux and the wsmux ioctl handler will route WSMOUSEIO_GTYPE to the first wsmouse device in the mux. xf86-input-ws will attach to /dev/wsmouse and all USB mouse traffic will flow through that single device properly, even if the mouse is unplugged and plugged back in later. However, if X is started when there are no other mice attached to the mux (because nothing is attached or because it already took the non-simple devices out of the mux), WSMOUSEIO_GTYPE will fail and xf86-input-ws will bail due to the bad ioctl response: [ 2459.571] (II) config/wscons: checking input device /dev/wsmouse [ 2459.571] (II) Using input driver 'ws' for '/dev/wsmouse' [ 2459.571] (**) /dev/wsmouse: always reports core events [ 2459.571] (II) ws: /dev/wsmouse: debuglevel 0 [ 2459.571] (**) Option "Device" "/dev/wsmouse" [ 2459.571] (**) ws: /dev/wsmouse: ZAxisMapping: buttons 4 and 5 [ 2459.571] (**) ws: /dev/wsmouse: WAxisMapping: buttons 6 and 7 [ 2459.571] (**) ws: /dev/wsmouse: associated screen: 0 [ 2459.571] (EE) PreInit returned 2 for "/dev/wsmouse" [ 2459.571] (II) UnloadModule: "ws" Later, if a USB mouse is attached while X is running, it sends its data through the wsmouse mux but the X server isn't listening to it. To remedy this, make xf86-input-ws ignore a bad WSMOUSEIO_GTYPE ioctl response if it's talking to the mux device, and just assume it will be USB mouse traffic. This hasn't affected "legacy" laptops because they often have a pms(4) port which remains the default device in the wsmouse mux even if there isn't an actual mouse attached to that port. (This doesn't solve the issue of a device like a umt(4) attached after starting X not being treated as its own device because X would need to open that device directly. That can't easily be solved right now.) diff --git driver/xf86-input-ws/src/ws.c driver/xf86-input-ws/src/ws.c index 894704877..ebbf24615 100644 --- driver/xf86-input-ws/src/ws.c +++ driver/xf86-input-ws/src/ws.c @@ -67,6 +67,8 @@ static Atom prop_swap; int ws_debug_level = 0; #endif +#define WSMOUSE_MUX_DEVICE "/dev/wsmouse" + static XF86ModuleVersionInfo VersionRec = { "ws", MODULEVENDORSTRING, @@ -212,8 +214,17 @@ wsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) } if (wsOpen(pInfo) != Success) goto fail; - if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &priv->type) != 0) - goto fail; + if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &priv->type) != 0) { + if (strcmp(priv->devName, WSMOUSE_MUX_DEVICE) == 0) + /* + * No mice are currently connected to the mux, assume + * any traffic we see on it later will come from a USB + * mouse. + */ + priv->type = WSMOUSE_TYPE_USB; + else + goto fail; + } if (priv->type == WSMOUSE_TYPE_TPANEL) { pInfo->type_name = XI_TOUCHSCREEN; priv->raw = xf86SetBoolOption(pInfo->options, "Raw", 1);