Subject: diffs to handle ACPI in pkgsrc/sysutils/xbattbar
To: None <tech-pkg@NetBSD.org>
From: Alistair Crooks <agc@pkgsrc.org>
List: tech-pkg
Date: 10/17/2003 17:31:52
--+HP7ph2BbKc20aGI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

These are some VERY crude hacks to allow xbattbar to use APM if it 
exists, and then to fall back to ACPI if it is there. They work just
fine on my Vaio, but, before I commit them, I'd like to know that
they work (a) on existing APM machines, and (b) on ACPI-based
machines.

I'm well aware that these are not neat.

All other feedback gratefully received.

Regards,
Alistair
--
Alistair Crooks <agc@pkgsrc.org>

--+HP7ph2BbKc20aGI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="xbattbar.diff"

Index: Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/sysutils/xbattbar/Makefile,v
retrieving revision 1.18
diff -u -r1.18 Makefile
--- Makefile	17 Jul 2003 22:53:58 -0000	1.18
+++ Makefile	17 Oct 2003 15:24:18 -0000
@@ -2,7 +2,7 @@
 
 DISTNAME=	xbattbar_1.4.2
 PKGNAME=	${DISTNAME:S/_/-/}
-PKGREVISION=	2
+PKGREVISION=	3
 WRKSRC=		${WRKDIR}/${DISTNAME:S/_/-/}
 CATEGORIES=	sysutils x11
 MASTER_SITES=	http://iplab.aist-nara.ac.jp/member/suguru/
Index: distinfo
===================================================================
RCS file: /cvsroot/pkgsrc/sysutils/xbattbar/distinfo,v
retrieving revision 1.4
diff -u -r1.4 distinfo
--- distinfo	26 Nov 2001 20:07:34 -0000	1.4
+++ distinfo	17 Oct 2003 15:24:18 -0000
@@ -3,4 +3,4 @@
 SHA1 (xbattbar_1.4.2.tar.gz) = 14e9aafd62919e4a625d3f84df3b074b9eef8279
 Size (xbattbar_1.4.2.tar.gz) = 14079 bytes
 SHA1 (patch-aa) = 3bd4b688ccaeebe766335245c1a8c5dde52768c2
-SHA1 (patch-ab) = 1552e04203d2ad229c603f05d6a69766de5353cf
+SHA1 (patch-ab) = bdbff422f5f673fabc1fb74625af5fd2c760e137
Index: patches/patch-ab
===================================================================
RCS file: /cvsroot/pkgsrc/sysutils/xbattbar/patches/patch-ab,v
retrieving revision 1.1
diff -u -r1.1 patch-ab
--- patches/patch-ab	26 Nov 2001 20:07:35 -0000	1.1
+++ patches/patch-ab	17 Oct 2003 15:24:18 -0000
@@ -1,12 +1,199 @@
 $NetBSD: patch-ab,v 1.1 2001/11/26 20:07:35 wiz Exp $
 
---- xbattbar.c.orig	Fri Feb  2 06:25:29 2001
-+++ xbattbar.c
-@@ -594,6 +594,7 @@
+--- xbattbar.c.orig	2001-02-02 05:25:29.000000000 +0000
++++ xbattbar.c	2003-10-17 13:15:51.000000000 +0100
+@@ -27,6 +27,13 @@
+ 
+ #include <sys/types.h>
+ #include <sys/time.h>
++
++#ifdef __NetBSD__
++#define ENVSYSUNITNAMES
++#include <sys/envsys.h>
++#include <paths.h>
++#endif /* __NetBSD__ */
++
+ #include <signal.h>
+ #include <stdio.h>
+ #include <unistd.h>
+@@ -583,46 +590,158 @@
+ #define _PATH_APM_CTLDEV       "/dev/apmctl"
+ #define _PATH_APM_NORMAL       "/dev/apm"
+ 
++/*
++ * pre:  fd contains a valid file descriptor of an envsys(4) supporting device
++ *       && ns is the number of sensors
++ *       && etds and ebis are arrays of sufficient size
++ * post: returns 0 and etds and ebis arrays are filled with sensor info
++ *       or returns -1 on failure
++ */
++static int
++fillsensors(int fd, envsys_tre_data_t *etds, envsys_basic_info_t *ebis,
++    size_t ns)
++{
++	int i;
++
++	for (i = 0; i < ns; ++i) {
++		ebis[i].sensor = i;
++		if (ioctl(fd, ENVSYS_GTREINFO, &ebis[i]) == -1) {
++			warn("Can't get sensor info for sensor %d", i);
++			return 0;
++		}
++
++		etds[i].sensor = i;
++		if (ioctl(fd, ENVSYS_GTREDATA, &etds[i]) == -1) {
++			warn("Can't get sensor data for sensor %d", i);
++			return 0;
++		}
++	}
++	return 1;
++}
++
++/*
++ * pre:  fd contains a valid file descriptor of an envsys(4) supporting device
++ * post: returns the number of valid sensors provided by the device
++ *       or -1 on error
++ */
++static size_t
++numsensors(int fd)
++{
++	int count = 0, valid = 1;
++	envsys_tre_data_t etd;
++	etd.sensor = 0;
++
++	while (valid) {
++		if (ioctl(fd, ENVSYS_GTREDATA, &etd) == -1)
++			err(1, "Can't get sensor data");
++
++		valid = etd.validflags & ENVSYS_FVALID;
++		if (valid)
++			++count;
++
++		++etd.sensor;
++	}
++
++	return count;
++}
++
++static envsys_tre_data_t *etds;
++static envsys_basic_info_t *ebis;
++static int *cetds;
++
+ int first = 1;
+ void battery_check(void)
+ {
+        int fd, r, p;
+        struct apm_power_info info;
++       int acpi;
++       size_t ns;
++       size_t cc;
++       int i;
+ 
++       acpi = 0;
+        if ((fd = open(_PATH_APM_NORMAL, O_RDONLY)) == -1) {
+-               fprintf(stderr, "xbattbar: cannot open apm device\n");
++	       fd = open(_PATH_SYSMON, O_RDONLY);
++	       acpi = 1;
++       }
++       if (fd < 0) {
++               fprintf(stderr, "xbattbar: cannot open %s device\n", (acpi) ? _PATH_SYSMON : _PATH_APM_NORMAL);
                 exit(1);
         }
  
-+       memset(&info, 0, sizeof(info));
-        if (ioctl(fd, APM_IOC_GETPOWER, &info) != 0) {
-                fprintf(stderr, "xbattbar: ioctl APM_IOC_GETPOWER failed\n");
-                exit(1);
+-       if (ioctl(fd, APM_IOC_GETPOWER, &info) != 0) {
+-               fprintf(stderr, "xbattbar: ioctl APM_IOC_GETPOWER failed\n");
+-               exit(1);
++       if (acpi) {
++		if ((ns = numsensors(fd)) == 0) {
++		       fprintf(stderr, "xbattbar: no sensors found\n");
++		       exit(1);
++		}
++		if (first) {
++			cetds = (int *)malloc(ns * sizeof(int));
++			etds = (envsys_tre_data_t *)malloc(ns * sizeof(envsys_tre_data_t));
++			ebis = (envsys_basic_info_t *)malloc(ns * sizeof(envsys_basic_info_t));
++
++			if ((cetds == NULL) || (etds == NULL) || (ebis == NULL)) {
++				err(1, "Out of memory");
++			}
++		}
++
++		fillsensors(fd, etds, ebis, ns);
++
++       } else {
++
++	       memset(&info, 0, sizeof(info));
++	       if (ioctl(fd, APM_IOC_GETPOWER, &info) != 0) {
++		       fprintf(stderr, "xbattbar: ioctl APM_IOC_GETPOWER failed\n");
++		       exit(1);
++	       }
+        }
+ 
+        close(fd);
+ 
+        ++elapsed_time;
+ 
+-       /* get current remoain */
+-       if (info.battery_life > 100) {
+-               /* some APM BIOSes return values slightly > 100 */
+-               r = 100;
+-       } else {
+-               r = info.battery_life;
+-       }
++       if (acpi) {
++		r = 0;
++		p = APM_AC_ON;
++		for (i = 0 ; i < ns ; i++) {
++			cc = strlen(ebis[i].desc);
++			if (strcmp(&ebis[i].desc[cc - 6], "energy") == 0) {
++				r = (etds[i].cur.data_s * 100.0) / etds[i].max.data_s;
++			}
++			if (ebis[i].units == ENVSYS_INDICATOR &&
++			    etds[i].cur.data_s &&
++			    strcmp(&ebis[i].desc[cc - 11], "discharging") == 0) {
++				p = APM_AC_OFF;
++			}
++		}
++	       if (first || ac_line != p || battery_level != r) {
++		       first = 0;
++		       ac_line = p;
++		       battery_level = r;
++		       redraw();
++	       }
+ 
+-       /* get AC-line status */
+-       if (info.ac_state == APM_AC_ON) {
+-               p = APM_AC_ON;
+        } else {
+-               p = APM_AC_OFF;
+-       }
+-
+-       if (first || ac_line != p || battery_level != r) {
+-               first = 0;
+-               ac_line = p;
+-               battery_level = r;
+-               redraw();
++	       /* get current remain */
++	       if (info.battery_life > 100) {
++		       /* some APM BIOSes return values slightly > 100 */
++		       r = 100;
++	       } else {
++		       r = info.battery_life;
++	       }
++
++	       /* get AC-line status */
++	       if (info.ac_state == APM_AC_ON) {
++		       p = APM_AC_ON;
++	       } else {
++		       p = APM_AC_OFF;
++	       }
++
++	       if (first || ac_line != p || battery_level != r) {
++		       first = 0;
++		       ac_line = p;
++		       battery_level = r;
++		       redraw();
++	       }
+        }
+ }
+ 

--+HP7ph2BbKc20aGI--