--- apmlib.c.orig	Sat Apr 12 19:37:14 2003
+++ apmlib.c	Sat Apr 12 19:25:01 2003
@@ -50,12 +50,13 @@
 /* Read information from /proc/apm.  Return 0 on success, 1 if APM not
  * installed, 2 if APM installed, but old version. 
  */
-int apm_read(apm_info * i)
+int apm_read(apm_info * info)
 {
     FILE *str;
     char units[10];
     char buffer[100];
     int retcode = 0;
+    int	num_bat, bat, tmp;
 
     if (!(str = fopen(APM_PROC, "r")))
 	return 1;
@@ -66,71 +67,71 @@
      * others) uses this format, which doesn't expose # batteries.
      */
     sscanf(buffer, "%s %d.%d %x %x %x %x %d%% %d %s\n",
-	   (char *) i->driver_version,
-	   &i->apm_version_major,
-	   &i->apm_version_minor,
-	   &i->apm_flags,
-	   &i->ac_line_status,
-	   &i->battery_status,
-	   &i->battery_flags,
-	   &i->battery_percentage,
-	   &i->battery_time,
+	   (char *) info->driver_version,
+	   &info->apm_version_major,
+	   &info->apm_version_minor,
+	   &info->apm_flags,
+	   &info->ac_line_status,
+	   &info->battery_status,
+	   &info->battery_flags,
+	   &info->battery_percentage,
+	   &info->battery_time,
 	   units);
-    i->using_minutes = !strncmp(units, "min", 3) ? 1 : 0;
-    if (i->driver_version[0] == 'B')
+    info->using_minutes = !strncmp(units, "min", 3) ? 1 : 0;
+    if (info->driver_version[0] == 'B')
     {				/* old style.  argh. */
 #if !BACKWARD_COMPAT
 	retcode = 2;
 #else
-	strcpy((char *) i->driver_version, "pre-0.7");
-	i->apm_version_major = 0;
-	i->apm_version_minor = 0;
-	i->apm_flags = 0;
-	i->ac_line_status = 0xff;
-	i->battery_status = 0xff;
-	i->battery_flags = 0xff;
-	i->battery_percentage = -1;
-	i->battery_time = -1;
-	i->using_minutes = 1;
+	strcpy((char *) info->driver_version, "pre-0.7");
+	info->apm_version_major = 0;
+	info->apm_version_minor = 0;
+	info->apm_flags = 0;
+	info->ac_line_status = 0xff;
+	info->battery_status = 0xff;
+	info->battery_flags = 0xff;
+	info->battery_percentage = -1;
+	info->battery_time = -1;
+	info->using_minutes = 1;
 
 	sscanf(buffer, "BIOS version: %d.%d",
-	       &i->apm_version_major, &i->apm_version_minor);
+	       &info->apm_version_major, &info->apm_version_minor);
 	fgets(buffer, sizeof(buffer) - 1, str);
-	sscanf(buffer, "Flags: 0x%02x", &i->apm_flags);
-	if (i->apm_flags & APM_32_BIT_SUPPORT)
+	sscanf(buffer, "Flags: 0x%02x", &info->apm_flags);
+	if (info->apm_flags & APM_32_BIT_SUPPORT)
 	{
 	    fgets(buffer, sizeof(buffer) - 1, str);
 	    fgets(buffer, sizeof(buffer) - 1, str);
 	    if (buffer[0] != 'P')
 	    {
 		if (!strncmp(buffer + 4, "off line", 8))
-		    i->ac_line_status = 0;
+		    info->ac_line_status = 0;
 		else if (!strncmp(buffer + 4, "on line", 7))
-		    i->ac_line_status = 1;
+		    info->ac_line_status = 1;
 		else if (!strncmp(buffer + 4, "on back", 7))
-		    i->ac_line_status = 2;
+		    info->ac_line_status = 2;
 
 		fgets(buffer, sizeof(buffer) - 1, str);
 		if (!strncmp(buffer + 16, "high", 4))
-		    i->battery_status = 0;
+		    info->battery_status = 0;
 		else if (!strncmp(buffer + 16, "low", 3))
-		    i->battery_status = 1;
+		    info->battery_status = 1;
 		else if (!strncmp(buffer + 16, "crit", 4))
-		    i->battery_status = 2;
+		    info->battery_status = 2;
 		else if (!strncmp(buffer + 16, "charg", 5))
-		    i->battery_status = 3;
+		    info->battery_status = 3;
 
 		fgets(buffer, sizeof(buffer) - 1, str);
 		if (strncmp(buffer + 14, "unknown", 7))
-		    i->battery_percentage = atoi(buffer + 14);
-		if (i->apm_version_major >= 1 && i->apm_version_minor >= 1)
+		    info->battery_percentage = atoi(buffer + 14);
+		if (info->apm_version_major >= 1 && info->apm_version_minor >= 1)
 		{
 		    fgets(buffer, sizeof(buffer) - 1, str);
-		    sscanf(buffer, "Battery flag: 0x%02x", &i->battery_flags);
+		    sscanf(buffer, "Battery flag: 0x%02x", &info->battery_flags);
 
 		    fgets(buffer, sizeof(buffer) - 1, str);
 		    if (strncmp(buffer + 14, "unknown", 7))
-			i->battery_time = atoi(buffer + 14);
+			info->battery_time = atoi(buffer + 14);
 		}
 	    }
 	}
@@ -140,9 +141,38 @@
     /* Fix possible kernel bug -- percentage
      * set to 0xff (==255) instead of -1. 
      */
-    if (i->battery_percentage > 100)
-	i->battery_percentage = -1;
+    if (info->battery_percentage > 100)
+	info->battery_percentage = -1;
 
+
+    buffer[0] = 0;
+	fgets(buffer, sizeof(buffer) - 1, str);
+    buffer[sizeof(buffer) - 1] = '\0';
+	if ((num_bat = atoi(buffer)) > 1) {
+		for (bat=0; bat< num_bat; bat++) {
+	    	buffer[0] = 0;
+			fgets(buffer, sizeof(buffer) - 1, str);
+		    buffer[sizeof(buffer) - 1] = '\0';
+			sscanf(buffer, "%d %x %x %d%% %d %s\n",
+				&tmp, 
+				&info->batteries[bat].battery_status,
+				&info->batteries[bat].battery_flags,
+				&info->batteries[bat].battery_percentage,
+				&info->batteries[bat].battery_time,
+				units);
+				info->batteries[bat].using_minutes = !strncmp(units, "min", 3) ? 1 : 0;
+		}
+		info->num_bat = num_bat;
+	} else {
+		info->num_bat = 1;
+		info->batteries[0].battery_status = info->battery_status;
+		info->batteries[0].battery_flags = info->battery_flags;
+		info->batteries[0].battery_percentage = info->battery_percentage;
+		info->batteries[0].battery_time = info->battery_time;
+		info->batteries[0].using_minutes = info->using_minutes;
+	}
+
+	
     fclose(str);
     return retcode;
 }
--- xapm.c.orig	Mon Aug 19 19:29:15 2002
+++ xapm.c	Sat Apr 12 18:54:11 2003
@@ -6,6 +6,8 @@
  * Modified: Fri Mar 26 11:26:00 1999 by bill.mair@bm-soft.com
  *           Added support for IBM ThinkPad charging options
  *           Added option display of AC/Battery useage
+ * Modified: 18 Aug 2002 Clive Stubbings
+ *			Added mutliple battery support
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -47,13 +49,15 @@
 } instance_variable_rec;
 
 static XtAppContext app_context;
-static Widget scrollbar;
+static Widget scrollbar[MAX_BATTERIES];
 static Widget topLevel;
 static Widget command;
 static XtIntervalId timerId;
 static instance_variable_rec iv;
 static int debug;
+static int display_bat = 0;		// Currently displaying battery (0 if total)
 
+#define DELL_INSPIRON 1		/* Inspirons have dual batteries and long life.. */
 /* Bill Mair, 26.03.1999 ----> */
 #define IBM_THINKPAD       0	/* ThinkPads use the battery_flags to indicate charging */
 #define SHOW_AC_BAT_STATUS 1
@@ -63,27 +67,45 @@
 #define TP_CHARGE_FLAG 0x08	/* This works on the TP770X but may be different on other TPs */
 #endif
 
+#if DELL_INSPIRON == 1
+#if SHOW_AC_BAT_STATUS == 1
+#define CHAR_COUNT 6
+#else
+#define CHAR_COUNT 5
+#endif
+#else
 #if SHOW_AC_BAT_STATUS == 1
 #define CHAR_COUNT 5
 #else
 #define CHAR_COUNT 4
 #endif
+#endif
 /* <---- Bill Mair, 26.03.1999 */
 
+void fixscrollbars(int nb);
+
+
+
 static void update(XtPointer client_data, XtIntervalId * id)
 {
     apm_info i;
     char buf[128];
-    static int pixel = -1;
+    int		bat;
+    static int pixel[MAX_BATTERIES], bpixel[MAX_BATTERIES];
     static int lpixel = -1;
-    static int bpixel = -1;
     static int lastPercentage = -1;
     static int lastMinutes = -1;
     static int lastDisplay = -1;
+    static int lastBat = -1;
+    static int lastNum_bat = -1;	// How many batteries?
     static int count = 0;
 #if SHOW_AC_BAT_STATUS == 1
     static int lastACStatus = -1;
 #endif
+
+	for (bat=0 ; bat<MAX_BATTERIES; bat++) {
+		pixel[bat] = bpixel[bat] = -1;
+	}
     apm_read(&i);
 
 #if DEBUG_UPDATE == 1
@@ -101,33 +123,56 @@
     }
 #endif
 
+	if (i.num_bat != lastNum_bat) {
+		fixscrollbars(i.num_bat);
+		lastNum_bat = i.num_bat;
+		for (bat=0 ; bat< MAX_BATTERIES; bat++) {
+			pixel[bat] = bpixel[bat] = -1;
+		}
+		lastDisplay = -1; lastPercentage = -1;
+	}
+	if (display_bat > i.num_bat)
+		display_bat = 0;
+
+	/* Use the total values to spot if things have changed */
+
     if (iv.displayPercent)
     {
+		int		tmp;
 	if (lastDisplay != iv.displayPercent
 	    || i.battery_percentage != lastPercentage
 
 #if SHOW_AC_BAT_STATUS == 1
 	    || i.ac_line_status != lastACStatus
 #endif
+		|| lastBat != display_bat
 	    )
 	{
 	    /* lastPercentage updated at end */
+	    if (display_bat)
+	    	tmp = i.batteries[display_bat-1].battery_percentage;
+	    else
+	    	tmp = i.battery_percentage;
 #if SHOW_AC_BAT_STATUS == 1
-	    sprintf(buf, "%s%d%%", i.ac_line_status ? "P" : "B", i.battery_percentage);
+		sprintf(buf, "%s%d%%", i.ac_line_status ? "P" : "B", tmp);
 #else
-	    sprintf(buf, "%d%%", i.battery_percentage);
+	    sprintf(buf, "%d%%", tmp);
 #endif
 	    XtVaSetValues(command, XtNlabel, buf, NULL);
 	}
     }
     else
     {
-	int minutes = i.using_minutes ? i.battery_time : i.battery_time / 60;
-
+	int minutes;
+		if (display_bat)
+			minutes = i.batteries[display_bat-1].using_minutes ? i.batteries[display_bat-1].battery_time : i.batteries[display_bat-1].battery_time / 60;
+		else
+			minutes = i.using_minutes ? i.battery_time : i.battery_time / 60;
 	if (lastDisplay != iv.displayPercent || lastMinutes != minutes
 #if SHOW_AC_BAT_STATUS == 1
 	    || i.ac_line_status != lastACStatus
 #endif
+		|| lastBat != display_bat
 	    )
 	{
 	    lastMinutes = minutes;
@@ -140,47 +185,55 @@
 	}
     }
     lastDisplay = iv.displayPercent;
+    lastBat = display_bat;
 #if SHOW_AC_BAT_STATUS == 1
     lastACStatus = i.ac_line_status;
 #endif
 
-    if (i.battery_percentage <= iv.lowValue)
-    {
-	if (pixel != iv.criticalColor)
-	    XtVaSetValues(scrollbar, XtNforeground,
-			  pixel = iv.criticalColor, NULL);
-	if (bpixel != iv.criticalColor)
-	    XtVaSetValues(scrollbar, XtNborderColor,
-			  bpixel = iv.criticalColor, NULL);
-    }
-    else if (i.battery_percentage <= iv.highValue)
-    {
-	if (pixel != iv.lowColor)
-	    XtVaSetValues(scrollbar, XtNforeground, pixel = iv.lowColor, NULL);
-	if (bpixel != iv.foreground)
-	    XtVaSetValues(scrollbar, XtNborderColor,
-			  bpixel = iv.foreground, NULL);
-    }
-    else
-    {
-	if (pixel != iv.highColor)
-	    XtVaSetValues(scrollbar, XtNforeground, pixel = iv.highColor, NULL);
-	if (i.battery_percentage == 100)
-	{
-	    if (bpixel != iv.highColor)
-		XtVaSetValues(scrollbar, XtNborderColor,
-			      bpixel = iv.highColor, NULL);
+    for (bat = 0; bat<i.num_bat; bat++) {
+
+	if (i.batteries[bat].battery_percentage <= iv.lowValue) {
+	    if (pixel[bat] != iv.criticalColor) {
+		XtVaSetValues(scrollbar[bat], XtNforeground,
+			  pixel[bat] = iv.criticalColor, NULL);
+	    }
+	    if (bpixel[bat] != iv.criticalColor) {
+		XtVaSetValues(scrollbar[bat], XtNborderColor,
+			  bpixel[bat] = iv.criticalColor, NULL);
+	    }
+	}
+	else if (i.batteries[bat].battery_percentage <= iv.highValue) {
+	    if (pixel[bat] != iv.lowColor) {
+		XtVaSetValues(scrollbar[bat], XtNforeground, pixel[bat] = iv.lowColor, NULL);
+	    }
+		if (bpixel[bat] != iv.foreground) {
+		XtVaSetValues(scrollbar[bat], XtNborderColor,
+			  bpixel[bat] = iv.foreground, NULL);
+	    }
 	}
 	else
 	{
-	    if (bpixel != iv.foreground)
-		XtVaSetValues(scrollbar, XtNborderColor,
-			      bpixel = iv.foreground, NULL);
+	    if (pixel[bat] != iv.highColor) {
+		XtVaSetValues(scrollbar[bat], XtNforeground, pixel[bat] = iv.highColor, NULL);
+	    }
+	    if (i.batteries[bat].battery_percentage == 100) {
+		if (bpixel[bat] != iv.highColor) {
+		    XtVaSetValues(scrollbar[bat], XtNborderColor,
+			      bpixel[bat] = iv.highColor, NULL);
+		}
+	    }
+	    else
+	    {
+		if (bpixel[bat] != iv.foreground) {
+		    XtVaSetValues(scrollbar[bat], XtNborderColor,
+			      bpixel[bat] = iv.foreground, NULL);
+		}
+	    }
 	}
+	if (debug)
+	    printf("scrollbar color = %d\n", pixel[bat]);
     }
-
-    if (debug)
-	printf("scrollbar color = %d\n", pixel);
+    
 
     if (i.battery_status == 3
 #if IBM_THINKPAD == 1
@@ -212,25 +265,42 @@
 	printf("command color = %d, status = %d\n",
 	       lpixel, i.battery_status);
 
-    if (i.battery_percentage != lastPercentage)
-	XawScrollbarSetThumb(scrollbar, 0.0,
-			     i.battery_percentage < 0
+    if (i.battery_percentage != lastPercentage) {
+    	for (bat=0; bat<i.num_bat; bat++) {
+		XawScrollbarSetThumb(scrollbar[bat], 0.0,
+			     i.batteries[bat].battery_percentage < 0
 			     ? 0.0
-			     : i.battery_percentage / 100.0);
-
+			     : i.batteries[bat].battery_percentage / 100.0);
+	}
     lastPercentage = i.battery_percentage;
-
+	}
     timerId = XtAppAddTimeOut(app_context, 1000 * iv.delay + 500,
 			      update, app_context);
 }
 
 static void press(Widget w, XtPointer client_data, XtPointer call_data)
 {
-    iv.displayPercent = !iv.displayPercent;
+    if (display_bat)
+	display_bat = 0;
+    else
+	iv.displayPercent = !iv.displayPercent;
     XtRemoveTimeOut(timerId);
     timerId = XtAppAddTimeOut(app_context, 0, update, app_context);
     if (debug)
 	printf("displayPercent = %d\n", iv.displayPercent);
+	
+}
+
+static void pressbar(Widget w, XtPointer client_data, XtPointer position)
+{
+	if (((int)client_data >= 0) && ((int)client_data < MAX_BATTERIES)) {
+		if (display_bat == ((int) client_data + 1))
+			iv.displayPercent = !iv.displayPercent;
+		else
+			display_bat = (int) client_data + 1;
+	    XtRemoveTimeOut(timerId);
+    	timerId = XtAppAddTimeOut(app_context, 0, update, app_context);
+    }
 }
 
 static XrmOptionDescRec options[] =
@@ -270,14 +340,16 @@
      offset(displayPercent), XtRImmediate, (XtPointer) FALSE},
 };
 
+    Cursor cursor;
+    Widget form;
+    int fontWidth, fontHeight, width = 100;
+
 int main(int argc, char **argv)
 {
-    Cursor cursor;
     int c;
-    Widget form;
+
     XFontStruct *fs;
-    int fontWidth, fontHeight;
-    int x = 0, y = 0, height = 10, width = 100;
+    int x = 0, y = 0, height = 10;
 
     switch (apm_exists())
     {
@@ -363,27 +435,85 @@
 	width, fontWidth * CHAR_COUNT, tmp, fontWidth * CHAR_COUNT + tmp);
     }
 
-    scrollbar = XtVaCreateManagedWidget("scrollbar",
-					scrollbarWidgetClass, form,
-					XtNhorizDistance, 3,
-					XtNfromHoriz, command,
-				      XtNorientation, XtorientHorizontal,
-					XtNscrollHCursor, cursor,
-					XtNthickness, fontHeight,
-			  XtNlength, (width > fontWidth * CHAR_COUNT - 6)
-				     ? width - fontWidth * CHAR_COUNT - 6
-					: fontWidth * CHAR_COUNT,
-					NULL);
-
-    XawScrollbarSetThumb(scrollbar, 0.0, 0.0);
-    XtVaSetValues(scrollbar,
-		  XtNtranslations, XtParseTranslationTable(""), NULL);
-
     XtAddCallback(command, XtNcallback, press, NULL);
-
+    fixscrollbars(1);
+	
     XtRealizeWidget(topLevel);
     timerId = XtAppAddTimeOut(app_context, 0, update, app_context);
     XtAppMainLoop(app_context);
 
     return 0;
+}
+
+/*
+ */
+void fixscrollbars(int nb)
+{
+	static int nscrollbar = -1;
+	Dimension  wid = width, height = fontHeight;
+	int		bat;
+
+	wid = (width > fontWidth * CHAR_COUNT - 6)
+				     ? width - fontWidth * CHAR_COUNT - 6
+					: fontWidth * CHAR_COUNT;
+
+//	printf("fixscrollbars(%d)\n", nb);
+	
+	if (nb != nscrollbar) {
+		// NEED TO KILL OLD ONES and OLD CALLBACKS
+		if (nscrollbar > 0) {
+//			printf("removing old!\n");
+			XtVaGetValues(scrollbar[0], XtNthickness, &height, NULL);
+			XtVaGetValues(scrollbar[0], XtNlength, &wid, NULL);
+			height *= nscrollbar;
+		}
+//		printf("width %d height %d\n", wid, height);
+		for (bat=0; bat<nscrollbar; bat++) {
+//			printf("destroy scrollbar %d\n", bat);
+			XtRemoveAllCallbacks(scrollbar[bat], XtNscrollProc);
+			XtUnmanageChild(scrollbar[bat]);
+			XtDestroyWidget(scrollbar[bat]);
+			scrollbar[bat] = NULL;
+		}
+
+
+		scrollbar[0] = XtVaCreateManagedWidget("scrollbar",
+					scrollbarWidgetClass, form,
+					XtNhorizDistance, 3,
+					XtNfromHoriz, command,
+					XtNorientation, XtorientHorizontal,
+					XtNscrollHCursor, cursor,
+					XtNscrollLCursor, cursor,
+					XtNthickness, height/nb,
+					XtNminimumThumb, 1,
+					XtNlength, wid);
+		XawScrollbarSetThumb(scrollbar[0], 0.0, 0.0);
+		XtVaSetValues(scrollbar[0], XtNtranslations,
+				XtParseTranslationTable("<Btn1Down>:StartScroll(Forward)\n<BtnUp>:NotifyScroll(Proportional)"), NULL);
+		XtAddCallback(scrollbar[0], XtNscrollProc, pressbar, 0);
+
+		for (bat=1; bat<nb; bat++) {
+			scrollbar[bat] = XtVaCreateWidget("scrollbar",
+					scrollbarWidgetClass, form,
+					XtNhorizDistance, 3,
+					XtNfromHoriz, command,
+					XtNvertDistance, 0,
+//					XtNfromVert, scrollbar[bat-1],
+					XtNorientation, XtorientHorizontal,
+					XtNsensitive, TRUE,
+					XtNscrollHCursor, cursor,
+					XtNscrollLCursor, cursor,
+					XtNthickness, height/nb,
+					XtNminimumThumb, 1,
+					XtNlength, wid);
+
+			XtVaSetValues(scrollbar[bat], XtNfromVert, scrollbar[bat-1], NULL);
+			XtManageChild(scrollbar[bat]);
+			XawScrollbarSetThumb(scrollbar[bat], 0.0, 0.0);
+			XtVaSetValues(scrollbar[bat], 
+				XtParseTranslationTable("<Btn1Down>:StartScroll(Forward)\n<BtnUp>:NotifyScroll(Proportional)"), NULL);
+			XtAddCallback(scrollbar[bat], XtNscrollProc, pressbar, (XtPointer)bat);
+		}
+	}
+	nscrollbar = nb;
 }
--- apm.h.orig	Sat Apr 12 19:35:28 2003
+++ apm.h	Tue Aug 20 20:54:53 2002
@@ -33,6 +33,9 @@
 #define APM_32_BIT_SUPPORT      0x0002
 #endif
 
+#define MAX_BATTERIES 3
+
+
 typedef struct apm_info
 {
     const char driver_version[10];
@@ -40,11 +43,21 @@
     int apm_version_minor;
     int apm_flags;
     int ac_line_status;
-    int battery_status;
+/* Total values */
+	int battery_status;
     int battery_flags;
-    int battery_percentage;
-    int battery_time;
-    int using_minutes;
+   	int battery_percentage;
+   	int battery_time;
+   	int using_minutes;
+    int	num_bat;			/* Number of batteries detected */
+/* Individual battery numbers */
+    struct {
+		int battery_status;
+	    int battery_flags;
+    	int battery_percentage;
+    	int battery_time;
+    	int using_minutes;
+    }  batteries[MAX_BATTERIES];
 }
 apm_info;
 
