Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Sep 2009 22:45:30 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   ports/138489: icewm ACPI support patch
Message-ID:  <200909022245.n82MjUPJ094728@www.freebsd.org>
Resent-Message-ID: <200909022250.n82Mo6GW058410@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         138489
>Category:       ports
>Synopsis:       icewm ACPI support patch
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 02 22:50:06 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Alexander Motin
>Release:        7-STABLE, 8-STABLE, 9-CURRENT
>Organization:
>Environment:
>Description:
IceWM supports power/battery indicator only for FreeBSD APM systems.
I have implemented patch which adds FreeBSD ACPI support to it also.
Patch allows to see main power parameters such as battery status, percentage,
current, status and time remaining in system tray and floating hint.

Patch was submitted upstream long ago, but without any effect till now.
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

diff -ruNp src.prev/aapm.cc src/aapm.cc
--- src.prev/aapm.cc	2009-01-25 16:39:51.000000000 +0200
+++ src/aapm.cc	2009-09-03 01:27:42.000000000 +0300
@@ -31,8 +31,12 @@
 #include <sys/file.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
+#ifdef i386
 #include <machine/apm_bios.h>
 #endif
+#include <sys/sysctl.h>
+#include <dev/acpica/acpiio.h>
+#endif
 
 #ifdef __NetBSD__
 #include <sys/file.h>
@@ -63,7 +67,7 @@ static YColor *taskBarBg = 0;
 
 
 void ApmStr(char *s, bool Tool) {
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) && defined(i386) 
     struct apm_info ai;
 #elif defined __NetBSD__
     struct apm_power_info ai;
@@ -88,7 +92,7 @@ void ApmStr(char *s, bool Tool) {
         error = 1;
         return ;
     }
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) && defined(i386)
     if (ioctl(fd,APMIO_GETINFO, &ai) == -1)
     {
         static int error = 0;
@@ -231,6 +235,7 @@ int YApm::ignore_directory_ac_entry(stru
 void YApm::AcpiStr(char *s, bool Tool) {
     char buf[80], buf2[80], bat_info[250];
     FILE *fd;
+    int      acpifd;
     //name of the battery
     char *BATname;
     //battery is present or absent
@@ -250,12 +255,14 @@ void YApm::AcpiStr(char *s, bool Tool) {
     //status of ac-adapter online/offline
     int ACstatus;
     int i;
+    size_t len;
 
     *s='\0';
 
     //assign some default values, in case
     //the file in /proc/acpi will contain unexpected values
     ACstatus = -1;
+#ifndef __FreeBSD__
     if (acpiACName && acpiACName[0] != 0) {
         strcat3(buf, "/proc/acpi/ac_adapter/", acpiACName, "/state", sizeof(buf));
         fd = fopen(buf, "r");
@@ -285,6 +292,17 @@ void YApm::AcpiStr(char *s, bool Tool) {
             fclose(fd);
         }
     }
+#else
+    len = sizeof(i);
+    if (sysctlbyname("hw.acpi.acline", &i, &len, NULL, 0) >= 0) {
+	if (i == 1)
+	    ACstatus = AC_ONLINE;
+	else if (i = 0)
+	    ACstatus = AC_OFFLINE;
+	else
+	    ACstatus = AC_UNKNOWN;
+    }
+#endif
 
     int n = 0;
     for (i = 0; i < batteryNum; i++) {
@@ -299,6 +317,7 @@ void YApm::AcpiStr(char *s, bool Tool) {
         BATrate = -1;
         BATtime_remain = -1;
 
+#ifndef __FreeBSD__
         strcat3(buf, "/proc/acpi/battery/", BATname, "/state", sizeof(buf));
         fd = fopen(buf, "r");
         if (fd == NULL) {
@@ -347,10 +366,43 @@ void YApm::AcpiStr(char *s, bool Tool) {
             }
             fclose(fd);
         }
+#else
+	int      acpifd;
+
+#define ACPIDEV         "/dev/acpi"
+	acpifd = open(ACPIDEV, O_RDONLY);
+	if (acpifd != -1) {
+	    union acpi_battery_ioctl_arg battio;
+	    
+	    battio.unit = i;
+	    if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) != -1) {
+		if (battio.battinfo.state != ACPI_BATT_STAT_NOT_PRESENT) {
+		    BATpresent = BAT_PRESENT;
+		    if (battio.battinfo.state == 0)
+			BATstatus = BAT_FULL;
+		    else if (battio.battinfo.state & ACPI_BATT_STAT_CHARGING)
+			BATstatus = BAT_CHARGING;
+		    else if (battio.battinfo.state & ACPI_BATT_STAT_DISCHARG)
+			BATstatus = BAT_DISCHARGING;
+		    else
+			BATstatus = BAT_UNKNOWN;
+		    if (battio.battinfo.cap != -1 && acpiBatteries[i]->capacity_full != -1)
+			BATcapacity_remain = acpiBatteries[i]->capacity_full *
+			    battio.battinfo.cap / 100;
+		    if (battio.battinfo.min != -1)
+			BATtime_remain = battio.battinfo.min;
+		    if (battio.battinfo.rate != -1)
+			BATrate = battio.battinfo.rate;
+		} else
+		    BATpresent = BAT_ABSENT;
+	    }
+	}
+#endif
 
         if (BATpresent == BAT_PRESENT) { //battery is present now
             if (acpiBatteries[i]->present == BAT_ABSENT) { //and previously was absent
                 //read full-capacity value
+#ifndef __FreeBSD__
                 strcat3(buf, "/proc/acpi/battery/", BATname, "/info", sizeof(buf));
                 fd = fopen(buf, "r");
                 if (fd != NULL) {
@@ -372,6 +424,21 @@ void YApm::AcpiStr(char *s, bool Tool) {
                     if (BATcapacity_remain > BATcapacity_full && BATcapacity_design > 0)
                         BATcapacity_full = BATcapacity_design;
                 }
+#else
+		union acpi_battery_ioctl_arg battio;
+#define UNKNOWN_CAP 0xffffffff                                                  
+#define UNKNOWN_VOLTAGE 0xffffffff                                              
+	    
+		battio.unit = i;
+		if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) != -1) {
+		    if (battio.bif.dcap != UNKNOWN_CAP)
+			BATcapacity_design = battio.bif.dcap;
+		    if (battio.bif.lfcap != UNKNOWN_CAP)
+			BATcapacity_full = battio.bif.lfcap;
+                    if (BATcapacity_remain > BATcapacity_full && BATcapacity_design > 0)
+                        BATcapacity_full = BATcapacity_design;
+		}
+#endif
                 acpiBatteries[i]->capacity_full = BATcapacity_full;
             }
             else {
@@ -380,6 +447,11 @@ void YApm::AcpiStr(char *s, bool Tool) {
         }
         acpiBatteries[i]->present = BATpresent;
 
+#ifdef __FreeBSD__
+	close(acpifd);
+#endif
+
+        bat_info[0] = 0;
         if (!Tool &&
             taskBarShowApmTime &&
             BATpresent == BAT_PRESENT &&
@@ -387,7 +459,8 @@ void YApm::AcpiStr(char *s, bool Tool) {
             BATstatus == BAT_DISCHARGING &&
             //did we parse the needed values successfully?
             BATcapacity_full >= 0 && BATcapacity_remain >= 0 && BATrate > 0) {
-            BATtime_remain = (int) (60 * (double)(BATcapacity_remain) / BATrate);
+	    if (BATtime_remain == -1)
+        	BATtime_remain = (int) (60 * (double)(BATcapacity_remain) / BATrate);
             sprintf(bat_info, "%d:%02d", BATtime_remain / 60, BATtime_remain % 60);
         }
         else if (BATpresent == BAT_PRESENT &&
@@ -397,17 +470,19 @@ void YApm::AcpiStr(char *s, bool Tool) {
             sprintf(bat_info, "%3.0f%%",
                     100 * (double)BATcapacity_remain / BATcapacity_full);
         }
-        else {
-            //battery is absent or we didn't parse some needed values
-            bat_info[0] = 0;
-        }
 
         if (BATstatus == BAT_CHARGING) {
             if (Tool)
                 strcat(bat_info, _(" - Charging"));
             else
                 strcat(bat_info, _("C"));
-        }
+	} else if (BATstatus == BAT_FULL && Tool)
+                strcat(bat_info, _(" - Full"));
+
+	if (Tool && BATrate > 0) {
+	    sprintf(buf, " %d", BATrate);
+            strcat(bat_info, buf);
+	}
 
         if ((n > 0) && (*bat_info)) {
             if (Tool)
@@ -738,6 +813,7 @@ void YApm::PmuStr(char *s, const bool to
 YApm::YApm(YWindow *aParent): YWindow(aParent) {
     struct dirent **de;
     int n, i;
+    size_t s;
     FILE *pmu_info;
                     char buf[80];
                     FILE *fd;
@@ -747,6 +823,7 @@ YApm::YApm(YWindow *aParent): YWindow(aP
     fCurrentState = 0;
 
     //search for acpi info first
+#ifndef __FreeBSD__
     n = scandir("/sys/class/power_supply", &de, 0, alphasort);
     if (n < 0) {
         n = scandir("/proc/acpi/battery", &de, 0, alphasort);
@@ -824,7 +901,34 @@ YApm::YApm(YWindow *aParent): YWindow(aP
             acpiACName = (char*)malloc(sizeof(char));
             *acpiACName = '\0';
         }
+#else
+    int acpifd;
+    
+    acpifd = open(ACPIDEV, O_RDONLY);
+    if (acpifd != -1) {
+	mode = ACPI;
 
+        //scan for batteries
+        i = 0;
+        while (i < 64 && batteryNum < MAX_ACPI_BATTERY_NUM) {
+	    union acpi_battery_ioctl_arg battio;
+	    
+	    battio.unit = i;
+	    if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) != -1) {
+    		acpiBatteries[batteryNum] =
+	            (bat_info*)malloc(sizeof(bat_info));
+	    	asprintf(&acpiBatteries[batteryNum]->name, "Battery%d", i);
+	        //initially set as absent, to force reading of
+	        //full-capacity value
+	        acpiBatteries[batteryNum]->present = BAT_ABSENT;
+	        acpiBatteries[batteryNum]->capacity_full = -1;
+	        batteryNum++;
+	    }
+	    i++;
+	}
+
+	asprintf(&acpiACName, "AC1");
+#endif
     } else if ( (pmu_info = fopen("/proc/pmu/info", "r")) != NULL) {
        mode = PMU;
        char line[80];
@@ -870,7 +974,21 @@ YApm::~YApm() {
 }
 
 void YApm::updateToolTip() {
-    setToolTip(fCurrentState);
+    char s[64] = {' ', ' ', ' ', 0, 0, 0, 0, 0};
+
+    switch (mode) {
+    case ACPI:
+        AcpiStr(s, 1);
+        break;
+    case APM:
+        ApmStr(s, 1);
+        break;
+    case PMU:
+        PmuStr(s, 1);
+        break;
+    }
+
+    setToolTip(s);
 }
 
 int YApm::calcInitialWidth() {
diff -ruNp src.prev/aapm.h src/aapm.h
--- src.prev/aapm.h	2009-01-25 16:39:51.000000000 +0200
+++ src/aapm.h	2009-09-03 01:26:29.000000000 +0300
@@ -1,5 +1,5 @@
 
-#if defined(linux) || (defined (__FreeBSD__) && defined(i386)) || (defined(__NetBSD__) && defined(i386))
+#if defined(linux) || (defined (__FreeBSD__)) || (defined(__NetBSD__) && defined(i386))
 
 #include "ywindow.h"
 #include "ytimer.h"
diff -ruNp src.prev/wmtaskbar.cc src/wmtaskbar.cc
--- src.prev/wmtaskbar.cc	2009-01-25 16:39:51.000000000 +0200
+++ src/wmtaskbar.cc	2009-09-03 01:26:29.000000000 +0300
@@ -458,6 +458,7 @@ void TaskBar::initApplets() {
 #ifdef CONFIG_APPLET_APM
     if (taskBarShowApm && (access(APMDEV, 0) == 0 ||
                            access("/proc/acpi", 0) == 0 ||
+                           access("/dev/acpi", 0) == 0 ||
 	                   access("/proc/pmu", R_OK|X_OK) == 0))
     {
         fApm = new YApm(this);


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200909022245.n82MjUPJ094728>