1 ;;; xwem-battery.el --- Dockapp APM battery monitor for XWEM.
3 ;; Copyright (C) 2004,2005 by XWEM Org.
5 ;; Author: Zajcev Evgeny <zevlg@yandex.ru>
6 ;; Steve Youngs <steve@youngs.au.com>
7 ;; Created: Thu Sep 2 01:14:36 GMT 2004
9 ;; X-CVS: $Id: xwem-battery.el,v 1.4 2009-10-02 12:03:35 aidan Exp $
11 ;; This file is part of XWEM.
13 ;; XWEM is free software; you can redistribute it and/or modify it
14 ;; under the terms of the GNU General Public License as published by
15 ;; the Free Software Foundation; either version 2, or (at your option)
18 ;; XWEM is distributed in the hope that it will be useful, but WITHOUT
19 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
21 ;; License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with XEmacs; see the file COPYING. If not, write to the Free
25 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 ;;; Synched up with: Not in FSF
32 ;; APM battery status monitor dockapp for use under XWEM.
49 ;; To start using it, just add:
51 ;; (load-module <path-to-apm-battery-ell>)
52 ;; (add-hook 'xwem-after-init-hook 'xwem-battery)
60 (autoload 'apm-battery "battery.ell" "Return current battery status."))
63 (require 'xlib-xshape)
68 (defgroup xwem-batt nil
69 "Group to customise APM battery monitor."
73 (defcustom xwem-batt-update-interval 5
74 "*Apm battery dockapp update interval in seconds."
78 (defcustom xwem-batt-height 24
79 "*Height of apm battery dockapp in pixels."
83 (defcustom xwem-batt-width 10
84 "*Width of apm battery dockapp in pixels."
88 (defcustom xwem-batt-percentage-colors
96 "*Table to translate percentage to color."
97 :type '(repeat (cons (number :tag "Percents")
98 (color :tag "Color")))
101 (defcustom xwem-batt-ac-line-width 4
106 (defcustom xwem-batt-ac-line-color "blue"
107 "*Color used to display ac-line."
111 ;;; Internal variables
114 (defmacro xwem-batt-itimer (win)
115 `(X-Win-get-prop ,win 'xwem-batt-itimer))
116 (defsetf xwem-batt-itimer (win) (itimer)
117 `(X-Win-put-prop ,win 'xwem-batt-itimer ,itimer))
118 (defmacro xwem-batt-xmask (win)
119 `(X-Win-get-prop ,win 'xwem-batt-xmask))
120 (defsetf xwem-batt-xmask (win) (xmask)
121 `(X-Win-put-prop ,win 'xwem-batt-xmask ,xmask))
122 (defmacro xwem-batt-pixmap (win)
123 `(X-Win-get-prop ,win 'xwem-batt-pixmap))
124 (defsetf xwem-batt-pixmap (win) (pixmap)
125 `(X-Win-put-prop ,win 'xwem-batt-pixmap ,pixmap))
127 (defmacro xwem-batt-old-ac-line-p (win)
128 `(X-Win-get-prop ,win 'old-ac-line-p))
129 (defsetf xwem-batt-old-ac-line-p (win) (oalp)
130 `(X-Win-put-prop ,win 'old-ac-line-p ,oalp))
131 (defmacro xwem-batt-old-dheight (win)
132 `(X-Win-get-prop ,win 'old-dheight))
133 (defsetf xwem-batt-old-dheight (win) (dheight)
134 `(X-Win-put-prop ,win 'old-dheight ,dheight))
136 (defun xwem-batt-init (xdpy)
137 "On display XDPY create and return APM battery monitor window."
138 (let (xwin xmask xpix)
139 (setq xwin (XCreateWindow xdpy (XDefaultRootWindow xdpy)
140 0 0 xwem-batt-width xwem-batt-height 0
142 (make-X-Attr :backing-store X-WhenMapped
143 :override-redirect t)))
145 ;; Create mask pixmap for xwin
146 (setq xmask (XCreatePixmap xdpy (make-X-Pixmap :dpy xdpy
147 :id (X-Dpy-get-id xdpy))
148 xwin 1 xwem-batt-width xwem-batt-height))
150 (XFillRectangle xdpy xmask xwem-misc-mask-bgc
151 0 0 xwem-batt-width xwem-batt-height)
152 (XFillRectangle xdpy xmask xwem-misc-mask-fgc
153 0 2 xwem-batt-width (- xwem-batt-height 3))
154 (XDrawSegments xdpy xmask xwem-misc-mask-fgc
155 (list (cons (cons 3 0) (cons (- xwem-batt-width 4) 0))
156 (cons (cons 1 1) (cons (- xwem-batt-width 2) 1))
157 (cons (cons 1 (- xwem-batt-height 1))
158 (cons (- xwem-batt-width 2)
159 (- xwem-batt-height 1)))))
162 (X-XShapeMask xdpy xwin X-XShape-Bounding X-XShapeSet 0 0 xmask)
163 (setf (xwem-batt-xmask xwin) xmask)
165 ;; Create pixmap for storer
166 (setq xpix (XCreatePixmap xdpy (make-X-Pixmap :dpy xdpy
167 :id (X-Dpy-get-id xdpy))
168 xwin (XDefaultDepth xdpy)
169 xwem-batt-width xwem-batt-height))
170 (setf (xwem-batt-pixmap xwin) xpix)
171 (xwem-batt-win-update xwin t)
175 (defface xwem-batt-tmp-face
176 `((t (:foreground "black")))
177 "Temporary face used by apm battery dockapp.")
179 (define-xwem-deffered xwem-batt-apply-pixmap (xwin)
180 "Apply pixmap storer to XWIN."
181 (XCopyArea (X-Win-dpy xwin) (xwem-batt-pixmap xwin) xwin
182 (XDefaultGC (X-Win-dpy xwin))
183 0 0 xwem-batt-width xwem-batt-height 0 0))
185 (defun xwem-batt-win-update (xwin &optional force)
186 "Update contents of XWIN to reflect current APM battery state."
187 (let* ((xdpy (X-Win-dpy xwin))
188 (xpix (xwem-batt-pixmap xwin))
192 (perc-cols xwem-batt-percentage-colors)
198 ;; Calculate displayed height
199 (setq dheight (round (/ (* cperc (- xwem-batt-height 5)) 100.0)))
201 (when (or force (not (eq dheight (xwem-batt-old-dheight xwin)))
202 (not (eq ac-line-p (xwem-batt-old-ac-line-p xwin))))
203 (XFillRectangle xdpy xpix (XDefaultGC xdpy)
204 0 0 xwem-batt-width xwem-batt-height)
206 (XFillRectangle xdpy xpix (XDefaultGC xdpy)
207 0 0 xwem-batt-width xwem-batt-height)
208 (XDrawRectangle xdpy xpix (xwem-face-get-gc 'xwem-face-black)
209 1 2 (- xwem-batt-width 3) (- xwem-batt-height 4))
210 (XDrawLine xdpy xpix (xwem-face-get-gc 'xwem-face-black)
211 3 1 (- xwem-batt-width 4) 1)
214 ;; Maybe redraw percentage
215 (when (or force (not (eq dheight (xwem-batt-old-dheight xwin))))
216 ;; Find appopriate color
217 (while (and perc-cols (> cperc (caar perc-cols)))
218 (setq perc-cols (cdr perc-cols)))
219 (setq perc-cols (cdar perc-cols))
221 (xwem-set-face-foreground 'xwem-batt-tmp-face perc-cols)
222 (XFillRectangle xdpy xpix (xwem-face-get-gc 'xwem-batt-tmp-face)
223 2 (- xwem-batt-height 2 dheight)
224 (- xwem-batt-width 4) dheight)
225 (when (< dheight (- xwem-batt-height 5))
226 (XDrawLine xdpy xpix (xwem-face-get-gc 'xwem-face-black)
227 2 (- xwem-batt-height 2 dheight)
228 (- xwem-batt-width 2) (- xwem-batt-height 2 dheight)))
231 (setf (xwem-batt-old-dheight xwin) dheight))
233 ;; Maybe redraw ac-line status
234 (when (or force (not (eq ac-line-p (xwem-batt-old-ac-line-p xwin))))
236 (xwem-set-face-foreground 'xwem-batt-tmp-face xwem-batt-ac-line-color)
237 (let ((acgc (xwem-face-get-gc 'xwem-batt-tmp-face)))
238 (setf (X-Gc-line-width acgc) xwem-batt-ac-line-width)
239 (XChangeGC xdpy acgc)
240 (XDrawLine xdpy xpix acgc
241 xwem-batt-width xwem-batt-ac-line-width
242 0 (- xwem-batt-height xwem-batt-ac-line-width))
243 (setf (X-Gc-line-width acgc) 0)
244 (XChangeGC xdpy acgc)))
245 (setf (xwem-batt-old-ac-line-p xwin) ac-line-p))
247 (xwem-batt-apply-pixmap xwin)))
249 (defun xwem-batt-win-remove (xwin &optional need-destroy)
250 "Remove battery dockapp."
251 (when (xwem-batt-itimer xwin)
252 (delete-itimer (xwem-batt-itimer xwin)))
253 (XFreePixmap (X-Win-dpy xwin) (xwem-batt-xmask xwin))
254 (XFreePixmap (X-Win-dpy xwin) (xwem-batt-pixmap xwin))
256 (setf (xwem-batt-itimer xwin) nil
257 (xwem-batt-xmask xwin) nil
258 (xwem-batt-pixmap xwin) nil
259 (xwem-batt-old-dheight xwin) nil
260 (xwem-batt-old-ac-line-p xwin) nil)
262 ;; Remove events handler
263 (X-Win-EventHandler-rem xwin 'xwem-batt-event-handler)
266 (XDestroyWindow (xwem-dpy) xwin)))
268 (defvar xwem-battery-keymap
269 (let ((map (make-sparse-keymap)))
270 (define-key map [button1] 'xwem-battery-status)
271 (define-key map [button3] 'xwem-battery-popup-menu)
273 "*Keymap for battery dock.")
275 (defvar xwem-battery-keymap
276 (let ((map (make-sparse-keymap)))
277 (define-key map [button1] 'xwem-battery-status)
278 (define-key map [button3] 'xwem-battery-popup-menu)
280 "*Keymap for battery dock.")
282 (defun xwem-batt-event-handler (xdpy win xev)
283 "Event handler for xwem battery monitor."
285 (:X-MapNotify (xwem-batt-win-update win t))
286 (:X-Expose (xwem-batt-apply-pixmap win))
287 (:X-DestroyNotify (xwem-batt-win-remove win))
289 (xwem-overriding-local-map xwem-battery-keymap
290 (xwem-dispatch-command-xevent xev)))))
293 (defun xwem-battery (&optional dockip dockgroup dockalign)
294 "Start xwem apm battery monitor in system tray."
296 (unless (fboundp 'apm-battery)
297 (error "APM Battery module not loaded"))
299 (let ((bxwin (xwem-batt-init (xwem-dpy))))
301 (when xwem-misc-turbo-mode
302 (XSetWindowBackgroundPixmap (xwem-dpy) bxwin (xwem-batt-pixmap bxwin)))
304 (XSelectInput (xwem-dpy) bxwin
305 (Xmask-or XM-Exposure XM-StructureNotify
306 XM-ButtonPress XM-ButtonRelease))
307 (X-Win-EventHandler-add bxwin 'xwem-batt-event-handler nil
308 (list X-Expose X-DestroyNotify
309 X-ButtonPress X-ButtonRelease))
311 (xwem-XTrayInit (xwem-dpy) bxwin dockip dockgroup dockalign)
313 (setf (xwem-batt-itimer bxwin)
314 (start-itimer "xwem-batt"
315 `(lambda () (xwem-batt-win-update ,bxwin))
316 xwem-batt-update-interval
317 xwem-batt-update-interval))
320 ;;;###autoload(autoload 'xwem-battery-status "xwem-battery" nil t)
321 (define-xwem-command xwem-battery-status ()
322 "Show battery status in xwem minibuffer."
325 (ac-line status perc)
326 (or (apm-battery) '(nil nil nil))
328 'info "APM Battery: AC-line: %s, Status: %S, Percentage: %d%%"
329 (if ac-line "on" "off") status perc)))
331 ;;;###autoload(autoload 'xwem-battery-popup-menu "xwem-battery" nil t)
332 (define-xwem-command xwem-battery-popup-menu (ev)
333 "Popup battery menu."
334 (xwem-interactive (list xwem-last-event))
335 (unless (button-event-p ev)
337 "`xwem-battery-popup-menu' must be bound to mouse event"))
340 ["Status" xwem-battery-status]
343 `(xwem-batt-win-remove
344 ,(X-Event-win xwem-last-xevent) t)))))
346 ;;;; In case there is no battery.ell
347 (unless (fboundp 'apm-battery)
348 (defvar apm-program "apm")
349 (defvar apm-state-percent-arguments "-bl")
350 (defvar apm-status-alist
351 '((0 . high) (1 . low) (2 . critical) (3 . charging)))
353 (defun apm-battery ()
354 "Return battery status."
355 (let (state percents)
357 (call-process apm-program nil (current-buffer)
358 nil apm-state-percent-arguments)
359 (goto-char (point-min))
360 (setq state (cdr (assq (string-to-int
361 (buffer-substring (point-at-bol)
365 (setq percents (string-to-int
366 (buffer-substring (point-at-bol)
368 (list (eq state 'charging) state percents))))
371 (provide 'xwem-battery)
373 ;;; xwem-battery.el ends here