Updating branch refs/heads/master
         to af9b6670205a5e76766f5f84a5b09dcb434baca3 (commit)
       from bb1cf8cbcc630f51bce482e57bfe02bf7018ac2a (commit)

commit af9b6670205a5e76766f5f84a5b09dcb434baca3
Author: Yves-Alexis Perez <[email protected]>
Date:   Mon Dec 27 14:12:23 2010 +0900

    Replace support by procfs with sysfs
    
    This fixes bug #3793

 panel-plugin/libacpi.c |  288 +++++++++++++++++++++++++++++++++++++++++++++++-
 panel-plugin/libacpi.h |    2 +
 2 files changed, 285 insertions(+), 5 deletions(-)

diff --git a/panel-plugin/libacpi.c b/panel-plugin/libacpi.c
index 19e7496..af17b09 100644
--- a/panel-plugin/libacpi.c
+++ b/panel-plugin/libacpi.c
@@ -52,6 +52,10 @@
 
 static char batteries[MAXBATT][128];
 static char battinfo[MAXBATT][128];
+/* path to AC adapter because not all AC adapter are listed 
+in /sys/class/power_supply/AC/ this obviously only supports one AC adapter. */
+static char sysfsacdir[128]; 
+
 #ifndef __linux__
 #if HAVE_SYSCTL
  static int
@@ -179,9 +183,76 @@ get_var(int *oid, int nlen)
 #endif
 #endif
 
+int check_acpi_sysfs(void)
+{
+       DIR *sysfs;
+       struct dirent *batt;
+       char *name;
+       FILE *typefile;
+       char typepath[128];
+       char tmptype[8];
+
+       sysfs = opendir("/sys/class/power_supply");
+       if (sysfs == 0)
+       {
+       #ifdef DEBUG
+         printf("DBG:No acpi support for sysfs. Trying procfs...\n");
+       #endif
+       return 2;
+       }
+       
+       while ((batt = readdir(sysfs)))
+       {
+               name = batt->d_name;
+               if (!strncmp(".", name, 1)) continue;
+               /* check whether /sys/class/power_supply/$name/type exists and 
+               contains "Battery" or "Mains" */
+               sprintf(typepath, "/sys/class/power_supply/%s/type",name);
+               if(!(typefile = fopen(typepath, "r"))) continue;
+               fgets(tmptype, 8, typefile);
+               fclose(typefile);
+               if(strncmp("Battery", tmptype, 7)==0)
+               {
+                       sprintf(batteries[batt_count], 
"/sys/class/power_supply/%s", name);
+               #ifdef DEBUG
+                       printf("DBG:battery number %d at:\n",batt_count);
+                       printf("DBG:sysfs dir->%s\n",batteries[batt_count]);
+                       printf("DBG:------------------------\n");
+               #endif
+                       batt_count++;
+               }
+               /* I guess that the type of the AC adapter is always "Mains" 
(?) */
+               else if(strncmp("Mains", tmptype, 5)==0){
+                       sprintf(sysfsacdir, "/sys/class/power_supply/%s", name);
+               #ifdef DEBUG
+                       printf("DBG:sysfs AC dir->%s\n",sysfsacdir);
+                       printf("DBG:------------------------\n");
+               #endif  
+               }
+       }
+       closedir(sysfs);
+       if ( batt_count == 0 )
+       {
+#ifdef DEBUG
+         printf("DBG:No acpi support for sysfs. Trying procfs...\n");
+#endif
+               acpi_sysfs = 0;
+               return 2;
+       }
+       else
+       {
+               acpi_sysfs = 1;
+               return 0;
+       }
+}
+
 /* see if we have ACPI support */
 int check_acpi(void)
 {
+#ifdef __linux__
+       if ( check_acpi_sysfs() == 0 )
+               return 0;
+#endif
   DIR *battdir;
   struct dirent *batt;
   char *name;
@@ -262,9 +333,82 @@ int check_acpi(void)
 #endif
 }
 
+int read_sysfs_int(char* filename)
+{
+       FILE* f;
+       f = fopen(filename,"r");
+       if ( !f )
+       {
+#ifdef DEBUG
+         printf("DBG:Could not open %s\n",filename);
+#endif
+               return 0;
+       }
+       int out;
+       fscanf(f,"%d",&out);
+       fclose(f);
+       return out;
+}
+
+char* read_sysfs_string(char* filename)
+{
+       FILE* f;
+       f = fopen(filename,"r");
+       if ( !f )
+       {
+#ifdef DEBUG
+         printf("DBG:Could not open %s\n",filename);
+#endif
+               return NULL;
+       }
+       fscanf(f,"%s",buf2);
+       fclose(f);
+       return buf2;
+}
+
+int read_acad_state_sysfs(void)
+{
+       DIR *sysfs;
+       struct dirent *propety;
+       char *name;
+       char onlinefilepath[128];
+       
+       sysfs = opendir(sysfsacdir);
+       if (sysfs == 0)
+       {
+       #ifdef DEBUG
+               printf("DBG:Can't open %s",sysfsacdir);
+       #endif
+               return 0;
+       }
+       closedir(sysfs);
+       
+       if (!acadstate) acadstate=(ACADstate *)malloc(sizeof(ACADstate));
+       /* this code doesn't make much sense.. why look at the whole directory?!
+       while ((propety = readdir(sysfs)))
+       {
+               name = propety->d_name;
+               if (!strncmp(".", name, 1) || !strncmp("..", name, 2)) continue;
+               
+               if (strcmp(name,"online") == 0)
+               {
+                       acadstate->state = ( 
read_sysfs_int("/sys/class/power_supply/AC/online") == 1 ) ;
+               }
+       } 
+       */
+       sprintf(onlinefilepath, "%s/online", sysfsacdir);
+       /* if onlinefilepath doesn't exist read_sysfs_int() will return 0
+       so acadstate->state will be 0, that should be ok */
+       acadstate->state = ( read_sysfs_int(onlinefilepath) == 1 );
+       
+       return acadstate->state;
+}
+
 int read_acad_state(void)
 {
 #ifdef __linux__
+       if (acpi_sysfs)
+               return read_acad_state_sysfs();
   FILE *acpi;
   char *ptr;
   char stat;
@@ -354,20 +498,83 @@ int read_acad_state(void)
 #endif
 }
 
+int read_acpi_info_sysfs(int battery)
+{
+       DIR *sysfs;
+       struct dirent *propety;
+       char *name;
+
+       sysfs = opendir(batteries[battery]);
+       if (sysfs == 0)
+       {
+       #ifdef DEBUG
+                 printf("DBG:Can't open %s!\n", batteries[battery]);
+       #endif
+           return 0;
+       }
+       /* malloc.. might explain the random battery level values on 2.6.24 
+       systems (energe_full is called charge_full so the value isn't 
initialised
+       and some random data from the heap is displayed..) 
+       if (!acpiinfo) acpiinfo=(ACPIinfo *)malloc(sizeof(ACPIinfo)); 
+       */
+       if (!acpiinfo) acpiinfo=(ACPIinfo *)calloc(1, sizeof(ACPIinfo));
+       
+       while ((propety = readdir(sysfs)))
+       {
+               name = propety->d_name;
+               if (!strncmp(".", name, 1) || !strncmp("..", name, 2)) continue;
+               /* at least on my system this is called charge_full */
+               if ((strcmp(name,"energy_full") == 0) || 
(strcmp(name,"charge_full") == 0))
+               {
+                       sprintf(buf,"%s/%s",batteries[battery], name);
+                       acpiinfo->last_full_capacity = read_sysfs_int(buf);
+               }
+               if ((strcmp(name,"energy_full_design") == 0) || 
(strcmp(name,"charge_full_design") == 0))
+               {
+                       sprintf(buf,"%s/%s",batteries[battery], name);
+                       acpiinfo->design_capacity = read_sysfs_int(buf);
+               }
+               if (strcmp(name,"technology") == 0)
+               {
+                       char *tmp;
+                       sprintf(buf,"%s/%s",batteries[battery], name);
+                       tmp = read_sysfs_string(buf);
+                       if (tmp != NULL)
+                       {
+                               if (strcmp(tmp,"Li-ion") == 0)
+                                       acpiinfo->battery_technology = 1;
+                               else
+                                       acpiinfo->battery_technology = 0;
+                       }
+               }
+               if (strcmp(name,"present") == 0)
+               {
+                       sprintf(buf,"%s/%s",batteries[battery], name);
+                       acpiinfo->present = read_sysfs_int(buf);
+               }
+       }
+       closedir(sysfs);
+       return acpiinfo->present;
+}
+
 int read_acpi_info(int battery)
 {
 #ifdef __linux__
-  FILE *acpi;
-  char *ptr;
-  char stat;
-  int temp;
-
   if (battery > MAXBATT) {
 #ifdef DEBUG
          printf("DBG: error, battery > MAXBATT (%d)\n",MAXBATT);
 #endif
          return 0;
   }
+
+       if (acpi_sysfs)
+               return read_acpi_info_sysfs(battery);
+  
+       FILE *acpi;
+  char *ptr;
+  char stat;
+  int temp;
+
   if (!(acpi = fopen (battinfo[battery], "r"))) {
 #ifdef DEBUG
          printf("DBG:cannot open %s for read!\n",battinfo[battery]);
@@ -514,9 +721,80 @@ int read_acpi_info(int battery)
 
 }
 
+int read_acpi_state_sysfs(int battery)
+{
+       DIR *sysfs;
+       struct dirent *propety;
+       char *name;
+
+       sysfs = opendir(batteries[battery]);
+       if (sysfs == 0)
+       {
+       #ifdef DEBUG
+         printf("DBG:Can't open %s!\n", batteries[battery]);
+       #endif
+       return 0;
+       }
+  
+       /* again it might be better to use calloc 
+       if (!acpistate) acpistate=(ACPIstate *)malloc(sizeof(ACPIstate));
+       */
+       if (!acpistate) acpistate=(ACPIstate *)calloc(1, sizeof(ACPIstate));
+
+       while ((propety = readdir(sysfs)))
+       {
+               name = propety->d_name;
+               if (!strncmp(".", name, 1) || !strncmp("..", name, 2)) continue;
+               
+               if (strcmp(name,"status") == 0)
+               {
+                       char *tmp;
+                       sprintf(buf,"%s/%s",batteries[battery], name);
+                       tmp = read_sysfs_string(buf);
+                       if ( tmp != NULL )
+                       {
+                               if (strcmp(tmp,"Charging") == 0)
+                                       acpistate->state = CHARGING;
+                               else if (strcmp(tmp,"Discharging") == 0)
+                                       acpistate->state = DISCHARGING;
+                               else if (strcmp(tmp,"Full") == 0)
+                                       acpistate->state = POWER;
+                               else
+                                       acpistate->state = UNKNOW;
+                       }
+               }
+               /* on my system this is called charge_now */
+               if ((strcmp(name,"energy_now") == 0) || 
(strcmp(name,"charge_now") == 0))
+               {
+                       sprintf(buf,"%s/%s",batteries[battery], name);
+                       acpistate->rcapacity = read_sysfs_int(buf);
+                       acpistate->percentage = (((float) 
acpistate->rcapacity)/acpiinfo->last_full_capacity) * 100;
+               }
+               if (strcmp(name,"current_now") == 0)
+               {
+                       sprintf(buf,"%s/%s",batteries[battery], name);
+                       acpistate->prate = read_sysfs_int(buf);
+                       if ( acpistate->prate < 0 )
+                               acpistate->prate = 0;
+                       if ( acpistate->prate > 0 )
+                               acpistate->rtime = (((float) 
acpistate->rcapacity) / acpistate->prate) * 60;
+               }
+               if (strcmp(name,"voltage_now") == 0)
+               {
+                       sprintf(buf,"%s/%s",batteries[battery], name);
+                       acpistate->pvoltage = read_sysfs_int(buf);
+               }
+       }
+       closedir(sysfs);
+       return acpiinfo->present;
+}
+
 int read_acpi_state(int battery)
 {
 #ifdef __linux__
+       if (acpi_sysfs)
+               return read_acpi_state_sysfs(battery);
+
   FILE *acpi;
   char *ptr;
   char stat;
diff --git a/panel-plugin/libacpi.h b/panel-plugin/libacpi.h
index 5e5540b..bcdd814 100644
--- a/panel-plugin/libacpi.h
+++ b/panel-plugin/libacpi.h
@@ -78,6 +78,8 @@ ACADstate *acadstate=NULL;
 int batt_count;
 /* temp buffer */
 char buf[512];
+char buf2[512];
+int acpi_sysfs;
 #else
 extern int batt_count;
 extern ACPIstate *acpistate;
_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to