]> code.delx.au - gnu-emacs/blobdiff - lisp/battery.el
* lisp/doc-view.el (doc-view-current-cache-dir): Beware % escapes.
[gnu-emacs] / lisp / battery.el
index 396423d9deadde790d22da0d129dfd54797f8c50..98ba7d1b631550e424b3739830a247f3c56e231d 100644 (file)
@@ -1,6 +1,6 @@
 ;;; battery.el --- display battery status information  -*- coding: iso-8859-1 -*-
 
-;; Copyright (C) 1997-1998, 2000-2011 Free Software Foundation, Inc.
+;; Copyright (C) 1997-1998, 2000-2013 Free Software Foundation, Inc.
 
 ;; Author: Ralph Schleicher <rs@nunatak.allgaeu.org>
 ;; Keywords: hardware
 ;;; Code:
 
 (require 'timer)
-(eval-when-compile (require 'cl))
-
+(eval-when-compile (require 'cl-lib))
 \f
 (defgroup battery nil
   "Display battery status information."
   :prefix "battery-"
   :group 'hardware)
 
+;; Either BATn or yeeloong-bat, basically.
+(defconst battery--linux-sysfs-regexp "[bB][aA][tT][0-9]?$")
+
 (defcustom battery-status-function
   (cond ((and (eq system-type 'gnu/linux)
              (file-readable-p "/proc/apm"))
         'battery-linux-proc-acpi)
        ((and (eq system-type 'gnu/linux)
              (file-directory-p "/sys/class/power_supply/")
-             (directory-files "/sys/class/power_supply/" nil "BAT[0-9]$"))
+             (directory-files "/sys/class/power_supply/" nil
+                               battery--linux-sysfs-regexp))
         'battery-linux-sysfs)
-       ((and (eq system-type 'gnu/linux)
-             (file-directory-p "/sys/class/power_supply/yeeloong-bat/")
-             (directory-files "/sys/class/power_supply/yeeloong-bat/" nil "charge_"))
-        'battery-yeeloong-sysfs)
+       ((and (eq system-type 'berkeley-unix)
+             (file-executable-p "/usr/sbin/apm"))
+        'battery-bsd-apm)
        ((and (eq system-type 'darwin)
              (condition-case nil
                  (with-temp-buffer
@@ -61,7 +63,7 @@
                         (> (buffer-size) 0)))
                (error nil)))
         'battery-pmset)
-       ((eq system-type 'windows-nt)
+       ((fboundp 'w32-battery-status)
         'w32-battery-status))
   "Function for getting battery status information.
 The function has to return an alist of conversion definitions.
@@ -78,11 +80,9 @@ introduced by a `%' character in a control string."
   (cond ((eq battery-status-function 'battery-linux-proc-acpi)
         "Power %L, battery %B at %r (%p%% load, remaining time %t)")
        ((eq battery-status-function 'battery-linux-sysfs)
-        "Power %L, battery %B (%p%% load)")
+        "Power %L, battery %B (%p%% load, remaining time %t)")
        ((eq battery-status-function 'battery-pmset)
         "%L power, battery %B (%p%% load, remaining time %t)")
-       ((eq battery-status-function 'battery-yeeloong-sysfs)
-        "%L power, battery %B (%p%% load, remaining time %t)")
        (battery-status-function
         "Power %L, battery %B (%p%% load, remaining time %t)"))
   "Control string formatting the string to display in the echo area.
@@ -110,6 +110,7 @@ string are substituted as defined by the current value of the variable
 
 (defcustom battery-mode-line-limit 100
   "Percentage of full battery load below which display battery status"
+  :version "24.1"
   :type 'integer
   :group 'battery)
 
@@ -343,14 +344,15 @@ The following %-sequences are provided:
               (setq charging-state (match-string 1)))
          (when (re-search-forward "present rate: +\\([0-9]+\\) \\(m[AW]\\)$"
                                   nil t)
-           (setq rate (+ (or rate 0) (string-to-number (match-string 1)))
-                 rate-type (or (and rate-type
+           (setq rate (+ (or rate 0) (string-to-number (match-string 1))))
+           (when (> rate 0)
+             (setq rate-type (or (and rate-type
                                     (if (string= rate-type (match-string 2))
                                         rate-type
                                       (error
                                        "Inconsistent rate types (%s vs. %s)"
                                        rate-type (match-string 2))))
-                               (match-string 2))))
+                                 (match-string 2)))))
          (when (re-search-forward "remaining capacity: +\\([0-9]+\\) m[AW]h$"
                                   nil t)
            (setq capacity
@@ -360,16 +362,16 @@ The following %-sequences are provided:
        (when (re-search-forward "present: +yes$" nil t)
          (when (re-search-forward "design capacity: +\\([0-9]+\\) m[AW]h$"
                                   nil t)
-           (incf design-capacity (string-to-number (match-string 1))))
+           (cl-incf design-capacity (string-to-number (match-string 1))))
          (when (re-search-forward "last full capacity: +\\([0-9]+\\) m[AW]h$"
                                   nil t)
-           (incf last-full-capacity (string-to-number (match-string 1))))
+           (cl-incf last-full-capacity (string-to-number (match-string 1))))
          (when (re-search-forward
                 "design capacity warning: +\\([0-9]+\\) m[AW]h$" nil t)
-           (incf warn (string-to-number (match-string 1))))
+           (cl-incf warn (string-to-number (match-string 1))))
          (when (re-search-forward "design capacity low: +\\([0-9]+\\) m[AW]h$"
                                   nil t)
-           (incf low (string-to-number (match-string 1)))))))
+           (cl-incf low (string-to-number (match-string 1)))))))
     (setq full-capacity (if (> last-full-capacity 0)
                            last-full-capacity design-capacity))
     (and capacity rate
@@ -446,7 +448,8 @@ The following %-sequences are provided:
     (with-temp-buffer
       (dolist (dir (ignore-errors
                    (directory-files
-                    "/sys/class/power_supply/" t "BAT[0-9]$")))
+                    "/sys/class/power_supply/" t
+                     battery--linux-sysfs-regexp)))
        (erase-buffer)
        (ignore-errors (insert-file-contents
                        (expand-file-name "uevent" dir)))
@@ -508,7 +511,7 @@ The following %-sequences are provided:
                     "N/A"))
          (cons ?d (or temperature "N/A"))
          (cons ?B (or charging-state "N/A"))
-         (cons ?p (cond ((> charge-full 0)
+         (cons ?p (cond ((and (> charge-full 0) (> charge-now 0))
                          (format "%.1f"
                                  (/ (* 100 charge-now) charge-full)))
                         ((> energy-full 0)
@@ -524,90 +527,74 @@ The following %-sequences are provided:
                         "BAT")
                     "N/A")))))
 
-(defun battery-yeeloong-sysfs ()
-  "Get ACPI status information from Linux (the kernel).
-This function works only on the Lemote Yeeloong.
-
+\f
+;;; `apm' interface for BSD.
+(defun battery-bsd-apm ()
+  "Get APM status information from BSD apm binary.
 The following %-sequences are provided:
-%c Current capacity (mAh)
-%r Current rate
+%L AC line status (verbose)
 %B Battery status (verbose)
 %b Battery status, empty means high, `-' means low,
-   `!' means critical, and `+' means charging
-%L AC line status (verbose)
-%p Battery load percentage
-%m Remaining time (to charge or discharge) in minutes
-%h Remaining time (to charge or discharge) in hours
-%t Remaining time (to charge or discharge) in the form `h:min'"
-
-  (let (capacity
-       capacity-level
-       status
-       ac-online
-       hours
-       current-now
-       charge-full
-       charge-now)
+ `!' means critical, and `+' means charging
+%P Advanced power saving mode state (verbose)
+%p Battery charge percentage
+%s Remaining battery charge time in seconds
+%m Remaining battery charge time in minutes
+%h Remaining battery charge time in hours
+%t Remaining battery charge time in the form `h:min'"
+  (let* ((os-name (car (split-string
+                       (shell-command-to-string "/usr/bin/uname"))))
+        (apm-flag (if (equal os-name "OpenBSD") "P" "s"))
+        (apm-cmd (concat "/usr/sbin/apm -ablm" apm-flag))
+        (apm-output (split-string (shell-command-to-string apm-cmd)))
+        ;; Battery status
+        (battery-status
+         (let ((stat (string-to-number (nth 0 apm-output))))
+           (cond ((eq stat 0) '("high" . ""))
+                 ((eq stat 1) '("low" . "-"))
+                 ((eq stat 2) '("critical" . "!"))
+                 ((eq stat 3) '("charging" . "+"))
+                 ((eq stat 4) '("absent" . nil)))))
+        ;; Battery percentage
+        (battery-percentage (nth 1 apm-output))
+        ;; Battery life
+        (battery-life (nth 2 apm-output))
+        ;; AC status
+        (line-status
+         (let ((ac (string-to-number (nth 3 apm-output))))
+           (cond ((eq ac 0) "disconnected")
+                 ((eq ac 1) "connected")
+                 ((eq ac 2) "backup power"))))
+        ;; Advanced power savings mode
+        (apm-mode
+         (let ((apm (string-to-number (nth 4 apm-output))))
+           (if (string= os-name "OpenBSD")
+               (cond ((eq apm 0) "manual")
+                     ((eq apm 1) "automatic")
+                     ((eq apm 2) "cool running"))
+             (if (eq apm 1) "on" "off"))))
+        seconds minutes hours remaining-time)
+    (unless (member battery-life '("unknown" "-1"))
+      (if (member os-name '("OpenBSD" "NetBSD"))
+         (setq minutes (string-to-number battery-life)
+               seconds (* 60 minutes))
+       (setq seconds (string-to-number battery-life)
+             minutes (truncate (/ seconds 60))))
+      (setq hours (truncate (/ minutes 60))
+           remaining-time (format "%d:%02d" hours
+                                  (- minutes (* 60 hours)))))
+    (list (cons ?L (or line-status "N/A"))
+         (cons ?B (or (car battery-status) "N/A"))
+         (cons ?b (or (cdr battery-status) "N/A"))
+         (cons ?p (if (string= battery-percentage "255")
+                      "N/A"
+                    battery-percentage))
+         (cons ?P (or apm-mode "N/A"))
+         (cons ?s (or (and seconds (number-to-string seconds)) "N/A"))
+         (cons ?m (or (and minutes (number-to-string minutes)) "N/A"))
+         (cons ?h (or (and hours (number-to-string hours)) "N/A"))
+         (cons ?t (or remaining-time "N/A")))))
 
-    (with-temp-buffer
-      (ignore-errors
-       (insert-file-contents "/sys/class/power_supply/yeeloong-bat/uevent")
-       (goto-char 1)
-       (search-forward "POWER_SUPPLY_CHARGE_NOW=")
-       (setq charge-now (read (current-buffer)))
-       (goto-char 1)
-       (search-forward "POWER_SUPPLY_CHARGE_FULL=")
-       (setq charge-full (read (current-buffer)))
-       (goto-char 1)
-       (search-forward "POWER_SUPPLY_CURRENT_NOW=")
-       (setq current-now (read (current-buffer)))
-       (goto-char 1)
-       (search-forward "POWER_SUPPLY_CAPACITY_LEVEL=")
-       (setq capacity-level (buffer-substring (point) (line-end-position)))
-       (goto-char 1)
-       (search-forward "POWER_SUPPLY_STATUS=")
-       (setq status (buffer-substring (point) (line-end-position))))
-       
-      (erase-buffer)
-      (ignore-errors
-       (insert-file-contents
-        "/sys/class/power_supply/yeeloong-ac/online")
-       (goto-char 1)
-       (setq ac-online (read (current-buffer)))
-       (erase-buffer)))
-
-
-    (setq capacity (round (/ (* charge-now 100.0) charge-full)))
-    (when (and current-now (not (= current-now 0)))
-      (if (< current-now 0)
-         ;; Charging
-         (setq hours (/ (- charge-now charge-full) (+ 0.0 current-now)))
-       ;; Discharging
-       (setq hours (/ charge-now (+ 0.0 current-now)))))
-
-    (list (cons ?c (if charge-now
-                      (number-to-string charge-now)
-                    "N/A"))
-         (cons ?r current-now)
-         (cons ?B (cond ((equal capacity-level "Full") "full")
-                        ((equal status "Charging") "charging")
-                        ((equal capacity-level "Low") "low")
-                        ((equal capacity-level "Critical") "critical")
-                        (t "high")))
-         (cons ?b (cond ((equal capacity-level "Full") " ")
-                        ((equal status "Charging") "+")
-                        ((equal capacity-level "Low") "-")
-                        ((equal capacity-level "Critical") "!")
-                        (t " ")))
-         (cons ?h (if hours (number-to-string hours) "N/A"))
-         (cons ?m (if hours (number-to-string (* 60 hours)) "N/A"))
-         (cons ?t (if hours
-                      (format "%d:%d"
-                              (/ (round (* 60 hours)) 60)
-                              (% (round (* 60 hours)) 60))
-                    "N/A"))
-         (cons ?p (if capacity (number-to-string capacity) "N/A"))
-         (cons ?L (if (eq ac-online 1) "AC" "BAT")))))
 \f
 ;;; `pmset' interface for Darwin (OS X).