evdev: Support hotplug (addition/removal) of evdev devices
Just connect to the GUdevClient "uevent" signal and deals with "add"/"remove" commands. This drives the installation/removal of GSource to listen to the device.
This commit is contained in:
parent
b83a4813a4
commit
afee3b009c
@ -130,6 +130,65 @@ evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
|
|||||||
device_file, type, sysfs_path);
|
device_file, type, sysfs_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClutterInputDeviceEvdev *
|
||||||
|
find_device_by_udev_device (ClutterDeviceManagerEvdev *manager_evdev,
|
||||||
|
GUdevDevice *udev_device)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
||||||
|
GSList *l;
|
||||||
|
const gchar *sysfs_path;
|
||||||
|
|
||||||
|
sysfs_path = g_udev_device_get_sysfs_path (udev_device);
|
||||||
|
if (sysfs_path == NULL)
|
||||||
|
{
|
||||||
|
g_message ("device file is NULL");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = priv->devices; l; l = g_slist_next (l))
|
||||||
|
{
|
||||||
|
ClutterInputDeviceEvdev *device = l->data;
|
||||||
|
|
||||||
|
if (strcmp (sysfs_path,
|
||||||
|
_clutter_input_device_evdev_get_sysfs_path (device)) == 0)
|
||||||
|
{
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
evdev_remove_device (ClutterDeviceManagerEvdev *manager_evdev,
|
||||||
|
GUdevDevice *device)
|
||||||
|
{
|
||||||
|
ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev);
|
||||||
|
ClutterInputDeviceEvdev *device_evdev;
|
||||||
|
ClutterInputDevice *input_device;
|
||||||
|
|
||||||
|
device_evdev = find_device_by_udev_device (manager_evdev, device);
|
||||||
|
if (device_evdev == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
input_device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||||
|
_clutter_device_manager_remove_device (manager, input_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_uevent (GUdevClient *client,
|
||||||
|
gchar *action,
|
||||||
|
GUdevDevice *device,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
ClutterDeviceManagerEvdev *manager = CLUTTER_DEVICE_MANAGER_EVDEV (data);
|
||||||
|
|
||||||
|
if (g_strcmp0 (action, "add") == 0)
|
||||||
|
evdev_add_device (manager, device);
|
||||||
|
else if (g_strcmp0 (action, "remove") == 0)
|
||||||
|
evdev_remove_device (manager, device);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ClutterDeviceManager implementation
|
* ClutterDeviceManager implementation
|
||||||
*/
|
*/
|
||||||
|
@ -282,6 +282,49 @@ _clutter_event_evdev_remove_source (ClutterEventSource *source)
|
|||||||
event_sources = g_slist_remove (event_sources, source);
|
event_sources = g_slist_remove (event_sources, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_device_added (ClutterDeviceManager *manager,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
ClutterInputDeviceEvdev *input_device = CLUTTER_INPUT_DEVICE_EVDEV (device);
|
||||||
|
|
||||||
|
_clutter_event_evdev_add_source (input_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterEventSource *
|
||||||
|
find_source_by_device (ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
for (l = event_sources; l; l = g_slist_next (l))
|
||||||
|
{
|
||||||
|
ClutterEventSource *source = l->data;
|
||||||
|
|
||||||
|
if (source->device == (ClutterInputDeviceEvdev *) device)
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_device_removed (ClutterDeviceManager *manager,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
ClutterEventSource *source;
|
||||||
|
|
||||||
|
source = find_source_by_device (device);
|
||||||
|
if (G_UNLIKELY (source == NULL))
|
||||||
|
{
|
||||||
|
g_warning ("Trying to remove a device without a source installed ?!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_clutter_event_evdev_remove_source (source);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_events_evdev_init (ClutterBackend *backend)
|
_clutter_events_evdev_init (ClutterBackend *backend)
|
||||||
{
|
{
|
||||||
@ -301,6 +344,12 @@ _clutter_events_evdev_init (ClutterBackend *backend)
|
|||||||
|
|
||||||
_clutter_event_evdev_add_source (input_device);
|
_clutter_event_evdev_add_source (input_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make sure to add/remove sources when devices are added/removed */
|
||||||
|
g_signal_connect (device_manager, "device-added",
|
||||||
|
G_CALLBACK (on_device_added), NULL);
|
||||||
|
g_signal_connect (device_manager, "device-removed",
|
||||||
|
G_CALLBACK (on_device_removed), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user