From 0d0b1249c74124826a8cc4c3542eb9a96c383b4c Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Sat, 8 Aug 2015 05:53:10 +0200 Subject: [PATCH] Battery: Handle Linux kernel events The Kernel sends notifications for AC (un)plug and some other important power supply events, so that we can instantly update the widget. Apart from that it sends notifications for any added or removed power supplies, so that the battery support can be reinitialized (useful on systems with removable batteries). --- src/battery/battery.h | 1 + src/battery/linux.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/battery/battery.h b/src/battery/battery.h index 8142760..c39434e 100644 --- a/src/battery/battery.h +++ b/src/battery/battery.h @@ -94,6 +94,7 @@ void default_battery(); // freed memory void cleanup_battery(); +void update_battery_tick(void* arg); int update_battery(); void init_battery(); diff --git a/src/battery/linux.c b/src/battery/linux.c index cf26a44..1897706 100644 --- a/src/battery/linux.c +++ b/src/battery/linux.c @@ -23,6 +23,7 @@ #include "common.h" #include "battery.h" +#include "uevent.h" enum psy_type { PSY_UNKNOWN, @@ -59,6 +60,28 @@ struct psy_mains { gboolean online; }; +static void uevent_battery_update() { + update_battery_tick(NULL); +} +static struct uevent_notify psy_change = { + UEVENT_CHANGE, + "power_supply", + NULL, + uevent_battery_update +}; + +static void uevent_battery_plug() { + printf("reinitialize batteries after HW change\n"); + cleanup_battery(); + init_battery(); +} +static struct uevent_notify psy_plug = { + UEVENT_ADD | UEVENT_REMOVE, + "power_supply", + NULL, + uevent_battery_plug +}; + #define RETURN_ON_ERROR(err) if(error) { g_error_free(err); return FALSE; } static GList *batteries = NULL; @@ -173,6 +196,9 @@ static gboolean init_linux_mains(struct psy_mains *ac) { void battery_os_free() { GList *l = batteries; + uevent_unregister_notifier(&psy_change); + uevent_unregister_notifier(&psy_plug); + while (l != NULL) { GList *next = l->next; struct psy_battery *bat = l->data; @@ -257,6 +283,9 @@ gboolean battery_os_init() { g_dir_close(directory); + uevent_register_notifier(&psy_change); + uevent_register_notifier(&psy_plug); + return batteries != NULL; }