mirror of
https://gitlab.freedesktop.org/upower/upower.git
synced 2025-12-20 05:30:03 +01:00
linux: up-enumerator-udev: Process add, change, and remove udev events for keyboard backlight device
Add, update, and remove the keyboard backlight LED device when receiving add, change, and remove udev events.
This commit is contained in:
parent
e01aa7c903
commit
fd6eebb397
1 changed files with 109 additions and 52 deletions
|
|
@ -31,6 +31,7 @@
|
||||||
#include "up-device-supply-battery.h"
|
#include "up-device-supply-battery.h"
|
||||||
#include "up-device-hid.h"
|
#include "up-device-hid.h"
|
||||||
#include "up-device-wup.h"
|
#include "up-device-wup.h"
|
||||||
|
#include "up-kbd-backlight-led.h"
|
||||||
#ifdef HAVE_IDEVICE
|
#ifdef HAVE_IDEVICE
|
||||||
#include "up-device-idevice.h"
|
#include "up-device-idevice.h"
|
||||||
#endif /* HAVE_IDEVICE */
|
#endif /* HAVE_IDEVICE */
|
||||||
|
|
@ -217,39 +218,13 @@ emit_changes_for_siblings (UpEnumeratorUdev *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uevent_signal_handler_cb (UpEnumeratorUdev *self,
|
power_supply_add_helper (UpEnumeratorUdev *self,
|
||||||
const gchar *action,
|
const gchar *action,
|
||||||
GUdevDevice *device,
|
GUdevDevice *device,
|
||||||
GUdevClient *client)
|
GUdevClient *client,
|
||||||
|
GObject *obj,
|
||||||
|
const gchar *device_key)
|
||||||
{
|
{
|
||||||
const char *device_key = g_udev_device_get_sysfs_path (device);
|
|
||||||
|
|
||||||
g_debug ("Received uevent %s on device %s", action, device_key);
|
|
||||||
|
|
||||||
/* Work around the fact that we don't get a REMOVE event in some cases. */
|
|
||||||
if (g_strcmp0 (g_udev_device_get_subsystem (device), "power_supply") == 0)
|
|
||||||
device_key = g_udev_device_get_name (device);
|
|
||||||
|
|
||||||
/* It appears that we may not always receive an "add" event. As such,
|
|
||||||
* treat "add"/"change" in the same way, by first checking if we have
|
|
||||||
* seen the device.
|
|
||||||
* Even worse, we may not get a "remove" event in some odd cases, so
|
|
||||||
* if there is an "add" but we find the device (as the power_supply
|
|
||||||
* node has the same name), then remove it first before adding the
|
|
||||||
* new one.
|
|
||||||
*/
|
|
||||||
if (g_strcmp0 (action, "change") == 0 || g_strcmp0 (action, "add") == 0) {
|
|
||||||
GObject *obj;
|
|
||||||
|
|
||||||
obj = g_hash_table_lookup (self->known, device_key);
|
|
||||||
if (UP_IS_DEVICE (obj) && g_strcmp0 (action, "add") == 0 &&
|
|
||||||
g_strcmp0 (g_udev_device_get_sysfs_path (device),
|
|
||||||
g_udev_device_get_sysfs_path (G_UDEV_DEVICE (up_device_get_native (UP_DEVICE (obj))))) != 0) {
|
|
||||||
uevent_signal_handler_cb (self, "remove", device, client);
|
|
||||||
obj = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!obj) {
|
|
||||||
g_autoptr(UpDevice) up_dev = NULL;
|
g_autoptr(UpDevice) up_dev = NULL;
|
||||||
g_autofree char *parent_id = NULL;
|
g_autofree char *parent_id = NULL;
|
||||||
|
|
||||||
|
|
@ -300,6 +275,83 @@ uevent_signal_handler_cb (UpEnumeratorUdev *self,
|
||||||
|
|
||||||
if (up_dev)
|
if (up_dev)
|
||||||
g_signal_emit_by_name (self, "device-added", up_dev);
|
g_signal_emit_by_name (self, "device-added", up_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kbd_backlight_add_helper (UpEnumeratorUdev *self,
|
||||||
|
const gchar *action,
|
||||||
|
GUdevDevice *device,
|
||||||
|
GUdevClient *client,
|
||||||
|
GObject *obj,
|
||||||
|
const char *device_key)
|
||||||
|
{
|
||||||
|
UpDaemon *daemon;
|
||||||
|
g_autoptr(UpDeviceKbdBacklight) up_kbd = NULL;
|
||||||
|
g_autofree char *parent_id = NULL;
|
||||||
|
|
||||||
|
daemon = up_enumerator_get_daemon (UP_ENUMERATOR (self));
|
||||||
|
|
||||||
|
up_kbd = g_initable_new (UP_TYPE_KBD_BACKLIGHT_LED, NULL, NULL,
|
||||||
|
"daemon", daemon,
|
||||||
|
"native", device,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (up_kbd)
|
||||||
|
obj = G_OBJECT (up_kbd);
|
||||||
|
else
|
||||||
|
obj = G_OBJECT (device);
|
||||||
|
g_hash_table_insert (self->known, (char*) device_key, g_object_ref (obj));
|
||||||
|
if (up_kbd)
|
||||||
|
g_signal_emit_by_name (self, "device-added", G_OBJECT (up_kbd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
uevent_signal_handler_cb (UpEnumeratorUdev *self,
|
||||||
|
const gchar *action,
|
||||||
|
GUdevDevice *device,
|
||||||
|
GUdevClient *client)
|
||||||
|
{
|
||||||
|
const char *device_key = g_udev_device_get_sysfs_path (device);
|
||||||
|
gboolean is_kbd_backlight = FALSE;
|
||||||
|
|
||||||
|
g_debug ("Received uevent %s on device %s", action, device_key);
|
||||||
|
|
||||||
|
/* Work around the fact that we don't get a REMOVE event in some cases. */
|
||||||
|
if (g_strcmp0 (g_udev_device_get_subsystem (device), "power_supply") == 0)
|
||||||
|
device_key = g_udev_device_get_name (device);
|
||||||
|
|
||||||
|
if (g_strcmp0 (g_udev_device_get_subsystem (device), "leds") == 0) {
|
||||||
|
if (g_strrstr (device_key, "kbd_backlight") == NULL)
|
||||||
|
return;
|
||||||
|
is_kbd_backlight = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_debug ("uevent subsystem %s", g_udev_device_get_subsystem (device));
|
||||||
|
|
||||||
|
/* It appears that we may not always receive an "add" event. As such,
|
||||||
|
* treat "add"/"change" in the same way, by first checking if we have
|
||||||
|
* seen the device.
|
||||||
|
* Even worse, we may not get a "remove" event in some odd cases, so
|
||||||
|
* if there is an "add" but we find the device (as the power_supply
|
||||||
|
* node has the same name), then remove it first before adding the
|
||||||
|
* new one.
|
||||||
|
*/
|
||||||
|
if (g_strcmp0 (action, "change") == 0 || g_strcmp0 (action, "add") == 0) {
|
||||||
|
GObject *obj;
|
||||||
|
|
||||||
|
obj = g_hash_table_lookup (self->known, device_key);
|
||||||
|
if (UP_IS_DEVICE (obj) && g_strcmp0 (action, "add") == 0 &&
|
||||||
|
g_strcmp0 (g_udev_device_get_sysfs_path (device),
|
||||||
|
g_udev_device_get_sysfs_path (G_UDEV_DEVICE (up_device_get_native (UP_DEVICE (obj))))) != 0) {
|
||||||
|
uevent_signal_handler_cb (self, "remove", device, client);
|
||||||
|
obj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!obj) {
|
||||||
|
if (is_kbd_backlight)
|
||||||
|
kbd_backlight_add_helper (self, action, device, client, obj, device_key);
|
||||||
|
else
|
||||||
|
power_supply_add_helper (self, action, device, client, obj, device_key);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!UP_IS_DEVICE (obj)) {
|
if (!UP_IS_DEVICE (obj)) {
|
||||||
|
|
@ -326,6 +378,11 @@ uevent_signal_handler_cb (UpEnumeratorUdev *self,
|
||||||
|
|
||||||
g_debug ("removing device for path %s", g_udev_device_get_sysfs_path (device));
|
g_debug ("removing device for path %s", g_udev_device_get_sysfs_path (device));
|
||||||
|
|
||||||
|
if (is_kbd_backlight) {
|
||||||
|
g_signal_emit_by_name (self, "device-removed", obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
parent_id = g_object_get_data (obj, "udev-parent-id");
|
parent_id = g_object_get_data (obj, "udev-parent-id");
|
||||||
|
|
||||||
/* Remove from siblings table. */
|
/* Remove from siblings table. */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue