[Pkg-wmaker-commits] [wmbattery] 30/241: added

Doug Torrance dtorrance-guest at moszumanska.debian.org
Mon Aug 24 23:37:25 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch master
in repository wmbattery.

commit f5509c2c82ef86d0f36234dbb4ea96916547244d
Author: joey <joey at a4a2c43b-8ac3-0310-8836-e0e880c912e2>
Date:   Sat Apr 6 04:19:24 2002 +0000

    added
---
 acpi.c   | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 acpi.h   |   7 ++
 sonypi.c |  73 ++++++++++++++++
 3 files changed, 363 insertions(+)

diff --git a/acpi.c b/acpi.c
new file mode 100644
index 0000000..eeac37a
--- /dev/null
+++ b/acpi.c
@@ -0,0 +1,283 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+#include <apm.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "acpi.h"
+
+#define MAXITEM 8
+
+int batt_count = 0;
+/* Filenames of the battery info files for each system battery. */
+char battery_info[MAXITEM][128];
+/* Filenames of the battery status files for each system battery. */
+char battery_status[MAXITEM][128];
+/* Stores battery capacity, or 0 if the battery is absent. */
+int battery_capacity[MAXITEM];
+
+int ac_count = 0;
+char ac_adapter_info[MAXITEM][128];
+char ac_adapter_status[MAXITEM][128];
+
+/* Read in an entire ACPI proc file (well, the first 1024 bytes anyway), and
+ * return a statically allocated array containing it. */
+inline char *get_acpi_file (const char *file) {
+	int fd;
+	int end;
+	static char buf[1024];
+	fd = open(file, O_RDONLY);
+	if (fd == -1) return NULL;
+	end = read(fd, buf, sizeof(buf));
+	buf[end] = '\0';
+	close(fd);
+	return buf;
+}
+
+/* Given a buffer holding an acpi file, searches for the given key in it,
+ * and returns the numeric value. 0 is returned on failure. */
+inline int scan_acpi_num (const char *buf, const char *key) {
+	char *ptr;
+	int ret;
+	if ((ptr = strstr(buf, key))) {
+		if (sscanf(ptr + strlen(key), "%d", &ret) == 1)
+			return ret;
+	}
+	return 0;
+}
+
+/* Given a buffer holding an acpi file, searches for the given key in it,
+ * and returns its value in a statically allocated string. */
+inline char *scan_acpi_value (const char *buf, const char *key) {
+	char *ptr;
+	static char ret[256];
+	if ((ptr = strstr(buf, key))) {
+		if (sscanf(ptr + strlen(key), "%s", ret) == 1)
+			return ret;
+	}
+	return NULL;
+}
+
+/* Read an ACPI proc file, pull out the requested piece of information, and
+ * return it (statically allocated string). Returns NULL on error, This is 
+ * the slow, dumb way, fine for initialization or if only one value is needed
+ * from a file, slow if called many times. */
+char *get_acpi_value (const char *file, const char *key) {
+	char *buf = get_acpi_file(file);
+	return scan_acpi_value(buf, key);
+}
+
+/* Returns the last full capacity of a battery. */
+int get_batt_capacity(int battery) {
+	int cap;
+	cap = atoi(get_acpi_value(battery_info[battery], "Last Full Capacity:"));
+	/* This is ACPI's broken way of saying that there is no battery. */
+	if (cap == 655350)
+		return 0;
+	return cap;
+}
+
+/* Find something (batteries, ac adpaters, etc), and set up a string array
+ * to hold the paths to info and status files of the things found. Must be 
+ * in /proc/acpi to call this. Returns the number of items found. */
+int find_items (char *itemname, char infoarray[MAXITEM][128],
+		                char statusarray[MAXITEM][128]) {
+	DIR *dir;
+	struct dirent *ent;
+	int count = 0;
+	
+	dir = opendir(itemname);
+	if (dir == NULL)
+		return -1;
+
+	while ((ent = readdir(dir))) {
+		if (!strncmp(".", ent->d_name, 1) || 
+		    !strncmp("..", ent->d_name, 2))
+			continue;
+
+		sprintf(infoarray[count], "%s/%s/%s", itemname, ent->d_name, "info");
+		sprintf(statusarray[count], "%s/%s/%s", itemname, ent->d_name, "status");
+		count++;
+		if (count > MAXITEM)
+			break;
+	}
+
+	closedir(dir);
+	return count;
+}
+
+/* Find batteries, return the number, and set batt_count to it as well. */
+int find_batteries(void) {
+	int i;
+	batt_count = find_items("battery", battery_info, battery_status);
+	/* Read in the last charged capacity of the batteries. */
+	for (i = 0; i < batt_count; i++)
+		battery_capacity[i] = get_batt_capacity(i);
+	return batt_count;
+}
+
+/* Find AC power adapters, return the number found, and set ac_count to it
+ * as well. */
+int find_ac_adapters(void) {
+	ac_count = find_items("ac_adapter", ac_adapter_info, ac_adapter_status);
+	return ac_count;
+}
+
+/* Returns true if the system is on ac power. Call find_ac_adapters first. */
+int on_ac_power (void) {
+	int i;
+	for (i = 0; i < ac_count; i++) {
+		if (strcmp("on-line", get_acpi_value(ac_adapter_status[i], "Status:")))
+			return 1;
+		else
+			return 0;
+	}
+	return 0;
+}
+
+/* See if we have ACPI support and check version. Also find batteries and
+ * ac power adapters. */
+int acpi_supported (void) {
+	char *version;
+
+	if (chdir("/proc/acpi") == -1) {
+		perror("chdir /proc/acpi");
+		return 0;
+	}
+	
+	version = get_acpi_value("info", "ACPI-CA Version:");
+	if (version == NULL) {
+		fprintf(stderr, "Unable to find ACPI version.\n");
+		return 0;
+	}
+	if (atoi(version) < ACPI_VERSION) {
+		fprintf(stderr, "ACPI subsystem %s too is old, consider upgrading to %i.\n",
+				version, ACPI_VERSION);
+		return 0;
+	}
+
+	if (! find_batteries()) {
+		fprintf(stderr, "No ACPI batteries found!");
+		return 0;
+	}
+
+	if (! find_ac_adapters()) {
+		fprintf(stderr, "No ACPI power adapter found!");
+	}
+
+	return 1;
+}
+
+/* Read ACPI info on a given power adapter and battery, and fill the passed
+ * apm_info struct. */
+int acpi_read (int battery, apm_info *info) {
+	char *buf, *state;
+	char *rate_s;
+	
+	/* Internally it's zero indexed. */
+	battery--;
+	
+	buf = get_acpi_file(battery_status[battery]);
+
+	info->ac_line_status = 0;
+	info->battery_flags = 0;
+	info->using_minutes = 1;
+	
+	/* Work out if the battery is present, and what percentage of full
+	 * it is and how much time is left. */
+	if (strcmp(scan_acpi_value(buf, "Present:"), "yes") == 0) {
+		int pcap, rate;
+		
+		pcap = scan_acpi_num(buf, "Remaining Capacity:");
+		rate = scan_acpi_num(buf, "Present Rate:");
+
+		if (rate) {
+			/* time remaining = (current_capacity / discharge rate) */
+			info->battery_time = (float) pcap / (float) rate * 60;
+			if (info->battery_time <= 0)
+				info->battery_time = 0;
+		}
+		else {
+			rate_s = scan_acpi_value(buf, "Present Rate:");
+			if (! rate_s) {
+				/* Time remaining unknown. */
+				info->battery_time = 0;
+			}
+			/* This is a hack for my picturebook. If
+			 * the battery is not present, ACPI still
+			 * says it is Present, but sets this to
+			 * unknown. I don't know if this is the
+			 * correct way to do it. */
+			else if (strcmp(rate_s, "unknown") == 0) {
+				goto NOBAT;
+			}
+		}
+
+		if (battery_capacity[battery] == 0) {
+			/* The battery was absent, and now is present.
+			 * Well, it might be a different battery. So
+			 * re-probe the battery. */
+			battery_capacity[battery] = get_batt_capacity(battery);
+		}
+		
+		if (pcap) {
+			/* percentage = (current_capacity / last_full_capacity) * 100 */
+			info->battery_percentage = (float) pcap / (float) battery_capacity[battery] * 100;
+		}
+		else {
+			info->battery_percentage = -1;
+		}
+
+		state = scan_acpi_value(buf, "State:");
+		if (state) {
+			if (state[0] == 'd') { /* discharging */
+				info->battery_status = BATTERY_STATUS_CHARGING;
+			}
+			else if (state[0] == 'c' && state[1] == 'h') { /* charging */
+				info->battery_status = BATTERY_STATUS_CHARGING;
+				info->ac_line_status = 1;
+				info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING;
+
+				/*   */
+				info->battery_time = -1 * (float) (battery_capacity[battery] - pcap) / (float) rate * 60;
+			}
+			else if (state[0] == 'o') { /* ok */
+				/* charged, on ac power */
+				info->battery_status = BATTERY_STATUS_HIGH;
+				info->ac_line_status = 1;
+			}
+			else if (state[0] == 'c') { /* not charging, so must be critical */
+				info->battery_status = BATTERY_STATUS_CRITICAL;
+			}
+			else
+				fprintf(stderr, "unknown battery state: %s\n", state);
+		}
+		else {
+			/* Battery state unknown. */
+			info->battery_status = BATTERY_STATUS_ABSENT;
+		}
+	}
+	else {
+NOBAT:
+		/* No battery. */
+		info->battery_percentage = 0;
+		info->battery_time = 0;
+		info->battery_status = BATTERY_STATUS_ABSENT;
+		battery_capacity[battery] = 0;
+		if (batt_count == 1) {
+			/* Where else would the power come from, eh? ;-) */
+			info->ac_line_status = 1;
+		}
+		else {
+			/* Expensive ac power check. */
+			info->ac_line_status = on_ac_power();
+		}
+	}
+	
+	return 0;
+}
diff --git a/acpi.h b/acpi.h
new file mode 100644
index 0000000..2996f9e
--- /dev/null
+++ b/acpi.h
@@ -0,0 +1,7 @@
+int acpi_supported (void);
+int acpi_read (int battery, apm_info *info);
+extern int batt_count;
+
+/* The lowest version of ACPI proc files supported. */
+#define ACPI_VERSION 20011018
+
diff --git a/sonypi.c b/sonypi.c
new file mode 100644
index 0000000..b4f658d
--- /dev/null
+++ b/sonypi.c
@@ -0,0 +1,73 @@
+#include <sys/ioctl.h>
+#include <apm.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "sonypi.h"
+
+signed int spicfd = -1;
+
+int sonypi_supported (void) {
+	if ((spicfd = open("/dev/sonypi", O_RDWR)) == -1)
+		return 0;
+	else
+		return 1;
+}
+
+inline int sonypi_ioctl(int ioctlno, void *param) {
+	if (ioctl(spicfd, ioctlno, param) < 0)
+		return 0;
+	else
+		return 1;
+}
+
+/* Read battery info from sonypi device and shove it into an apm_info
+ * struct. */
+int sonypi_read (apm_info *info) {
+	__u8 batflags;
+	__u16 cap, rem;
+	int havebatt = 0;
+	
+	info->using_minutes = info->battery_flags = 0;
+	
+	if (! sonypi_ioctl(SONYPI_IOCGBATFLAGS, &batflags)) {
+		return 1;
+	}
+
+	info->ac_line_status = (batflags & SONYPI_BFLAGS_AC) != 0;
+	if (batflags & SONYPI_BFLAGS_B1) {
+		if (! sonypi_ioctl(SONYPI_IOCGBAT1CAP, &cap))
+			return 1;
+		if (! sonypi_ioctl(SONYPI_IOCGBAT1REM, &rem))
+			return 1;
+		havebatt = 1;
+	}
+	else if (batflags & SONYPI_BFLAGS_B2) {
+		/* Not quite right, if there is a second battery I should
+		 * probably merge the two somehow.. */
+		if (! sonypi_ioctl(SONYPI_IOCGBAT2CAP, &cap))
+			return 1;
+		if (! sonypi_ioctl(SONYPI_IOCGBAT2REM, &rem))
+			return 1;
+		havebatt = 1;
+	}
+	else {
+		info->battery_percentage = 0;
+		info->battery_status = BATTERY_STATUS_ABSENT;
+	}
+	
+	if (havebatt) {
+		info->battery_percentage = 100 * rem / cap;
+		/* Guess at whether the battery is charging. */
+		if (info->battery_percentage < 99 && info->ac_line_status == 1) {
+			info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING;
+			info->battery_status = BATTERY_STATUS_CHARGING;
+		}
+	}
+	
+	/* Sadly, there is no way to estimate this. */
+	info->battery_time = 0;
+	
+	return 0;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-wmaker/wmbattery.git



More information about the Pkg-wmaker-commits mailing list