mirror of
https://gitlab.freedesktop.org/upower/upower.git
synced 2025-12-20 02:00: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-hid.h"
|
||||
#include "up-device-wup.h"
|
||||
#include "up-kbd-backlight-led.h"
|
||||
#ifdef HAVE_IDEVICE
|
||||
#include "up-device-idevice.h"
|
||||
#endif /* HAVE_IDEVICE */
|
||||
|
|
@ -216,13 +217,102 @@ emit_changes_for_siblings (UpEnumeratorUdev *self,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
power_supply_add_helper (UpEnumeratorUdev *self,
|
||||
const gchar *action,
|
||||
GUdevDevice *device,
|
||||
GUdevClient *client,
|
||||
GObject *obj,
|
||||
const gchar *device_key)
|
||||
{
|
||||
g_autoptr(UpDevice) up_dev = NULL;
|
||||
g_autofree char *parent_id = NULL;
|
||||
|
||||
up_dev = device_new (self, device);
|
||||
|
||||
/* We work with `obj` further down, which is the UpDevice
|
||||
* if we have it, or the GUdevDevice if not. */
|
||||
if (up_dev)
|
||||
obj = G_OBJECT (up_dev);
|
||||
else
|
||||
obj = G_OBJECT (device);
|
||||
g_hash_table_insert (self->known, (char*) device_key, g_object_ref (obj));
|
||||
|
||||
/* Fire relevant sibling events and insert into lookup table */
|
||||
parent_id = device_parent_id (device);
|
||||
g_debug ("device %s has parent id: %s", device_key, parent_id);
|
||||
if (parent_id) {
|
||||
GPtrArray *devices = NULL;
|
||||
char *parent_id_key = NULL;
|
||||
int i;
|
||||
|
||||
g_hash_table_lookup_extended (self->siblings, parent_id,
|
||||
(gpointer*)&parent_id_key, (gpointer*)&devices);
|
||||
if (!devices)
|
||||
devices = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
for (i = 0; i < devices->len; i++) {
|
||||
GObject *sibling = g_ptr_array_index (devices, i);
|
||||
|
||||
if (up_dev) {
|
||||
g_autoptr(GUdevDevice) d = get_latest_udev_device (self, sibling);
|
||||
if (d)
|
||||
up_device_sibling_discovered (up_dev, G_OBJECT (d));
|
||||
}
|
||||
if (UP_IS_DEVICE (sibling))
|
||||
up_device_sibling_discovered (UP_DEVICE (sibling), obj);
|
||||
}
|
||||
|
||||
g_ptr_array_add (devices, g_object_ref (obj));
|
||||
if (!parent_id_key) {
|
||||
parent_id_key = g_strdup (parent_id);
|
||||
g_hash_table_insert (self->siblings, parent_id_key, devices);
|
||||
}
|
||||
|
||||
/* Just a reference to the hash table key */
|
||||
g_object_set_data (obj, "udev-parent-id", parent_id_key);
|
||||
}
|
||||
|
||||
if (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 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);
|
||||
|
||||
|
|
@ -230,6 +320,14 @@ uevent_signal_handler_cb (UpEnumeratorUdev *self,
|
|||
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.
|
||||
|
|
@ -250,56 +348,10 @@ uevent_signal_handler_cb (UpEnumeratorUdev *self,
|
|||
}
|
||||
|
||||
if (!obj) {
|
||||
g_autoptr(UpDevice) up_dev = NULL;
|
||||
g_autofree char *parent_id = NULL;
|
||||
|
||||
up_dev = device_new (self, device);
|
||||
|
||||
/* We work with `obj` further down, which is the UpDevice
|
||||
* if we have it, or the GUdevDevice if not. */
|
||||
if (up_dev)
|
||||
obj = G_OBJECT (up_dev);
|
||||
if (is_kbd_backlight)
|
||||
kbd_backlight_add_helper (self, action, device, client, obj, device_key);
|
||||
else
|
||||
obj = G_OBJECT (device);
|
||||
g_hash_table_insert (self->known, (char*) device_key, g_object_ref (obj));
|
||||
|
||||
/* Fire relevant sibling events and insert into lookup table */
|
||||
parent_id = device_parent_id (device);
|
||||
g_debug ("device %s has parent id: %s", device_key, parent_id);
|
||||
if (parent_id) {
|
||||
GPtrArray *devices = NULL;
|
||||
char *parent_id_key = NULL;
|
||||
int i;
|
||||
|
||||
g_hash_table_lookup_extended (self->siblings, parent_id,
|
||||
(gpointer*)&parent_id_key, (gpointer*)&devices);
|
||||
if (!devices)
|
||||
devices = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
for (i = 0; i < devices->len; i++) {
|
||||
GObject *sibling = g_ptr_array_index (devices, i);
|
||||
|
||||
if (up_dev) {
|
||||
g_autoptr(GUdevDevice) d = get_latest_udev_device (self, sibling);
|
||||
if (d)
|
||||
up_device_sibling_discovered (up_dev, G_OBJECT (d));
|
||||
}
|
||||
if (UP_IS_DEVICE (sibling))
|
||||
up_device_sibling_discovered (UP_DEVICE (sibling), obj);
|
||||
}
|
||||
|
||||
g_ptr_array_add (devices, g_object_ref (obj));
|
||||
if (!parent_id_key) {
|
||||
parent_id_key = g_strdup (parent_id);
|
||||
g_hash_table_insert (self->siblings, parent_id_key, devices);
|
||||
}
|
||||
|
||||
/* Just a reference to the hash table key */
|
||||
g_object_set_data (obj, "udev-parent-id", parent_id_key);
|
||||
}
|
||||
|
||||
if (up_dev)
|
||||
g_signal_emit_by_name (self, "device-added", up_dev);
|
||||
power_supply_add_helper (self, action, device, client, obj, device_key);
|
||||
|
||||
} else {
|
||||
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));
|
||||
|
||||
if (is_kbd_backlight) {
|
||||
g_signal_emit_by_name (self, "device-removed", obj);
|
||||
return;
|
||||
}
|
||||
|
||||
parent_id = g_object_get_data (obj, "udev-parent-id");
|
||||
|
||||
/* Remove from siblings table. */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue