summaryrefslogtreecommitdiff
path: root/lisp/battery.el
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1997-06-22 20:08:32 +0000
committerRichard M. Stallman <rms@gnu.org>1997-06-22 20:08:32 +0000
commit6b2797406826346ad2f3dfaeb1837d602e844bb9 (patch)
tree2c45d2407ab7434ec053407b944ebb00d29a1264 /lisp/battery.el
parent326e87d25cab2a13ff23191635388fb4c9b2ea74 (diff)
downloademacs-6b2797406826346ad2f3dfaeb1837d602e844bb9.tar.gz
Initial revision
Diffstat (limited to 'lisp/battery.el')
-rw-r--r--lisp/battery.el279
1 files changed, 279 insertions, 0 deletions
diff --git a/lisp/battery.el b/lisp/battery.el
new file mode 100644
index 00000000000..b04b6af369f
--- /dev/null
+++ b/lisp/battery.el
@@ -0,0 +1,279 @@
+;;; battery.el --- display battery status information.
+
+;; Copyright (C) 1997 Ralph Schleicher
+
+;; Author: Ralph Schleicher <rs@purple.UL.BaWue.DE>
+;; Keywords: local hardware
+
+;; This file is not part of GNU Emacs.
+
+;; 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 Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; There is at present only a function interpreting the new `/proc/apm'
+;; file format of Linux version 1.3.58 or newer. That is, what a lucky
+;; coincidence, exactly the interface provided by the author's labtop.
+
+;;; Code:
+
+(require 'timer)
+
+
+(defvar battery-status-function
+ (cond ((and (eq system-type 'gnu/linux)
+ (file-readable-p "/proc/apm"))
+ 'battery-linux-proc-apm))
+ "*Function for getting battery status information.
+The function have to return an alist of conversion definitions.
+Cons cells are of the form
+
+ (CONVERSION . REPLACEMENT-TEXT)
+
+CONVERSION is the character code of a \"conversion specification\"
+introduced by a `%' character in a control string.")
+
+(defvar battery-echo-area-format
+ (cond ((eq battery-status-function 'battery-linux-proc-apm)
+ "Power %L, battery %B (%p%% load, remaining time %t)"))
+ "*Control string formatting the string to display in the echo area.
+Ordinary characters in the control string are printed as-is, while
+conversion specifications introduced by a `%' character in the control
+string are substituted as defined by the current value of the variable
+`battery-status-function'.")
+
+(defvar battery-mode-line-string nil
+ "String to display in the mode line.")
+
+(defvar battery-mode-line-format
+ (cond ((eq battery-status-function 'battery-linux-proc-apm)
+ " [%b%p%%]"))
+ "*Control string formatting the string to display in the mode line.
+Ordinary characters in the control string are printed as-is, while
+conversion specifications introduced by a `%' character in the control
+string are substituted as defined by the current value of the variable
+`battery-status-function'.")
+
+(defvar battery-update-interval 60
+ "*Seconds after which the battery status will be updated.")
+
+(defvar battery-update-timer nil
+ "Interval timer object.")
+
+;;;### autoload
+(defun battery ()
+ "Display battery status information in the echo area.
+The text beeing displayed in the echo area is controlled by the variables
+`battery-echo-area-format' and `battery-status-function'."
+ (interactive)
+ (message "%s" (if (and battery-echo-area-format battery-status-function)
+ (battery-format battery-echo-area-format
+ (funcall battery-status-function))
+ "Battery status not available")))
+
+;;;### autoload
+(defun display-battery ()
+ "Display battery status information in the mode line.
+The text beeing displayed in the mode line is controlled by the variables
+`battery-mode-line-format' and `battery-status-function'.
+The mode line will be updated automatically every `battery-update-interval'
+seconds."
+ (interactive)
+ (setq battery-mode-line-string "")
+ (or global-mode-string (setq global-mode-string '("")))
+ (or (memq 'battery-mode-line-string global-mode-string)
+ (setq global-mode-string (append global-mode-string
+ '(battery-mode-line-string))))
+ (and battery-update-timer (cancel-timer battery-update-timer))
+ (setq battery-update-timer (run-at-time nil battery-update-interval
+ 'battery-update-handler))
+ (battery-update))
+
+(defun battery-update-handler ()
+ (battery-update)
+ (sit-for 0))
+
+(defun battery-update ()
+ "Update battery status information in the mode line."
+ (setq battery-mode-line-string (if (and battery-mode-line-format
+ battery-status-function)
+ (battery-format
+ battery-mode-line-format
+ (funcall battery-status-function))
+ ""))
+ (force-mode-line-update))
+
+
+;;; `/proc/apm' interface for Linux.
+
+(defconst battery-linux-proc-apm-regexp
+ (concat "^\\([^ ]+\\)" ; Driver version.
+ " \\([^ ]+\\)" ; APM BIOS version.
+ " 0x\\([0-9a-f]+\\)" ; APM BIOS flags.
+ " 0x\\([0-9a-f]+\\)" ; AC line status.
+ " 0x\\([0-9a-f]+\\)" ; Battery status.
+ " 0x\\([0-9a-f]+\\)" ; Battery flags.
+ " \\([0-9]+\\)%" ; Load percentage.
+ " \\([0-9]+\\)" ; Remaining time.
+ " \\(.*\\)" ; Time unit.
+ "$")
+ "Regular expression matching contents of `/proc/apm'.")
+
+(defun battery-linux-proc-apm ()
+ "Get APM status information from Linux kernel.
+This function works only with the new `/proc/apm' format introduced
+in Linux version 1.3.58.
+
+The following %-sequences are provided:
+%v Linux driver version
+%V APM BIOS version
+%I APM BIOS status (verbose)
+%L AC line status (verbose)
+%B Battery status (verbose)
+%b Battery status, empty means high, `-' means low,
+ `!' means critical, and `+' means charging
+%p battery load percentage
+%s Remaining time in seconds
+%m Remaining time in minutes
+%h Remaining time in hours
+%t Remaining time in the form `h:min'"
+ (let (driver-version bios-version bios-interface line-status
+ battery-status battery-status-symbol load-percentage
+ seconds minutes hours remaining-time buffer tem)
+ (unwind-protect
+ (save-excursion
+ (setq buffer (generate-new-buffer " *battery*"))
+ (buffer-disable-undo buffer)
+ (set-buffer buffer)
+ (battery-insert-file-contents "/proc/apm")
+ (re-search-forward battery-linux-proc-apm-regexp)
+ (setq driver-version (match-string 1))
+ (setq bios-version (match-string 2))
+ (setq tem (battery-hex-to-int-2 (match-string 3)))
+ (if (not (logand tem 2))
+ (setq bios-interface "not supported")
+ (setq bios-interface "enabled")
+ (cond ((logand tem 16) (setq bios-interface "disabled"))
+ ((logand tem 32) (setq bios-interface "disengaged")))
+ (setq tem (battery-hex-to-int-2 (match-string 4)))
+ (cond ((= tem 0) (setq line-status "off-line"))
+ ((= tem 1) (setq line-status "on-line"))
+ ((= tem 2) (setq line-status "on backup")))
+ (setq tem (battery-hex-to-int-2 (match-string 6)))
+ (if (= tem 255)
+ (setq battery-status "N/A")
+ (setq tem (battery-hex-to-int-2 (match-string 5)))
+ (cond ((= tem 0) (setq battery-status "high"
+ battery-status-symbol ""))
+ ((= tem 1) (setq battery-status "low"
+ battery-status-symbol "-"))
+ ((= tem 2) (setq battery-status "critical"
+ battery-status-symbol "!"))
+ ((= tem 3) (setq battery-status "charging"
+ battery-status-symbol "+")))
+ (setq load-percentage (match-string 7))
+ (setq seconds (string-to-number (match-string 8)))
+ (and (string-equal (match-string 9) "min")
+ (setq seconds (* 60 seconds)))
+ (setq minutes (/ seconds 60)
+ hours (/ seconds 3600))
+ (setq remaining-time
+ (format "%d:%02d" hours (- minutes (* 60 hours)))))))
+ (and buffer (kill-buffer buffer)))
+ (list (cons ?v driver-version)
+ (cons ?V bios-version)
+ (cons ?I bios-interface)
+ (cons ?L line-status)
+ (cons ?B battery-status)
+ (cons ?b battery-status-symbol)
+ (cons ?p load-percentage)
+ (cons ?s (and seconds (number-to-string seconds)))
+ (cons ?m (and minutes (number-to-string minutes)))
+ (cons ?h (and hours (number-to-string hours)))
+ (cons ?t remaining-time))))
+
+
+;;; Private functions.
+
+(defun battery-format (format alist)
+ "Substitute %-sequences in FORMAT."
+ (let ((index 0)
+ (length (length format))
+ (result "")
+ char flag elem)
+ (while (< index length)
+ (setq char (aref format index))
+ (if (not flag)
+ (if (char-equal char ?%)
+ (setq flag t)
+ (setq result (concat result (char-to-string char))))
+ (cond ((char-equal char ?%)
+ (setq result (concat result "%")))
+ ((setq elem (assoc char alist))
+ (setq result (concat result (cdr elem)))))
+ (setq flag nil))
+ (setq index (1+ index)))
+ (or (null flag)
+ (setq result (concat result "%")))
+ result))
+
+(defun battery-insert-file-contents (file-name)
+ "Insert contents of file FILE-NAME after point.
+FILE-NAME can be a non-ordinary file, for example, a named pipe.
+Return t if file exists."
+ (let ((load-read-function 'battery-read-function)
+ (load-path '("."))
+ (load-history nil))
+ (save-excursion
+ (load file-name nil t t))))
+
+(defun battery-read-function (&optional stream)
+ "Function for reading expressions from STREAM.
+Value is always nil."
+ (let (char)
+ (while (not (< (setq char (get-file-char)) 0))
+ (insert char))))
+
+(defconst battery-hex-map '((?0 . 0) (?1 . 1) (?2 . 2) (?3 . 3)
+ (?4 . 4) (?5 . 5) (?6 . 6) (?7 . 7)
+ (?8 . 8) (?9 . 9) (?a . 10) (?b . 11)
+ (?c . 12) (?d . 13) (?e . 14) (?f . 15)))
+
+(defun battery-hex-to-int (string)
+ "Convert a hexadecimal number (a string) into a number."
+ (save-match-data
+ (and (string-match "^[ \t]+" string)
+ (setq string (substring string (match-end 0))))
+ (and (string-match "^0[xX]" string)
+ (setq string (substring string (match-end 0)))))
+ (battery-hex-to-int-2 string))
+
+(defun battery-hex-to-int-2 (string)
+ (let ((index 0)
+ (length (length string))
+ (value 0)
+ (elem nil))
+ (while (and (< index length)
+ (setq elem (assoc (downcase (aref string index))
+ battery-hex-map)))
+ (setq value (+ (* 16 value) (cdr elem))
+ index (1+ index)))
+ value))
+
+
+(provide 'battery)
+
+;;; battery.el ends here