evdev: keyboard or mouse?

Peter Hutterer peter.hutterer at who-t.net
Wed Dec 3 15:53:54 PST 2008


On Wed, Dec 03, 2008 at 07:59:49AM -0800, Sebastian Glita wrote:
> xinput --reattach did the trick.
> I didn't see the messages "configure as mouse/keyboard/..." as *additive*,
> so I thought only one must occur.

No, mouse is basically axes + buttons, keyboards is keys, etc. More and more
devices have multiple features and cannot be classified as only pointers or
keyboards anymore. The whole pointer/keyboard division we have in X is a bit
outdated, but we haven't really been able to replace it yet.

> But can one "filter" the device so that it is exactly and only a pointer? Or
> the reverse?

Before I review the patch: Why would you want to do that? Do you have a
practical use-case for that?

btw. git formatted patches please, it makes a lot of things a lot easier for
reviewers.

Cheers,
  Peter

> --- a/evdev.c	2008-12-03 08:36:59.000000000 +0200
> +++ b/evdev.c	2008-12-03 16:20:53.000000000 +0200
> @@ -1333,8 +1333,10 @@
>      long rel_bitmask[NBITS(REL_MAX)] = {0};
>      long abs_bitmask[NBITS(ABS_MAX)] = {0};
>      int i, has_axes, has_keys, num_buttons, has_scroll;
> +    int as_mouse, as_touchpad, as_touchscreen, as_keyboard;
>      int kernel24 = 0;
>      EvdevPtr pEvdev = pInfo->private;
> +    pointer pOpts = pInfo->options;
>  
>      if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
>          if (errno == EINVAL) {
> @@ -1367,6 +1369,8 @@
>          return 1;
>      }
>  
> +    as_mouse = as_touchpad = as_touchscreen = as_keyboard = FALSE;
> +
>      has_axes = FALSE;
>      has_keys = FALSE;
>      has_scroll = FALSE;
> @@ -1379,91 +1383,139 @@
>              num_buttons++;
>      }
>  
> -    if (num_buttons)
> -    {
> -        pEvdev->flags |= EVDEV_BUTTON_EVENTS;
> -        pEvdev->buttons = num_buttons;
> -        xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name,
> -                num_buttons);
> -    }
> -
> -    if (TestBit(REL_X, rel_bitmask) && TestBit(REL_Y, rel_bitmask)) {
> -        xf86Msg(X_INFO, "%s: Found x and y relative axes\n", pInfo->name);
> -	pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
> -	has_axes = TRUE;
> -    }
> +    /* query axes */
> +    if (TestBit(REL_X, rel_bitmask) && TestBit(REL_Y, rel_bitmask) ||
> +        TestBit(ABS_X, abs_bitmask) && TestBit(ABS_Y, abs_bitmask))
> +        has_axes = TRUE;
>  
> -    if (TestBit(REL_WHEEL, rel_bitmask) || TestBit(REL_HWHEEL, rel_bitmask)) {
> -        xf86Msg(X_INFO, "%s: Found scroll wheel(s)\n", pInfo->name);
> +    /* poll scroll */
> +    if (TestBit(REL_WHEEL, rel_bitmask) || TestBit(REL_HWHEEL, rel_bitmask))
>          has_scroll = TRUE;
> -    }
> -
> -    if (TestBit(ABS_X, abs_bitmask) && TestBit(ABS_Y, abs_bitmask)) {
> -        xf86Msg(X_INFO, "%s: Found x and y absolute axes\n", pInfo->name);
> -	pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
> -	if (TestBit(BTN_TOUCH, key_bitmask)) {
> -            if (num_buttons) {
> -                xf86Msg(X_INFO, "%s: Found absolute touchpad\n", pInfo->name);
> -                pEvdev->flags |= EVDEV_TOUCHPAD;
> -                pEvdev->old_x = pEvdev->old_y = -1;
> -            } else {
> -                xf86Msg(X_INFO, "%s: Found absolute touchscreen\n", pInfo->name);
> -                pEvdev->flags |= EVDEV_TOUCHSCREEN;
> -                pEvdev->flags |= EVDEV_BUTTON_EVENTS;
> -            }
> -	}
> -	has_axes = TRUE;
> -    }
>  
> +    /* find keys */
>      for (i = 0; i < BTN_MISC; i++)
>          if (TestBit(i, key_bitmask))
>              break;
> +    if (i < BTN_MISC)
> +        has_keys = TRUE;
>  
> -    if (i < BTN_MISC) {
> -        xf86Msg(X_INFO, "%s: Found keys\n", pInfo->name);
> -	pEvdev->flags |= EVDEV_KEYBOARD_EVENTS;
> -	has_keys = TRUE;
> -    }
>  
> +    /* mouse caps */
>      if (has_axes && num_buttons) {
> -        xf86Msg(X_INFO, "%s: Configuring as mouse\n", pInfo->name);
> -	pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
> -	    XI86_CONFIGURED;
> -	pInfo->type_name = XI_MOUSE;
> +        pInfo->flags |= XI86_CONFIGURED;
> +        as_mouse = TRUE;
>      }
>  
> -    if (pEvdev->flags & EVDEV_TOUCHSCREEN) {
> -        xf86Msg(X_INFO, "%s: Configuring as touchscreen\n", pInfo->name);
> -        pInfo->type_name = XI_TOUCHSCREEN;
> -        pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS |
> -                        XI86_CONFIGURED;
> -    }
> +    /* touchscreen/touchpad caps */
> +    if (TestBit(ABS_X, abs_bitmask) && TestBit(ABS_Y, abs_bitmask))
> +        if (TestBit(BTN_TOUCH, key_bitmask)) {
> +            pInfo->flags |= XI86_CONFIGURED;
> +            xf86Msg(X_INFO, "%s: Found absolute %s\n",
> +                    pInfo->name, num_buttons ? "touchpad" : "touchscreen");
> +            if (num_buttons)
> +                as_touchpad = TRUE;
> +            else
> +                as_touchscreen = TRUE;
> +        }
>  
> +    /* keyboard caps */
>      if (has_keys) {
>          if (kernel24) {
>              xf86Msg(X_INFO, "%s: Kernel < 2.6 is too old, ignoring keyboard\n",
>                      pInfo->name);
>          } else {
> -            xf86Msg(X_INFO, "%s: Configuring as keyboard\n", pInfo->name);
> -            pInfo->flags |= XI86_KEYBOARD_CAPABLE | XI86_CONFIGURED;
> -	    pInfo->type_name = XI_KEYBOARD;
> +            pInfo->flags |= XI86_CONFIGURED;
> +	    as_keyboard = TRUE;
>          }
>      }
>  
> -    if (has_scroll && (pInfo->flags & XI86_CONFIGURED) &&
> -        (pInfo->flags & XI86_POINTER_CAPABLE) == 0)
> -    {
> -        xf86Msg(X_INFO, "%s: Adding scrollwheel support\n", pInfo->name);
> -        pInfo->flags  |= XI86_POINTER_CAPABLE;
> -        pEvdev->flags |= EVDEV_BUTTON_EVENTS;
> -        pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
> -    }
> -
>      if ((pInfo->flags & XI86_CONFIGURED) == 0) {
>          xf86Msg(X_WARNING, "%s: Don't know how to use device\n",
>  		pInfo->name);
>          return 1;
>      }
> +    else {
> +        /* UseAsPointing and UseAsKeyboard, when specified, */
> +        /* completely ignore one use for another, forcing type_name; */
> +        /* otherwise, keyboard (if any) wins "at no cost". */
> +        int is_ptr = as_mouse || as_touchpad || as_touchscreen;
> +        int is_kbd = as_keyboard;
> +
> +        if (is_kbd && is_ptr) {
> +            is_ptr = xf86CheckBoolOption(pOpts, "UseAsPointing", FALSE);
> +            is_kbd = xf86CheckBoolOption(pOpts, "UseAsKeyboard", FALSE);
> +            if (is_kbd && is_ptr)
> +                xf86Msg(X_INFO, "%s: Don't care how you set device\n",
> +                        pInfo->name);
> +            else if (is_ptr)
> +                as_keyboard = FALSE;
> +            else if (is_kbd)
> +                as_mouse = as_touchpad = as_touchscreen = has_scroll = FALSE;
> +        } else {
> +            is_ptr = (is_ptr == xf86SetBoolOption(pOpts, "UseAsPointing", is_ptr));
> +            is_kbd = (is_kbd == xf86SetBoolOption(pOpts, "UseAsKeyboard", is_kbd));
> +            if (!is_ptr || !is_kbd)
> +                xf86Msg(X_INFO, "%s: Don't mind how you see device\n",
> +                        pInfo->name);
> +        }
> +    }
> +
> +    if (as_keyboard) {
> +        xf86Msg(X_INFO, "%s: Found keys\n", pInfo->name);
> +        pEvdev->flags |= EVDEV_KEYBOARD_EVENTS;
> +    }
> +
> +    if (as_mouse || as_touchpad || as_touchscreen) {
> +        if (num_buttons) {
> +            xf86Msg(X_INFO, "%s: Found %d mouse buttons\n", pInfo->name,
> +                    num_buttons);
> +            pEvdev->flags |= EVDEV_BUTTON_EVENTS;
> +            pEvdev->buttons = num_buttons;
> +        }
> +        if (has_scroll) {
> +            xf86Msg(X_INFO, "%s: Found scroll wheel(s)\n", pInfo->name);
> +        }
> +        if (TestBit(REL_X, rel_bitmask) && TestBit(REL_Y, rel_bitmask)) {
> +            xf86Msg(X_INFO, "%s: Found x and y relative axes\n", pInfo->name);
> +            pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
> +        }
> +        if (TestBit(ABS_X, abs_bitmask) && TestBit(ABS_Y, abs_bitmask)) {
> +            xf86Msg(X_INFO, "%s: Found x and y absolute axes\n", pInfo->name);
> +            pEvdev->flags |= EVDEV_ABSOLUTE_EVENTS;
> +        }
> +    } else if (has_scroll) {
> +        xf86Msg(X_INFO, "%s: Adding scrollwheel support\n", pInfo->name);
> +        pEvdev->flags |= EVDEV_RELATIVE_EVENTS | EVDEV_BUTTON_EVENTS;
> +        pInfo->flags |= XI86_POINTER_CAPABLE;
> +    }
> +
> +    if (as_mouse) {
> +        xf86Msg(X_INFO, "%s: Configuring as mouse\n", pInfo->name);
> +        pInfo->flags |= XI86_SEND_DRAG_EVENTS
> +                     |  XI86_POINTER_CAPABLE;
> +        pInfo->type_name = XI_MOUSE;
> +    }
> +
> +    if (as_touchpad) {
> +        xf86Msg(X_INFO, "%s: Configuring as touchpad\n", pInfo->name);
> +        pEvdev->old_x = pEvdev->old_y = -1;
> +        pInfo->flags |= XI86_SEND_DRAG_EVENTS
> +                     |  XI86_POINTER_CAPABLE;
> +        pInfo->type_name = XI_TOUCHPAD;
> +    }
> +
> +    if (as_touchscreen) {
> +        xf86Msg(X_INFO, "%s: Configuring as touchscreen\n", pInfo->name);
> +        pInfo->flags |= XI86_SEND_DRAG_EVENTS | EVDEV_BUTTON_EVENTS
> +                     |  XI86_POINTER_CAPABLE;
> +        pInfo->type_name = XI_TOUCHSCREEN;
> +    }
> +
> +    if (as_keyboard) {
> +        xf86Msg(X_INFO, "%s: Configuring as keyboard\n", pInfo->name);
> +        pInfo->flags |= XI86_KEYBOARD_CAPABLE;
> +        pInfo->type_name = XI_KEYBOARD;
> +    }
>  
>      return 0;
>  }




More information about the xorg mailing list