diff mbox series

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

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

Commit Message

Dixit Parmar Oct. 24, 2024, 11:09 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>
---
 applets/battery/Makefile.am     |   4 +
 applets/battery/battery-sysfs.c | 155 ++++++++++++++++++++++++++++++++
 applets/battery/battery.h       |   5 +-
 configure.ac                    |   4 +
 4 files changed, 167 insertions(+), 1 deletion(-)
 create mode 100644 applets/battery/battery-sysfs.c

Comments

Ross Burton Nov. 4, 2024, 10:45 a.m. UTC | #1
On 24 Oct 2024, at 12:09, Dixit Parmar via lists.yoctoproject.org <dixitparmar19=gmail.com@lists.yoctoproject.org> wrote:
> battery applet supports reading battery and supply
> information from sysfs entries, /sys/class/power_supply/.

First, many thanks for this, it’s been on my todo list for far too long! However, some comments to make the code more idiomatically glib.

> +int read_file_content(const char *file_path, char *buff, size_t len)

Instead of reinventing the wheel, just use g_file_get_contents() (https://docs.gtk.org/glib/func.file_get_contents.html).

> + snprintf(file_path, sizeof(file_path), "%s/%s/%s", PROCFS_PS_DIR, dev, f);

GLib also provides g_build_filename().

> + dir = opendir(PROCFS_PS_DIR);

And g_dir_open().

> + ac_sts = atoi(buff);

As presumably the files in sysfs are defined as being ASCII digits, it’s probably safer to use g_ascii_strtoll() from glib.  The standard C conversion functions are locale sensitive which can cause “interesting” behaviour when parsing.

Thanks Dixit!

Ross
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Dixit Parmar Nov. 7, 2024, 4:20 p.m. UTC | #2
Thank you for taking out time reviewing this and sharing your feedback. I have covered all your suggestions in v4 patchset and shared. Kindly review.
~Dixit
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-sysfs.c b/applets/battery/battery-sysfs.c
new file mode 100644
index 0000000..7a416ea
--- /dev/null
+++ b/applets/battery/battery-sysfs.c
@@ -0,0 +1,155 @@ 
+/*
+ * (C) Dixit Parmar
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Licensed under the GPL v2 or greater.
+ */
+
+#include "battery.h"
+
+#define PROCFS_PS_DIR "/sys/class/power_supply"
+
+static char batt_dev[128] = "";
+static char ac_dev[128] = "";
+static char batt_exist = 0;
+static char ac_exist = 0;
+
+int read_file_content(const char *file_path, char *buff, size_t len)
+{
+	FILE *fd = NULL;
+	int ret = 0;
+
+	fd = fopen(file_path, "r");
+	char *line = NULL;
+	if(fd != NULL)
+	{
+		ret = getline(&line, &len, fd);
+		if(ret > 0)
+		{
+			memcpy(buff, line, ret);
+		}
+		free(line);
+		fclose(fd);
+	}
+	return ret;
+}
+
+int read_file(const char *dev, const char *f, char *buff, size_t len)
+{
+	char file_path[256] = "";
+	printf("%s/%s\n", dev, f);
+
+	if(dev != NULL && f != NULL && buff != NULL)
+	{
+		memset(buff, 0, len);
+		snprintf(file_path, sizeof(file_path), "%s/%s/%s", PROCFS_PS_DIR, dev, f);
+		return read_file_content(file_path, buff, len);
+	}
+	return -1;
+}
+
+int pm_support(void)
+{
+	DIR *dir;
+	struct dirent *in_file;
+	dir = opendir(PROCFS_PS_DIR);
+	char buff[128];
+	int ret;
+
+	if(dir != NULL)
+	{
+		while(in_file = readdir(dir))
+		{
+			if(in_file->d_name[0] == '.') /* Skip . & .. directory */
+				continue;
+			if(in_file->d_type == DT_DIR || in_file->d_type == DT_LNK)
+			{
+				ret = read_file(in_file->d_name, "type", buff, sizeof(buff));
+				if(ret > 0)
+				{
+					if(!batt_exist && strncmp(buff, "Battery", strlen("Battery")) == 0)
+					{
+						strncpy(batt_dev, in_file->d_name, strlen(in_file->d_name));
+						batt_exist = 1;
+					}
+					if(!ac_exist && strncmp(buff, "Mains", strlen("Mains")) == 0)
+					{
+						strncpy(ac_dev, in_file->d_name, strlen(in_file->d_name));
+						ac_exist = 1;
+					}
+				}
+			}
+			if(batt_exist && ac_exist)
+				break;
+		}
+	}
+	return (int)batt_exist;
+}
+
+const char* pm_battery_icon(void)
+{
+	const char *icon;
+	char buff[128] = "";
+	int ret = 0;
+	int ac_sts = 0;
+	int batt_present = 0;
+	int batt_percentage = 0;
+
+	if(batt_exist == 0)
+		return NULL;
+
+	/* Check battery presence */
+	ret = read_file(batt_dev, "present", buff, sizeof(buff));
+	if(ret > 0)
+		batt_present = atoi(buff);
+	if(batt_present == 0)
+	{
+		/* Battery is removed */
+		icon = "ac-adapter.png";
+		return icon;
+	}
+
+	/* Check Adaptor status*/
+	ret = read_file(ac_dev, "online", buff, sizeof(buff));
+	if(ret > 0)
+		ac_sts = atoi(buff);
+
+	/* Check battery percentage */
+	ret = read_file(batt_dev, "capacity", buff, sizeof(buff));
+	if(ret > 0)
+		batt_percentage = atoi(buff);
+
+	if(ac_exist && ac_sts == 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.h b/applets/battery/battery.h
index cf23431..5c60744 100644
--- a/applets/battery/battery.h
+++ b/applets/battery/battery.h
@@ -6,8 +6,11 @@ 
 
 #ifndef MB_APPLET_BATTERY_H
 #define MB_APPLET_BATTERY_H
-
+#include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
 
 int pm_support(void);
 const char* pm_battery_icon(void);
diff --git a/configure.ac b/configure.ac
index d6c57d8..7038212 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`