summaryrefslogtreecommitdiff
path: root/sysutils/xbattbar/files/patch-xbattbar.c
blob: 65d3eaa7b1f8c044017fe235c13aa38354bc714a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
--- xbattbar.c.orig	2001-02-02 06:25:29.000000000 +0100
+++ xbattbar.c	2012-04-04 17:47:34.000000000 +0200
@@ -29,6 +29,8 @@ static char *ReleaseVersion="1.4.2";
 #include <sys/time.h>
 #include <signal.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
@@ -501,6 +503,10 @@ void battery_check(void)
 
 #ifdef __FreeBSD__
 
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#if defined(__i386__)
 #include <machine/apm_bios.h>
 
 #define APMDEV21       "/dev/apm0"
@@ -515,54 +521,90 @@ void battery_check(void)
 #define        APM_STAT_BATT_LOW       1
 #define        APM_STAT_BATT_CRITICAL  2
 #define        APM_STAT_BATT_CHARGING  3
+#endif /* i386 */
 
 int first = 1;
 void battery_check(void)
 {
-  int fd, r, p;
-  struct apm_info     info;
+  int r, p;
+  static int sysctl = 1;
 
-  if ((fd = open(APMDEV21, O_RDWR)) == -1 &&
-      (fd = open(APMDEV22, O_RDWR)) == -1) {
-    fprintf(stderr, "xbattbar: cannot open apm device\n");
-    exit(1);
-  }
-  if (ioctl(fd, APMIO_GETINFO, &info) == -1) {
-    fprintf(stderr, "xbattbar: ioctl APMIO_GETINFO failed\n");
-    exit(1);
+  if (sysctl) {
+    size_t r_size, p_size;
+
+    /* get current status */
+    r_size = sizeof(r);
+    if (sysctl && sysctlbyname("hw.acpi.battery.life", &r, &r_size, NULL, 0) == -1) {
+#if defined(__i386__)
+      fprintf(stderr, "xbattbar: fall back to apm interface\n");
+      sysctl = 0;
+#else /* !i386 */
+      fprintf(stderr, "xbattbar: can not get battery status\n");
+      exit(1);
+#endif /* i386 */
+    }
+
+    /* get AC-line status */
+    p_size = sizeof(p);
+    if (sysctl && sysctlbyname("hw.acpi.acline", &p, &p_size, NULL, 0) == -1) {
+#if defined(__i386__)
+      fprintf(stderr, "xbattbar: fall back to apm interface\n");
+      sysctl = 0;
+#else /* !i386 */
+      fprintf(stderr, "xbattbar: can not get AC-line status\n");
+      exit(1);
+#endif /* i386 */
+    }
   }
-  close (fd);
 
-  ++elapsed_time;
+#if defined(__i386__)
+  if (!sysctl) {
+    int fd;
+    struct apm_info info;
+
+    if ((fd = open(APMDEV21, O_RDONLY)) == -1 &&
+        (fd = open(APMDEV22, O_RDONLY)) == -1) {
+      fprintf(stderr, "xbattbar: cannot open apm device\n");
+      exit(1);
+    }
+    if (ioctl(fd, APMIO_GETINFO, &info) == -1) {
+      fprintf(stderr, "xbattbar: ioctl APMIO_GETINFO failed\n");
+      exit(1);
+    }
+    close (fd);
 
-  /* get current status */
-  if (info.ai_batt_life == APM_STAT_UNKNOWN) {
-    switch (info.ai_batt_stat) {
-    case APM_STAT_BATT_HIGH:
-      r = 100;
-      break;
-    case APM_STAT_BATT_LOW:
-      r = 40;
-      break;
-    case APM_STAT_BATT_CRITICAL:
-      r = 10;
-      break;
-    default:        /* expected to be APM_STAT_UNKNOWN */
+    /* get current status */
+    if (info.ai_batt_life == APM_STAT_UNKNOWN) {
+      switch (info.ai_batt_stat) {
+      case APM_STAT_BATT_HIGH:
+        r = 100;
+        break;
+      case APM_STAT_BATT_LOW:
+        r = 40;
+        break;
+      case APM_STAT_BATT_CRITICAL:
+        r = 10;
+        break;
+      default:        /* expected to be APM_STAT_UNKNOWN */
+        r = 100;
+      }
+    } else if (info.ai_batt_life > 100) {
+      /* some APM BIOSes return values slightly > 100 */
       r = 100;
+    } else {
+      r = info.ai_batt_life;
     }
-  } else if (info.ai_batt_life > 100) {
-    /* some APM BIOSes return values slightly > 100 */
-    r = 100;
-  } else {
-    r = info.ai_batt_life;
-  }
 
-  /* get AC-line status */
-  if (info.ai_acline == APM_STAT_LINE_ON) {
-    p = APM_STAT_LINE_ON;
-  } else {
-    p = APM_STAT_LINE_OFF;
+    /* get AC-line status */
+    if (info.ai_acline == APM_STAT_LINE_ON) {
+      p = APM_STAT_LINE_ON;
+    } else {
+      p = APM_STAT_LINE_OFF;
+    }
   }
+#endif /* i386 */
+
+  ++elapsed_time;
 
   if (first || ac_line != p || battery_level != r) {
     first = 0;