mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
evdev: Recycle device ids after devices are removed
In order to not grow the device id number forever, recycle the ids whenever a device is released. https://bugzilla.gnome.org/show_bug.cgi?id=755849
This commit is contained in:
parent
3a8ba7b173
commit
a10200509e
@ -65,6 +65,16 @@
|
|||||||
#define INITIAL_POINTER_X 16
|
#define INITIAL_POINTER_X 16
|
||||||
#define INITIAL_POINTER_Y 16
|
#define INITIAL_POINTER_Y 16
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clutter makes the assumption that two core devices have ID's 2 and 3 (core
|
||||||
|
* pointer and core keyboard).
|
||||||
|
*
|
||||||
|
* Since the two first devices that will ever be created will be the virtual
|
||||||
|
* pointer and virtual keyboard of the first seat, we fulfill the made
|
||||||
|
* assumptions by having the first device having ID 2 and following 3.
|
||||||
|
*/
|
||||||
|
#define INITIAL_DEVICE_ID 2
|
||||||
|
|
||||||
typedef struct _ClutterTouchState ClutterTouchState;
|
typedef struct _ClutterTouchState ClutterTouchState;
|
||||||
typedef struct _ClutterEventFilter ClutterEventFilter;
|
typedef struct _ClutterEventFilter ClutterEventFilter;
|
||||||
|
|
||||||
@ -142,6 +152,9 @@ struct _ClutterDeviceManagerEvdevPrivate
|
|||||||
guint stage_removed_handler;
|
guint stage_removed_handler;
|
||||||
|
|
||||||
GSList *event_filters;
|
GSList *event_filters;
|
||||||
|
|
||||||
|
gint device_id_next;
|
||||||
|
GList *free_device_ids;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void clutter_device_manager_evdev_event_extender_init (ClutterEventExtenderInterface *iface);
|
static void clutter_device_manager_evdev_event_extender_init (ClutterEventExtenderInterface *iface);
|
||||||
@ -1944,6 +1957,8 @@ clutter_device_manager_evdev_finalize (GObject *object)
|
|||||||
if (priv->libinput != NULL)
|
if (priv->libinput != NULL)
|
||||||
libinput_unref (priv->libinput);
|
libinput_unref (priv->libinput);
|
||||||
|
|
||||||
|
g_list_free (priv->free_device_ids);
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_device_manager_evdev_parent_class)->finalize (object);
|
G_OBJECT_CLASS (clutter_device_manager_evdev_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2043,6 +2058,8 @@ clutter_device_manager_evdev_init (ClutterDeviceManagerEvdev *self)
|
|||||||
"stage-removed",
|
"stage-removed",
|
||||||
G_CALLBACK (clutter_device_manager_evdev_stage_removed_cb),
|
G_CALLBACK (clutter_device_manager_evdev_stage_removed_cb),
|
||||||
self);
|
self);
|
||||||
|
|
||||||
|
priv->device_id_next = INITIAL_DEVICE_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2061,6 +2078,51 @@ _clutter_events_evdev_uninit (ClutterBackend *backend)
|
|||||||
CLUTTER_NOTE (EVENT, "Uninitializing evdev backend");
|
CLUTTER_NOTE (EVENT, "Uninitializing evdev backend");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
_clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev *manager_evdev)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
||||||
|
GList *first;
|
||||||
|
gint next_id;
|
||||||
|
|
||||||
|
if (priv->free_device_ids == NULL)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
/* We ran out of free ID's, so append 10 new ones. */
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
priv->free_device_ids =
|
||||||
|
g_list_append (priv->free_device_ids,
|
||||||
|
GINT_TO_POINTER (priv->device_id_next++));
|
||||||
|
}
|
||||||
|
|
||||||
|
first = g_list_first (priv->free_device_ids);
|
||||||
|
next_id = GPOINTER_TO_INT (first->data);
|
||||||
|
priv->free_device_ids = g_list_remove_link (priv->free_device_ids, first);
|
||||||
|
|
||||||
|
return next_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_ids (gconstpointer a,
|
||||||
|
gconstpointer b)
|
||||||
|
{
|
||||||
|
return GPOINTER_TO_INT (a) - GPOINTER_TO_INT (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_device_manager_evdev_release_device_id (ClutterDeviceManagerEvdev *manager_evdev,
|
||||||
|
ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
||||||
|
gint device_id;
|
||||||
|
|
||||||
|
device_id = clutter_input_device_get_device_id (device);
|
||||||
|
priv->free_device_ids = g_list_insert_sorted (priv->free_device_ids,
|
||||||
|
GINT_TO_POINTER (device_id),
|
||||||
|
compare_ids);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_evdev_release_devices:
|
* clutter_evdev_release_devices:
|
||||||
*
|
*
|
||||||
|
@ -56,6 +56,11 @@ GType clutter_device_manager_evdev_get_type (void) G_GNUC_CONST;
|
|||||||
void _clutter_events_evdev_init (ClutterBackend *backend);
|
void _clutter_events_evdev_init (ClutterBackend *backend);
|
||||||
void _clutter_events_evdev_uninit (ClutterBackend *backend);
|
void _clutter_events_evdev_uninit (ClutterBackend *backend);
|
||||||
|
|
||||||
|
gint _clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev *manager_evdev);
|
||||||
|
|
||||||
|
void _clutter_device_manager_evdev_release_device_id (ClutterDeviceManagerEvdev *manager_evdev,
|
||||||
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_DEVICE_MANAGER_EVDEV_H__ */
|
#endif /* __CLUTTER_DEVICE_MANAGER_EVDEV_H__ */
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "clutter-evdev.h"
|
#include "clutter-evdev.h"
|
||||||
|
|
||||||
#include "clutter-input-device-evdev.h"
|
#include "clutter-input-device-evdev.h"
|
||||||
|
#include "clutter-device-manager-evdev.h"
|
||||||
|
|
||||||
typedef struct _ClutterInputDeviceClass ClutterInputDeviceEvdevClass;
|
typedef struct _ClutterInputDeviceClass ClutterInputDeviceEvdevClass;
|
||||||
|
|
||||||
@ -41,25 +42,18 @@ G_DEFINE_TYPE (ClutterInputDeviceEvdev,
|
|||||||
clutter_input_device_evdev,
|
clutter_input_device_evdev,
|
||||||
CLUTTER_TYPE_INPUT_DEVICE)
|
CLUTTER_TYPE_INPUT_DEVICE)
|
||||||
|
|
||||||
/*
|
|
||||||
* Clutter makes the assumption that two core devices have ID's 2 and 3 (core
|
|
||||||
* pointer and core keyboard).
|
|
||||||
*
|
|
||||||
* Since the two first devices that will ever be created will be the virtual
|
|
||||||
* pointer and virtual keyboard of the first seat, we fulfill the made
|
|
||||||
* assumptions by having the first device having ID 2 and following 3.
|
|
||||||
*/
|
|
||||||
#define INITIAL_DEVICE_ID 2
|
|
||||||
|
|
||||||
static gint global_device_id_next = INITIAL_DEVICE_ID;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_input_device_evdev_finalize (GObject *object)
|
clutter_input_device_evdev_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
ClutterInputDeviceEvdev *device = CLUTTER_INPUT_DEVICE_EVDEV (object);
|
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (object);
|
||||||
|
ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (object);
|
||||||
|
ClutterDeviceManagerEvdev *manager_evdev =
|
||||||
|
CLUTTER_DEVICE_MANAGER_EVDEV (device->device_manager);
|
||||||
|
|
||||||
if (device->libinput_device)
|
if (device_evdev->libinput_device)
|
||||||
libinput_device_unref (device->libinput_device);
|
libinput_device_unref (device_evdev->libinput_device);
|
||||||
|
|
||||||
|
_clutter_device_manager_evdev_release_device_id (manager_evdev, device);
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_input_device_evdev_parent_class)->finalize (object);
|
G_OBJECT_CLASS (clutter_input_device_evdev_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -107,13 +101,17 @@ _clutter_input_device_evdev_new (ClutterDeviceManager *manager,
|
|||||||
{
|
{
|
||||||
ClutterInputDeviceEvdev *device;
|
ClutterInputDeviceEvdev *device;
|
||||||
ClutterInputDeviceType type;
|
ClutterInputDeviceType type;
|
||||||
|
ClutterDeviceManagerEvdev *manager_evdev;
|
||||||
gchar *vendor, *product;
|
gchar *vendor, *product;
|
||||||
|
gint device_id;
|
||||||
|
|
||||||
type = _clutter_input_device_evdev_determine_type (libinput_device);
|
type = _clutter_input_device_evdev_determine_type (libinput_device);
|
||||||
vendor = g_strdup_printf ("%.4x", libinput_device_get_id_vendor (libinput_device));
|
vendor = g_strdup_printf ("%.4x", libinput_device_get_id_vendor (libinput_device));
|
||||||
product = g_strdup_printf ("%.4x", libinput_device_get_id_product (libinput_device));
|
product = g_strdup_printf ("%.4x", libinput_device_get_id_product (libinput_device));
|
||||||
|
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
||||||
|
device_id = _clutter_device_manager_evdev_acquire_device_id (manager_evdev);
|
||||||
device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_EVDEV,
|
device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_EVDEV,
|
||||||
"id", global_device_id_next++,
|
"id", device_id,
|
||||||
"name", libinput_device_get_sysname (libinput_device),
|
"name", libinput_device_get_sysname (libinput_device),
|
||||||
"device-manager", manager,
|
"device-manager", manager,
|
||||||
"device-type", type,
|
"device-type", type,
|
||||||
@ -148,7 +146,9 @@ _clutter_input_device_evdev_new_virtual (ClutterDeviceManager *manager,
|
|||||||
ClutterInputDeviceType type)
|
ClutterInputDeviceType type)
|
||||||
{
|
{
|
||||||
ClutterInputDeviceEvdev *device;
|
ClutterInputDeviceEvdev *device;
|
||||||
|
ClutterDeviceManagerEvdev *manager_evdev;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
gint device_id;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -163,8 +163,10 @@ _clutter_input_device_evdev_new_virtual (ClutterDeviceManager *manager,
|
|||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
||||||
|
device_id = _clutter_device_manager_evdev_acquire_device_id (manager_evdev);
|
||||||
device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_EVDEV,
|
device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_EVDEV,
|
||||||
"id", global_device_id_next++,
|
"id", device_id,
|
||||||
"name", name,
|
"name", name,
|
||||||
"device-manager", manager,
|
"device-manager", manager,
|
||||||
"device-type", type,
|
"device-type", type,
|
||||||
|
Loading…
Reference in New Issue
Block a user