diff mbox series

[v7,matchbox-panel-2] panel: added sysfs support

Message ID 20250910054700.76888-1-dixitparmar19@gmail.com
State New
Headers show
Series [v7,matchbox-panel-2] panel: added sysfs support | expand

Commit Message

Dixit Parmar Sept. 10, 2025, 5:46 a.m. UTC
battery applet supports reading battery and supply
information from sysfs entries, /sys/class/power_supply/.

[YOCTO #12904]
https://bugzilla.yoctoproject.org/show_bug.cgi?id=12904

Signed-off-by: Dixit Parmar <dixitparmar19@gmail.com>
---
V6: https://lists.yoctoproject.org/g/yocto-patches/message/2145
---
 applets/battery/Makefile.am     |   4 +
 applets/battery/battery-acpi.c  |   2 +
 applets/battery/battery-apm.c   |   2 +
 applets/battery/battery-sysfs.c | 143 ++++++++++++++++++++++++++++++++
 applets/battery/battery.c       |   2 +
 applets/battery/battery.h       |   3 +-
 configure.ac                    |   4 +
 7 files changed, 158 insertions(+), 2 deletions(-)
 create mode 100644 applets/battery/battery-sysfs.c
diff mbox series

Patch

diff --git a/applets/battery/Makefile.am b/applets/battery/Makefile.am
index 9b02240..1b93a0b 100644
--- a/applets/battery/Makefile.am
+++ b/applets/battery/Makefile.am
@@ -5,6 +5,10 @@  applet_LTLIBRARIES = libbattery.la
 libbattery_la_SOURCES = battery.c battery.h
 libbattery_la_CPPFLAGS = $(AM_CPPFLAGS) -DDATADIR=\"$(pkgdatadir)/battery/\"
 
+if HAVE_SYSFS
+libbattery_la_SOURCES += battery-sysfs.c
+endif
+
 if HAVE_LIBAPM
 libbattery_la_LIBADD = -lapm
 libbattery_la_SOURCES += battery-apm.c
diff --git a/applets/battery/battery-acpi.c b/applets/battery/battery-acpi.c
index d1d3de9..42ef9c8 100644
--- a/applets/battery/battery-acpi.c
+++ b/applets/battery/battery-acpi.c
@@ -14,6 +14,8 @@  global_t global;
 adapter_t *ac;
 int batt_state, ac_state;
 
+void pm_cleanup(void) { }
+
 int pm_support(void)
 {
 	if(check_acpi_support() == NOT_SUPPORTED){
diff --git a/applets/battery/battery-apm.c b/applets/battery/battery-apm.c
index edaba43..f1501a0 100644
--- a/applets/battery/battery-apm.c
+++ b/applets/battery/battery-apm.c
@@ -9,6 +9,8 @@ 
 #include "battery.h"
 #include <apm.h>
 
+void pm_cleanup(void) { }
+
 int pm_support(void)
 {
 	if (1 == apm_exists ()) {
diff --git a/applets/battery/battery-sysfs.c b/applets/battery/battery-sysfs.c
new file mode 100644
index 0000000..ec1d179
--- /dev/null
+++ b/applets/battery/battery-sysfs.c
@@ -0,0 +1,143 @@ 
+/*
+ * (C) Dixit Parmar
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Licensed under the GPL v2 or greater.
+ */
+
+#include "battery.h"
+#include <glib.h>
+
+#define PROCFS_PS_DIR "/sys/class/power_supply"
+
+static gchar *batt_dev;
+static gchar *ac_dev;
+static gboolean batt_exist = FALSE;
+static gboolean ac_exist = FALSE;
+
+void pm_cleanup(void)
+{
+        g_free(batt_dev);
+        g_free(ac_dev);
+}
+
+int pm_support(void)
+{
+        GDir *dir = g_dir_open(PROCFS_PS_DIR, 0, NULL);
+        if (dir != NULL) {
+                const gchar *subdir_name;
+                while ((subdir_name = g_dir_read_name(dir)) != NULL) {
+                        gchar *subdir_path = g_build_filename(PROCFS_PS_DIR, subdir_name, NULL);
+                        // Check if it's a directory
+                        if (g_file_test(subdir_path, G_FILE_TEST_IS_DIR)) {
+                                gchar *type_file_path = g_build_filename(subdir_path, "type", NULL);
+                                // Check if the "type" file exists
+                                if (g_file_test(type_file_path, G_FILE_TEST_EXISTS)) {
+                                        gchar *file_content = NULL;
+                                        gsize length;
+
+                                        if (g_file_get_contents(type_file_path, &file_content, &length, NULL)) {
+                                                file_content = g_strchomp(file_content);
+                                                if(!batt_exist && g_strcmp0(file_content, "Battery") == 0) {
+                                                        batt_dev = g_strdup(subdir_name);
+                                                        batt_exist = TRUE;
+                                                }
+                                                if(!ac_exist && g_strcmp0(file_content, "Mains") == 0) {
+                                                        ac_dev = g_strdup(subdir_name);
+                                                        ac_exist = TRUE;
+                                                }
+                                                g_free(file_content);
+                                        }
+                                }
+                                g_free(type_file_path);
+                        }
+                        g_free(subdir_path);
+                        if(batt_exist && ac_exist)
+                                break;
+                }
+                g_dir_close(dir);
+        }
+        return (int)batt_exist;
+}
+
+static gboolean read_val_from_file(const gchar *dev, const gchar *f, gint64 *val)
+{
+        gboolean ret = FALSE;
+
+        if(dev != NULL && f != NULL && val != NULL) {
+                gchar *file_path = g_build_filename(PROCFS_PS_DIR, dev, f, NULL);
+                gchar *file_content;
+                gsize length;
+
+                if(g_file_get_contents(file_path, &file_content, &length, NULL)) {
+                       *val = g_ascii_strtoll(file_content, NULL, 10);
+                        ret = TRUE;
+                }
+
+                g_free(file_content);
+                g_free(file_path);
+        }
+        return ret;
+}
+
+const char* pm_battery_icon(void)
+{
+        const char *icon;
+        gint64 temp_val = 0;
+        gint64 ac_status = 0;
+        gint64 batt_present = 0;
+        gint64 batt_percentage = 0;
+
+        if(batt_exist == FALSE)
+                return NULL;
+
+        /* Check battery presence */
+        if(read_val_from_file(batt_dev, "present", &temp_val))
+                batt_present = temp_val;
+
+        if(batt_present == 0) {
+                /* Battery is removed */
+                icon = "ac-adapter.png";
+                return icon;
+        }
+
+        /* Check Adaptor status*/
+        if(ac_exist && read_val_from_file(ac_dev, "online", &temp_val))
+                ac_status = temp_val;
+
+        /* Check battery percentage */
+        if(read_val_from_file(batt_dev, "capacity", &temp_val))
+                batt_percentage = temp_val;
+
+        if(ac_status == 1) {
+                /* We're charging */
+                if (batt_percentage < 10)
+                        icon = "battery-charging-000.png";
+                else if (batt_percentage < 30)
+                        icon = "battery-charging-020.png";
+                else if (batt_percentage < 50)
+                        icon = "battery-charging-040.png";
+                else if (batt_percentage < 70)
+                        icon = "battery-charging-060.png";
+                else if (batt_percentage < 90)
+                        icon = "battery-charging-080.png";
+                else
+                        icon = "battery-charging-100.png";
+        } else {
+                if (batt_percentage < 10)
+                        icon = "battery-discharging-000.png";
+                else if (batt_percentage < 30)
+                        icon = "battery-discharging-020.png";
+                else if (batt_percentage < 50)
+                        icon = "battery-discharging-040.png";
+                else if (batt_percentage < 70)
+                        icon = "battery-discharging-060.png";
+                else if (batt_percentage < 90)
+                        icon = "battery-discharging-080.png";
+                else
+                        icon = "battery-discharging-100.png";
+        }
+
+        return icon;
+}
diff --git a/applets/battery/battery.c b/applets/battery/battery.c
index b11517d..755042b 100644
--- a/applets/battery/battery.c
+++ b/applets/battery/battery.c
@@ -24,6 +24,8 @@  battery_applet_free (BatteryApplet *applet)
         g_source_remove (applet->timeout_id);
 
         g_slice_free (BatteryApplet, applet);
+
+        pm_cleanup ();
 }
 
 static gboolean
diff --git a/applets/battery/battery.h b/applets/battery/battery.h
index 534988f..7c54a3a 100644
--- a/applets/battery/battery.h
+++ b/applets/battery/battery.h
@@ -9,8 +9,7 @@ 
 #ifndef MB_APPLET_BATTERY_H
 #define MB_APPLET_BATTERY_H
 
-#include <string.h>
-
+void pm_cleanup(void);
 int pm_support(void);
 const char* pm_battery_icon(void);
 
diff --git a/configure.ac b/configure.ac
index be4d591..0f607f8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -61,6 +61,9 @@  AC_ARG_WITH(
 )
 
 case "$with_battery" in
+     "sysfs") enable_linux_sysfs=yes
+     enable_battery=yes
+     ;;
      "acpi") AC_CHECK_HEADERS(libacpi.h, enable_linux_acpi=yes, AC_MSG_FAILURE([You need to install libacpi]))
      enable_battery=yes
      ;;
@@ -75,6 +78,7 @@  esac
 AM_CONDITIONAL(HAVE_BATTERY, test x$enable_battery = xyes)
 AM_CONDITIONAL(HAVE_LIBAPM, test x$enable_linux_apm = xyes)
 AM_CONDITIONAL(HAVE_LIBACPI, test x$enable_linux_acpi = xyes)
+AM_CONDITIONAL(HAVE_SYSFS, test x$enable_linux_sysfs = xyes)
 
 # glib-genmarshal
 GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0`