backends/x11: Set trackball/trackpoint capabilities
Use gudev to detect these capabilities in input devices. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2617>
This commit is contained in:
parent
d274d4359f
commit
5471b866b3
@ -22,6 +22,10 @@
|
|||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
#include <X11/extensions/XKB.h>
|
#include <X11/extensions/XKB.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGUDEV
|
||||||
|
#include <gudev/gudev.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "backends/meta-input-settings-private.h"
|
#include "backends/meta-input-settings-private.h"
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "backends/x11/meta-clutter-backend-x11.h"
|
#include "backends/x11/meta-clutter-backend-x11.h"
|
||||||
@ -72,6 +76,10 @@ struct _MetaSeatX11
|
|||||||
GHashTable *touch_coords;
|
GHashTable *touch_coords;
|
||||||
MetaKeymapX11 *keymap;
|
MetaKeymapX11 *keymap;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGUDEV
|
||||||
|
GUdevClient *udev_client;
|
||||||
|
#endif
|
||||||
|
|
||||||
int pointer_id;
|
int pointer_id;
|
||||||
int keyboard_id;
|
int keyboard_id;
|
||||||
int opcode;
|
int opcode;
|
||||||
@ -234,10 +242,11 @@ translate_device_classes (Display *xdisplay,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_touch_device (XIAnyClassInfo **classes,
|
is_touch_device (XIAnyClassInfo **classes,
|
||||||
int n_classes,
|
int n_classes,
|
||||||
ClutterInputDeviceType *device_type,
|
ClutterInputDeviceType *device_type,
|
||||||
uint32_t *n_touch_points)
|
ClutterInputCapabilities *capabilities,
|
||||||
|
uint32_t *n_touch_points)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -251,11 +260,21 @@ is_touch_device (XIAnyClassInfo **classes,
|
|||||||
if (class->num_touches > 0)
|
if (class->num_touches > 0)
|
||||||
{
|
{
|
||||||
if (class->mode == XIDirectTouch)
|
if (class->mode == XIDirectTouch)
|
||||||
*device_type = CLUTTER_TOUCHSCREEN_DEVICE;
|
{
|
||||||
|
*device_type = CLUTTER_TOUCHSCREEN_DEVICE;
|
||||||
|
*capabilities = CLUTTER_INPUT_CAPABILITY_TOUCH;
|
||||||
|
}
|
||||||
else if (class->mode == XIDependentTouch)
|
else if (class->mode == XIDependentTouch)
|
||||||
*device_type = CLUTTER_TOUCHPAD_DEVICE;
|
{
|
||||||
|
*device_type = CLUTTER_TOUCHPAD_DEVICE;
|
||||||
|
*capabilities =
|
||||||
|
CLUTTER_INPUT_CAPABILITY_POINTER |
|
||||||
|
CLUTTER_INPUT_CAPABILITY_TOUCHPAD;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
continue;
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
*n_touch_points = class->num_touches;
|
*n_touch_points = class->num_touches;
|
||||||
|
|
||||||
@ -405,9 +424,10 @@ get_pad_features (XIDeviceInfo *info,
|
|||||||
/* The Wacom driver exports the tool type as property. Use that over
|
/* The Wacom driver exports the tool type as property. Use that over
|
||||||
guessing based on the device name */
|
guessing based on the device name */
|
||||||
static gboolean
|
static gboolean
|
||||||
guess_source_from_wacom_type (MetaSeatX11 *seat_x11,
|
guess_source_from_wacom_type (MetaSeatX11 *seat_x11,
|
||||||
XIDeviceInfo *info,
|
XIDeviceInfo *info,
|
||||||
ClutterInputDeviceType *source_out)
|
ClutterInputDeviceType *source_out,
|
||||||
|
ClutterInputCapabilities *capabilities_out)
|
||||||
{
|
{
|
||||||
Display *xdisplay = xdisplay_from_seat (seat_x11);
|
Display *xdisplay = xdisplay_from_seat (seat_x11);
|
||||||
gulong nitems, bytes_after;
|
gulong nitems, bytes_after;
|
||||||
@ -453,26 +473,33 @@ guess_source_from_wacom_type (MetaSeatX11 *seat_x11,
|
|||||||
if (device_type == types[WACOM_TYPE_STYLUS])
|
if (device_type == types[WACOM_TYPE_STYLUS])
|
||||||
{
|
{
|
||||||
*source_out = CLUTTER_PEN_DEVICE;
|
*source_out = CLUTTER_PEN_DEVICE;
|
||||||
|
*capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
|
||||||
}
|
}
|
||||||
else if (device_type == types[WACOM_TYPE_CURSOR])
|
else if (device_type == types[WACOM_TYPE_CURSOR])
|
||||||
{
|
{
|
||||||
*source_out = CLUTTER_CURSOR_DEVICE;
|
*source_out = CLUTTER_CURSOR_DEVICE;
|
||||||
|
*capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
|
||||||
}
|
}
|
||||||
else if (device_type == types[WACOM_TYPE_ERASER])
|
else if (device_type == types[WACOM_TYPE_ERASER])
|
||||||
{
|
{
|
||||||
*source_out = CLUTTER_ERASER_DEVICE;
|
*source_out = CLUTTER_ERASER_DEVICE;
|
||||||
|
*capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
|
||||||
}
|
}
|
||||||
else if (device_type == types[WACOM_TYPE_PAD])
|
else if (device_type == types[WACOM_TYPE_PAD])
|
||||||
{
|
{
|
||||||
*source_out = CLUTTER_PAD_DEVICE;
|
*source_out = CLUTTER_PAD_DEVICE;
|
||||||
|
*capabilities_out = CLUTTER_INPUT_CAPABILITY_TABLET_PAD;
|
||||||
}
|
}
|
||||||
else if (device_type == types[WACOM_TYPE_TOUCH])
|
else if (device_type == types[WACOM_TYPE_TOUCH])
|
||||||
{
|
{
|
||||||
uint32_t num_touches = 0;
|
uint32_t num_touches = 0;
|
||||||
|
|
||||||
if (!is_touch_device (info->classes, info->num_classes,
|
if (!is_touch_device (info->classes, info->num_classes,
|
||||||
source_out, &num_touches))
|
source_out, capabilities_out, &num_touches))
|
||||||
|
{
|
||||||
*source_out = CLUTTER_TOUCHSCREEN_DEVICE;
|
*source_out = CLUTTER_TOUCHSCREEN_DEVICE;
|
||||||
|
*capabilities_out = CLUTTER_INPUT_CAPABILITY_TOUCH;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -482,6 +509,25 @@ guess_source_from_wacom_type (MetaSeatX11 *seat_x11,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGUDEV
|
||||||
|
static gboolean
|
||||||
|
has_udev_property (GUdevDevice *udev_device,
|
||||||
|
const char *property_name)
|
||||||
|
{
|
||||||
|
g_autoptr (GUdevDevice) parent_udev_device = NULL;
|
||||||
|
|
||||||
|
if (NULL != g_udev_device_get_property (udev_device, property_name))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
parent_udev_device = g_udev_device_get_parent (udev_device);
|
||||||
|
|
||||||
|
if (!parent_udev_device)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return g_udev_device_get_property (parent_udev_device, property_name) != NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static ClutterInputDevice *
|
static ClutterInputDevice *
|
||||||
create_device (MetaSeatX11 *seat_x11,
|
create_device (MetaSeatX11 *seat_x11,
|
||||||
ClutterBackend *clutter_backend,
|
ClutterBackend *clutter_backend,
|
||||||
@ -489,6 +535,7 @@ create_device (MetaSeatX11 *seat_x11,
|
|||||||
{
|
{
|
||||||
Display *xdisplay = xdisplay_from_seat (seat_x11);
|
Display *xdisplay = xdisplay_from_seat (seat_x11);
|
||||||
ClutterInputDeviceType source, touch_source;
|
ClutterInputDeviceType source, touch_source;
|
||||||
|
ClutterInputCapabilities capabilities = 0;
|
||||||
ClutterInputDevice *retval;
|
ClutterInputDevice *retval;
|
||||||
ClutterInputMode mode;
|
ClutterInputMode mode;
|
||||||
uint32_t num_touches = 0, num_rings = 0, num_strips = 0;
|
uint32_t num_touches = 0, num_rings = 0, num_strips = 0;
|
||||||
@ -497,6 +544,7 @@ create_device (MetaSeatX11 *seat_x11,
|
|||||||
if (info->use == XIMasterKeyboard || info->use == XISlaveKeyboard)
|
if (info->use == XIMasterKeyboard || info->use == XISlaveKeyboard)
|
||||||
{
|
{
|
||||||
source = CLUTTER_KEYBOARD_DEVICE;
|
source = CLUTTER_KEYBOARD_DEVICE;
|
||||||
|
capabilities = CLUTTER_INPUT_CAPABILITY_KEYBOARD;
|
||||||
}
|
}
|
||||||
else if (is_touchpad_device (seat_x11, info))
|
else if (is_touchpad_device (seat_x11, info))
|
||||||
{
|
{
|
||||||
@ -504,29 +552,49 @@ create_device (MetaSeatX11 *seat_x11,
|
|||||||
}
|
}
|
||||||
else if (info->use == XISlavePointer &&
|
else if (info->use == XISlavePointer &&
|
||||||
is_touch_device (info->classes, info->num_classes,
|
is_touch_device (info->classes, info->num_classes,
|
||||||
&touch_source,
|
&touch_source, &capabilities,
|
||||||
&num_touches))
|
&num_touches))
|
||||||
{
|
{
|
||||||
source = touch_source;
|
source = touch_source;
|
||||||
}
|
}
|
||||||
else if (!guess_source_from_wacom_type (seat_x11, info, &source))
|
else if (!guess_source_from_wacom_type (seat_x11, info, &source, &capabilities))
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
name = g_ascii_strdown (info->name, -1);
|
name = g_ascii_strdown (info->name, -1);
|
||||||
|
|
||||||
if (strstr (name, "eraser") != NULL)
|
if (strstr (name, "eraser") != NULL)
|
||||||
source = CLUTTER_ERASER_DEVICE;
|
{
|
||||||
|
source = CLUTTER_ERASER_DEVICE;
|
||||||
|
capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
|
||||||
|
}
|
||||||
else if (strstr (name, "cursor") != NULL)
|
else if (strstr (name, "cursor") != NULL)
|
||||||
source = CLUTTER_CURSOR_DEVICE;
|
{
|
||||||
|
source = CLUTTER_CURSOR_DEVICE;
|
||||||
|
capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
|
||||||
|
}
|
||||||
else if (strstr (name, " pad") != NULL)
|
else if (strstr (name, " pad") != NULL)
|
||||||
source = CLUTTER_PAD_DEVICE;
|
{
|
||||||
|
source = CLUTTER_PAD_DEVICE;
|
||||||
|
capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_PAD;
|
||||||
|
}
|
||||||
else if (strstr (name, "wacom") != NULL || strstr (name, "pen") != NULL)
|
else if (strstr (name, "wacom") != NULL || strstr (name, "pen") != NULL)
|
||||||
source = CLUTTER_PEN_DEVICE;
|
{
|
||||||
|
source = CLUTTER_PEN_DEVICE;
|
||||||
|
capabilities = CLUTTER_INPUT_CAPABILITY_TABLET_TOOL;
|
||||||
|
}
|
||||||
else if (strstr (name, "touchpad") != NULL)
|
else if (strstr (name, "touchpad") != NULL)
|
||||||
source = CLUTTER_TOUCHPAD_DEVICE;
|
{
|
||||||
|
source = CLUTTER_TOUCHPAD_DEVICE;
|
||||||
|
capabilities =
|
||||||
|
CLUTTER_INPUT_CAPABILITY_POINTER |
|
||||||
|
CLUTTER_INPUT_CAPABILITY_TOUCHPAD;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
source = CLUTTER_POINTER_DEVICE;
|
{
|
||||||
|
source = CLUTTER_POINTER_DEVICE;
|
||||||
|
capabilities = CLUTTER_INPUT_CAPABILITY_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
g_free (name);
|
g_free (name);
|
||||||
}
|
}
|
||||||
@ -556,6 +624,23 @@ create_device (MetaSeatX11 *seat_x11,
|
|||||||
node_path = get_device_node_path (seat_x11, info);
|
node_path = get_device_node_path (seat_x11, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGUDEV
|
||||||
|
if (node_path)
|
||||||
|
{
|
||||||
|
g_autoptr (GUdevDevice) udev_device = NULL;
|
||||||
|
|
||||||
|
udev_device = g_udev_client_query_by_device_file (seat_x11->udev_client,
|
||||||
|
node_path);
|
||||||
|
if (udev_device)
|
||||||
|
{
|
||||||
|
if (has_udev_property (udev_device, "ID_INPUT_TRACKBALL"))
|
||||||
|
capabilities |= CLUTTER_INPUT_CAPABILITY_TRACKBALL;
|
||||||
|
if (has_udev_property (udev_device, "ID_INPUT_POINTINGSTICK"))
|
||||||
|
capabilities |= CLUTTER_INPUT_CAPABILITY_TRACKPOINT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (source == CLUTTER_PAD_DEVICE)
|
if (source == CLUTTER_PAD_DEVICE)
|
||||||
get_pad_features (info, &num_rings, &num_strips);
|
get_pad_features (info, &num_rings, &num_strips);
|
||||||
|
|
||||||
@ -564,6 +649,7 @@ create_device (MetaSeatX11 *seat_x11,
|
|||||||
"id", info->deviceid,
|
"id", info->deviceid,
|
||||||
"has-cursor", (info->use == XIMasterPointer),
|
"has-cursor", (info->use == XIMasterPointer),
|
||||||
"device-type", source,
|
"device-type", source,
|
||||||
|
"capabilities", capabilities,
|
||||||
"device-mode", mode,
|
"device-mode", mode,
|
||||||
"backend", clutter_backend,
|
"backend", clutter_backend,
|
||||||
"vendor-id", vendor_id,
|
"vendor-id", vendor_id,
|
||||||
@ -1410,6 +1496,11 @@ meta_seat_x11_constructed (GObject *object)
|
|||||||
XIEventMask event_mask;
|
XIEventMask event_mask;
|
||||||
unsigned char mask[XIMaskLen(XI_LASTEVENT)] = { 0, };
|
unsigned char mask[XIMaskLen(XI_LASTEVENT)] = { 0, };
|
||||||
int n_devices, i;
|
int n_devices, i;
|
||||||
|
#ifdef HAVE_LIBGUDEV
|
||||||
|
const char *udev_subsystems[] = { "input", NULL };
|
||||||
|
|
||||||
|
seat_x11->udev_client = g_udev_client_new (udev_subsystems);
|
||||||
|
#endif
|
||||||
|
|
||||||
info = XIQueryDevice (xdisplay, XIAllDevices, &n_devices);
|
info = XIQueryDevice (xdisplay, XIAllDevices, &n_devices);
|
||||||
|
|
||||||
@ -1475,6 +1566,10 @@ meta_seat_x11_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
MetaSeatX11 *seat_x11 = META_SEAT_X11 (object);
|
MetaSeatX11 *seat_x11 = META_SEAT_X11 (object);
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGUDEV
|
||||||
|
g_clear_object (&seat_x11->udev_client);
|
||||||
|
#endif
|
||||||
|
|
||||||
g_hash_table_unref (seat_x11->devices_by_id);
|
g_hash_table_unref (seat_x11->devices_by_id);
|
||||||
g_hash_table_unref (seat_x11->tools_by_serial);
|
g_hash_table_unref (seat_x11->tools_by_serial);
|
||||||
g_hash_table_unref (seat_x11->touch_coords);
|
g_hash_table_unref (seat_x11->touch_coords);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user