From: Damien Lespiau Date: Tue, 9 Nov 2010 16:56:26 +0000 (-0500) Subject: evdev: Support hotplug (addition/removal) of evdev devices X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=afee3b009cff5149a1a97aadb3d8009c7b4a26f8;p=profile%2Fivi%2Fclutter.git 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. --- diff --git a/clutter/evdev/clutter-device-manager-evdev.c b/clutter/evdev/clutter-device-manager-evdev.c index 0b7f379..3fbd913 100644 --- a/clutter/evdev/clutter-device-manager-evdev.c +++ b/clutter/evdev/clutter-device-manager-evdev.c @@ -130,6 +130,65 @@ evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev, 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 */ diff --git a/clutter/evdev/clutter-event-evdev.c b/clutter/evdev/clutter-event-evdev.c index 0a33357..b714fd3 100644 --- a/clutter/evdev/clutter-event-evdev.c +++ b/clutter/evdev/clutter-event-evdev.c @@ -282,6 +282,49 @@ _clutter_event_evdev_remove_source (ClutterEventSource *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 _clutter_events_evdev_init (ClutterBackend *backend) { @@ -301,6 +344,12 @@ _clutter_events_evdev_init (ClutterBackend *backend) _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