Subject: APM battery_state considered useless
To: None <port-i386@netbsd.org>
From: Johan Danielsson <joda@pdc.kth.se>
List: port-i386
Date: 01/13/2003 10:33:58
APM 1.0 returned the battery state as a number indicating high, low,
charging etc. In APM 1.1 this was changes to a bitfield, so batteries
could be both low and charging. Unfortunately the APM_IOC_GETPOWER
ioctl emulates APM 1.0 on 1.1 machines, which is not very practical
for some applications. Furthermore it returns the least interesting
flag bits (if both charging and low are set, it will return low).

Two possible solutions, add a new ioctl that makes battery_state more
1.1-like, or add a new field with 1.1-like information. Here's a patch
for the latter. Better name suggestions are appreciated.

/Johan

--- apmio.h	2002/10/14 02:08:40	1.1
+++ apmio.h	2003/01/13 09:15:25
@@ -47,7 +47,7 @@
 	u_char battery_state;
 	u_char ac_state;
 	u_char battery_life;
-	u_char spare1;
+	u_char battery_state2;
 	u_int minutes_left;		/* estimate */
 	u_int nbattery;		
 	u_int batteryid;
--- apm.c	2002/11/26 19:50:24	1.75
+++ apm.c	2003/01/13 09:18:11
@@ -1768,19 +1768,32 @@
 		powerp->ac_state = APM_AC_STATE(&regs);
 		switch (apm_minver) {
 		case 0:
+			powerp->battery_state2 = 0;
+			if(APM_BATT_STATE(&regs) == APM_BATT_HIGH)
+				powerp->battery_state2 |= APM_BATT_FLAG_HIGH;
+			else if(APM_BATT_STATE(&regs) == APM_BATT_LOW)
+				powerp->battery_state2 |= APM_BATT_FLAG_LOW;
+			else if(APM_BATT_STATE(&regs) == APM_BATT_CRITICAL)
+				powerp->battery_state2 |= APM_BATT_FLAG_CRITICAL;
+			else if(APM_BATT_STATE(&regs) == APM_BATT_CHARGING)
+				powerp->battery_state2 |= APM_BATT_FLAG_CHARGING;
+			else if(APM_BATT_STATE(&regs) == APM_BATT_UNKNOWN)
+			    powerp->battery_state2 |= APM_BATT_FLAG_UNKNOWN;
+			    
 			powerp->battery_state = APM_BATT_STATE(&regs);
 			break;
 		case 1:
 		default:
+			powerp->battery_state2 = APM_BATT_FLAGS(&regs);
 			powerp->battery_state = APM_BATT_UNKNOWN;
-			if (APM_BATT_FLAGS(&regs) & APM_BATT_FLAG_HIGH)
-				powerp->battery_state = APM_BATT_HIGH;
-			else if (APM_BATT_FLAGS(&regs) & APM_BATT_FLAG_LOW)
-				powerp->battery_state = APM_BATT_LOW;
+			if (APM_BATT_FLAGS(&regs) & APM_BATT_FLAG_CHARGING)
+				powerp->battery_state = APM_BATT_CHARGING;
 			else if (APM_BATT_FLAGS(&regs) & APM_BATT_FLAG_CRITICAL)
 				powerp->battery_state = APM_BATT_CRITICAL;
-			else if (APM_BATT_FLAGS(&regs) & APM_BATT_FLAG_CHARGING)
-				powerp->battery_state = APM_BATT_CHARGING;
+			else if (APM_BATT_FLAGS(&regs) & APM_BATT_FLAG_LOW)
+				powerp->battery_state = APM_BATT_LOW;
+			else if (APM_BATT_FLAGS(&regs) & APM_BATT_FLAG_HIGH)
+				powerp->battery_state = APM_BATT_HIGH;
 			else if (APM_BATT_FLAGS(&regs) & APM_BATT_FLAG_NO_SYSTEM_BATTERY)
 				powerp->battery_state = APM_BATT_ABSENT;
 			if (APM_BATT_REM_VALID(&regs))