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

Reply via email to