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);