1 ;;; xwem-time.el --- Time Date Load and Mail display in tray.
3 ;; Copyright (C) 2003-2005 by XWEM Org.
5 ;; Author: Zajcev Evgeny <zevlg@yandex.ru>
6 ;; Steve Youngs <steve@youngs.au.com>
7 ;; Created: Mon Dec 8 09:53:42 MSK 2003
8 ;; Keywords: xwem, xlib
9 ;; X-CVS: $Id: xwem-time.el,v 1.8 2005-04-04 19:54:16 lg 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 ;; `display-time' like application, which starts in system tray and
33 ;; shows current time, load average and mail status.
35 ;; To start using it, add:
37 ;; (autoload 'xwem-time "xwem-time" "Start `display-time' like app in system tray.")
38 ;; (add-hook 'xwem-after-init-hook 'xwem-time)
49 (require 'xlib-xshape)
57 (defgroup xwem-time nil
58 "Group to customize XWEM time display."
62 (defcustom xwem-time-format '(time load mail)
63 "*Format to display time/load/mail.
64 List of keywords, where each keyword is either:
67 load - Display load average
68 mail - Display mail status."
69 :type '(list (choice (const :tag "Time" time)
70 (const :tag "Load average" load)
71 (const :tag "Mail status" mail)))
72 :set (lambda (sym val)
75 (xwem-time-reformat xwem-time-win)))
76 :initialize 'custom-initialize-default
79 (defcustom xwem-time-format-distance 3
80 "*Distance in pixels between time/load/mail items."
85 (defcustom xwem-time-time-color "#CA1E1C"
86 "Foreground color to display time."
90 (defcustom xwem-time-update-interval 1
91 "*Seconds between updates of xwem time window."
96 (defcustom xwem-time-load-list
97 (list 0.10 0.20 0.30 0.40 0.50 0.60 0.80 1.0 1.2 1.5 1.8)
98 "*A list giving six thresholds for the load
99 which correspond to the six different icons to be displayed
100 as a load indicator."
101 :type '(list (number :tag "Threshold 1")
102 (number :tag "Threshold 2")
103 (number :tag "Threshold 3")
104 (number :tag "Threshold 4")
105 (number :tag "Threshold 5")
106 (number :tag "Threshold 6")
107 (number :tag "Threshold 7")
108 (number :tag "Threshold 8")
109 (number :tag "Threshold 9")
110 (number :tag "Threshold 10")
111 (number :tag "Threshold 11"))
114 (defcustom xwem-time-load-interval 5
115 "*Seconds between load average updates."
120 (defcustom xwem-time-get-mail-function 'xwem-time-default-get-mail
121 "Function to call in order to check mail availability."
125 (defvar xwem-time-map
126 (let ((map (make-sparse-keymap)))
127 (define-key map [button1] 'xwem-time-show-current-time-and-date)
128 (define-key map [button3] 'xwem-time-popup-menu)
130 "Keymap used when clicking time dockapp.")
133 ;;; Internal variables
134 (defvar xwem-time-dockapp-height 13)
136 (defconst xwem-time-digit-width 9)
137 (defconst xwem-time-ampm-width 4)
138 (defconst xwem-time-load-width 10)
139 (defconst xwem-time-mail-width 18)
142 (defvar xwem-time-xpm-empty-digit (concat "/* XPM */\n"
143 "static char *noname[] = {\n"
144 "/* width height ncolors chars_per_pixel */\n"
147 "\"` c None s ledbg\",\n"
148 "\"a c black s ledfg\",\n"
165 (defvar xwem-time-xpm-time0 '(concat "/* XPM */\n"
166 "static char *noname[] = {\n"
167 "/* width height ncolors chars_per_pixel */\n"
170 "\"` c None s ledbg\",\n"
171 "\"a c " xwem-time-time-color " s ledfg\",\n"
188 (defvar xwem-time-xpm-time1 '(concat "/* XPM */\n"
189 "static char *noname[] = {\n"
190 "/* width height ncolors chars_per_pixel */\n"
193 "\"` c None s ledbg\",\n"
194 "\"a c " xwem-time-time-color " s ledfg\",\n"
211 (defconst xwem-time-xpm-time2 '(concat "/* XPM */\n"
212 "static char *noname[] = {\n"
213 "/* width height ncolors chars_per_pixel */\n"
216 "\"` c None s ledbg\",\n"
217 "\"a c " xwem-time-time-color " s ledfg\",\n"
234 (defconst xwem-time-xpm-time3 '(concat "/* XPM */\n"
235 "static char *noname[] = {\n"
236 "/* width height ncolors chars_per_pixel */\n"
239 "\"` c None s ledbg\",\n"
240 "\"a c " xwem-time-time-color " s ledfg\",\n"
257 (defconst xwem-time-xpm-time4 '(concat "/* XPM */\n"
258 "static char *noname[] = {\n"
259 "/* width height ncolors chars_per_pixel */\n"
262 "\"` c None s ledbg\",\n"
263 "\"a c " xwem-time-time-color " s ledfg\",\n"
281 (defconst xwem-time-xpm-time5 '(concat "/* XPM */\n"
282 "static char *noname[] = {\n"
283 "/* width height ncolors chars_per_pixel */\n"
286 "\"` c None s ledbg\",\n"
287 "\"a c " xwem-time-time-color " s ledfg\",\n"
304 (defconst xwem-time-xpm-time6 '(concat "/* XPM */\n"
305 "static char *noname[] = {\n"
306 "/* width height ncolors chars_per_pixel */\n"
309 "\"` c None s ledbg\",\n"
310 "\"a c " xwem-time-time-color " s ledfg\",\n"
327 (defconst xwem-time-xpm-time7 '(concat "/* XPM */\n"
328 "static char *noname[] = {\n"
329 "/* width height ncolors chars_per_pixel */\n"
332 "\"` c None s ledbg\",\n"
333 "\"a c " xwem-time-time-color " s ledfg\",\n"
350 (defconst xwem-time-xpm-time8 '(concat "/* XPM */\n"
351 "static char *noname[] = {\n"
352 "/* width height ncolors chars_per_pixel */\n"
355 "\"` c None s ledbg\",\n"
356 "\"a c " xwem-time-time-color " s ledfg\",\n"
373 (defconst xwem-time-xpm-time9 '(concat "/* XPM */\n"
374 "static char *noname[] = {\n"
375 "/* width height ncolors chars_per_pixel */\n"
378 "\"` c None s ledbg\",\n"
379 "\"a c " xwem-time-time-color " s ledfg\",\n"
396 (defconst xwem-time-xpm-am '(concat "/* XPM */\n"
397 "static char *noname[] = {\n"
398 "/* width height ncolors chars_per_pixel */\n"
401 "\"` c None s ledbg\",\n"
402 "\"a c " xwem-time-time-color " s ledfg\",\n"
419 (defconst xwem-time-xpm-dp '(concat "/* XPM */\n"
420 "static char *noname[] = {\n"
421 "/* width height ncolors chars_per_pixel */\n"
424 "\"` c None s ledbg\",\n"
425 "\"a c " xwem-time-time-color " s ledfg\",\n"
442 (defconst xwem-time-xpm-pm '(concat "/* XPM */\n"
443 "static char *noname[] = {\n"
444 "/* width height ncolors chars_per_pixel */\n"
447 "\"` c None s ledbg\",\n"
448 "\"a c " xwem-time-time-color " s ledfg\",\n"
465 (defconst xwem-time-xpm-load00 (concat "/* XPM */\n"
466 "static char *noname[] = {\n"
467 "/* width height ncolors chars_per_pixel */\n"
470 "\"` s None c None\",\n"
471 "\". s pad-color c #606060\",\n"
488 (defconst xwem-time-xpm-load05 (concat "/* XPM */\n"
489 "static char *noname[] = {\n"
490 "/* width height ncolors chars_per_pixel */\n"
493 "\"` s None c None\",\n"
495 "\". s pad-color c #606060\",\n"
512 (defconst xwem-time-xpm-load10 (concat "/* XPM */"
513 "static char *noname[] = {\n"
514 "/* width height ncolors chars_per_pixel */\n"
517 "\"` s None c None\",\n"
519 "\". s pad-color c #606060\",\n"
536 (defconst xwem-time-xpm-load15 (concat "/* XPM */"
537 "static char *noname[] = {\n"
538 "/* width height ncolors chars_per_pixel */\n"
541 "\"` s None c None\",\n"
543 "\". s pad-color c #606060\",\n"
560 (defconst xwem-time-xpm-load20 (concat "/* XPM */\n"
561 "static char *noname[] = {\n"
562 "/* width height ncolors chars_per_pixel */\n"
565 "\"` s None c None\",\n"
568 "\". s pad-color c #606060\",\n"
585 (defconst xwem-time-xpm-load25 (concat "/* XPM */\n"
586 "static char *noname[] = {\n"
587 "/* width height ncolors chars_per_pixel */\n"
590 "\"` s None c None\",\n"
593 "\". s pad-color c #606060\",\n"
610 (defconst xwem-time-xpm-load30 (concat "/* XPM */\n"
611 "static char *noname[] = {\n"
612 "/* width height ncolors chars_per_pixel */\n"
615 "\"` s None c None\",\n"
618 "\". s pad-color c #606060\",\n"
635 (defconst xwem-time-xpm-load35 (concat "/* XPM */\n"
636 "static char *noname[] = {\n"
637 "/* width height ncolors chars_per_pixel */\n"
640 "\"` s None c None\",\n"
643 "\". s pad-color c #606060\",\n"
660 (defconst xwem-time-xpm-load40 (concat "/* XPM */\n"
661 "static char *noname[] = {\n"
662 "/* width height ncolors chars_per_pixel */\n"
665 "\"a s None c None\",\n"
669 "\". s pad-color c #606060\",\n"
686 (defconst xwem-time-xpm-load45 (concat "/* XPM */\n"
687 "static char *noname[] = {\n"
688 "/* width height ncolors chars_per_pixel */\n"
691 "\"a s None c None\",\n"
695 "\". s pad-color c #606060\",\n"
712 (defconst xwem-time-xpm-load50 (concat "/* XPM */\n"
713 "static char *noname[] = {\n"
714 "/* width height ncolors chars_per_pixel */\n"
717 "\"a s None c None\",\n"
721 "\". s pad-color c #606060\",\n"
738 (defconst xwem-time-xpm-load55 (concat "/* XPM */\n"
739 "static char *noname[] = {\n"
740 "/* width height ncolors chars_per_pixel */\n"
743 "\"a s None c None\",\n"
747 "\". s pad-color c #606060\",\n"
765 (defconst xwem-time-xpm-letter (concat "/* XPM */\n"
766 "static char * jmail_xpm[] = {\n"
768 "\" s None c None\",\n"
774 "\" .XXXXXXXXXXX. \",\n"
775 "\" XoXXXXXXXXXoXoo\",\n"
776 "\" XXoXXXXXXXoXXoo\",\n"
777 "\" XXXoXXXXXoXXXoo\",\n"
778 "\" XXX.oXXXo.XXXoo\",\n"
779 "\" XXXo.oXo.oXXXoo\",\n"
780 "\" XXoXXXoXXXoXXoo\",\n"
781 "\" XoXXXXXXXXXoXoo\",\n"
782 "\" .XXXXXXXXXXX.oo\",\n"
783 "\" ooooooooooooo\",\n"
784 "\" ooooooooooooo\"};\n"))
786 (defconst xwem-time-xpm-no-letter (concat "/* XPM */\n"
787 "static char * jmail_xpm[] = {\n"
789 "\" s None c None\",\n"
795 "\" ooooooooooooox \",\n"
796 "\" o.xxxxxxxxx.ox \",\n"
798 "\" ox ox ox ox \",\n"
799 "\" ox ox ox ox \",\n"
800 "\" ox oxoxoxox ox \",\n"
801 "\" oxox ox oxox \",\n"
803 "\" ooooooooooooox \",\n"
804 "\" xxxxxxxxxxxxxx \",\n"
809 ;;; Huge amount of macroses
810 (defvar xwem-time-win nil)
812 (defmacro xwem-time-win (&optional win)
813 `(or ,win xwem-time-win))
814 (defsetf xwem-time-win () (win)
815 `(setq xwem-time-win ,win))
816 (defmacro xwem-time-get-prop (win prop)
817 `(X-Win-get-prop (xwem-time-win ,win) ,prop))
818 (defmacro xwem-time-set-prop (win prop val)
819 `(X-Win-put-prop (xwem-time-win ,win) ,prop ,val))
821 (defmacro xwem-time-mask (&optional win)
822 `(xwem-time-get-prop ,win 'time-mask))
823 (defsetf xwem-time-mask (&optional win) (mask)
824 `(xwem-time-set-prop ,win 'time-mask ,mask))
826 (defmacro xwem-time-pixmap (&optional win)
827 `(xwem-time-get-prop ,win 'time-pixmap))
828 (defsetf xwem-time-pixmap (&optional win) (pixmap)
829 `(xwem-time-set-prop ,win 'time-pixmap ,pixmap))
832 (defmacro xwem-time-digits-pixmaps (&optional win)
833 `(xwem-time-get-prop ,win 'time-digits-pixmaps))
834 (defsetf xwem-time-digits-pixmaps (&optional win) (pixs)
835 `(xwem-time-set-prop ,win 'time-digits-pixmaps ,pixs))
836 (defmacro xwem-time-digit-add (win digit pix pix-mask)
837 `(setf (xwem-time-digits-pixmaps ,win)
838 (cons (cons ,digit (cons ,pix ,pix-mask))
839 (xwem-time-digits-pixmaps ,win))))
840 (defmacro xwem-time-digit-get-pix (win digit)
841 `(car (cdr (assq ,digit (xwem-time-digits-pixmaps ,win)))))
842 (defmacro xwem-time-digit-get-mask (win digit)
843 `(cdr (cdr (assq ,digit (xwem-time-digits-pixmaps ,win)))))
846 (defmacro xwem-time-load-pixmaps (&optional win)
847 `(xwem-time-get-prop ,win 'time-load-pixmaps))
848 (defsetf xwem-time-load-pixmaps (&optional win) (pixs)
849 `(xwem-time-set-prop ,win 'time-load-pixmaps ,pixs))
850 (defmacro xwem-time-load-add (win load pix pix-mask)
851 `(setf (xwem-time-load-pixmaps ,win)
852 (cons (cons ,load (cons ,pix ,pix-mask))
853 (xwem-time-load-pixmaps ,win))))
854 (defmacro xwem-time-load-get-pix (win load)
855 `(car (cdr (assq ,load (xwem-time-load-pixmaps ,win)))))
856 (defmacro xwem-time-load-get-mask (win load)
857 `(cdr (cdr (assq ,load (xwem-time-load-pixmaps ,win)))))
860 (defmacro xwem-time-mail-pixmaps (&optional win)
861 `(xwem-time-get-prop ,win 'time-mail-pixmaps))
862 (defsetf xwem-time-mail-pixmaps (&optional win) (pixs)
863 `(xwem-time-set-prop ,win 'time-mail-pixmaps ,pixs))
864 (defmacro xwem-time-mail-add (win mail pix pix-mask)
865 `(setf (xwem-time-mail-pixmaps ,win)
866 (cons (cons ,mail (cons ,pix ,pix-mask))
867 (xwem-time-mail-pixmaps ,win))))
868 (defmacro xwem-time-mail-get-pix (win mail)
869 `(car (cdr (assq ,mail (xwem-time-mail-pixmaps ,win)))))
870 (defmacro xwem-time-mail-get-mask (win mail)
871 `(cdr (cdr (assq ,mail (xwem-time-mail-pixmaps ,win)))))
874 (defmacro xwem-time-saved-state (&optional win)
875 `(xwem-time-get-prop (xwem-time-win ,win) 'time-saved-state))
876 (defsetf xwem-time-saved-state (&optional win) (state)
877 `(xwem-time-set-prop (xwem-time-win ,win) 'time-saved-state ,state))
878 (defmacro xwem-time-get-state (win state)
879 `(plist-get (xwem-time-saved-state ,win) ,state))
880 (defmacro xwem-time-set-state (win state val)
881 `(setf (xwem-time-saved-state ,win)
882 (plist-put (xwem-time-saved-state ,win) ,state ,val)))
884 (defmacro xwem-time-itimer (&optional win)
885 `(xwem-time-get-prop ,win 'time-itimer))
886 (defsetf xwem-time-itimer (&optional win) (itimer)
887 `(xwem-time-set-prop ,win 'time-itimer ,itimer))
889 ;; Format related stuff
890 (defsubst xwem-time-format-tag-width (tag)
892 (time (* 5 xwem-time-digit-width))
893 (load xwem-time-load-width)
894 (mail xwem-time-mail-width)))
895 (defmacro xwem-time-format-offset (tag)
896 `(let ((fmt xwem-time-format)
898 (while (and fmt (not (eq (car fmt) ,tag)))
899 (incf off (xwem-time-format-tag-width (car fmt)))
900 (incf off xwem-time-format-distance)
901 (setq fmt (cdr fmt)))
903 (defmacro xwem-time-format-width ()
904 `(+ (apply '+ (mapcar 'xwem-time-format-tag-width xwem-time-format))
905 (* (1- (length xwem-time-format)) xwem-time-format-distance)))
906 (defmacro xwem-time-format-height ()
907 'xwem-time-dockapp-height)
910 (defun xwem-time-get-time ()
911 "Return current time in format acceptable by `xwem-time-update-time'."
912 (mapcar 'identity (substring (current-time-string) 11 16)))
914 (defun xwem-time-get-load ()
915 "Return load average in format acceptable by `xwem-time-update-load'."
916 (let ((alist (list (cons 0 0.0)
917 (cons 5 (nth 0 xwem-time-load-list))
918 (cons 10 (nth 1 xwem-time-load-list))
919 (cons 15 (nth 2 xwem-time-load-list))
920 (cons 20 (nth 3 xwem-time-load-list))
921 (cons 25 (nth 4 xwem-time-load-list))
922 (cons 30 (nth 5 xwem-time-load-list))
923 (cons 35 (nth 6 xwem-time-load-list))
924 (cons 40 (nth 7 xwem-time-load-list))
925 (cons 45 (nth 8 xwem-time-load-list))
926 (cons 50 (nth 9 xwem-time-load-list))
927 (cons 55 (nth 10 xwem-time-load-list))
928 (cons 100000 100000)))
929 (load-number (car (load-average t)))
931 (while (>= load-number (cdr (setq elem (pop alist))))
932 (setq load-elem elem))
935 (defun xwem-time-default-get-mail ()
936 "Default function to search for new mail."
937 (let* ((now (current-time))
938 (nowhigh (* (- (nth 0 now) (* (/ (nth 0 now) 10) 10)) 65536))
939 (mail-spool-file (or display-time-mail-file
941 (concat rmail-spool-directory
943 (mail (and (stringp mail-spool-file)
944 (or (null display-time-server-down-time)
945 ;; If have been down for 20 min, try again.
946 (> (- (+ (nth 1 now) nowhigh)
947 display-time-server-down-time)
949 (let ((start-time (current-time)))
951 (display-time-file-nonempty-p mail-spool-file)
952 (setq now (current-time)
953 nowhigh (* (- (nth 0 now) (* (/ (nth 0 now) 10) 10)) 65536))
954 (if (> (- (+ (nth 1 now) nowhigh)
955 (+ (nth 1 start-time)
956 (* (- (nth 0 start-time)
957 (* (/ (nth 0 start-time) 10) 10))
960 ;; Record that mail file is not accessible.
961 (setq display-time-server-down-time
962 (+ (nth 1 now) nowhigh))
963 ;; Record that mail file is accessible.
964 (setq display-time-server-down-time nil)))))))
967 (defun xwem-time-get-mail ()
968 "Return mail status in format acceptable by `xwem-time-update-mail'."
969 (if xwem-time-get-mail-function
970 (if (funcall xwem-time-get-mail-function)
973 (xwem-time-default-get-mail)))
975 (define-xwem-deffered xwem-time-update (win)
976 "Update time window WIN."
977 (X-XShapeMask (xwem-dpy) win X-XShape-Bounding X-XShapeSet 0 0
978 (xwem-time-mask win))
979 (XCopyArea (xwem-dpy) (xwem-time-pixmap win) win
980 (XDefaultGC (xwem-dpy)) 0 0
981 (xwem-time-format-width) (xwem-time-format-height)
984 (defun xwem-time-update-digit (win digit-position digit)
985 "Update WIN's DIGIT-POSITION to display DIGIT."
986 (let ((off (+ (xwem-time-format-offset 'time)
987 (* digit-position xwem-time-digit-width))))
988 (XCopyArea (xwem-dpy) (xwem-time-digit-get-mask win digit)
989 (xwem-time-mask win) xwem-misc-mask-fgc 0 0
990 xwem-time-digit-width xwem-time-dockapp-height
992 (XCopyArea (xwem-dpy) (xwem-time-digit-get-pix win digit)
993 (xwem-time-pixmap win) (XDefaultGC (xwem-dpy)) 0 0
994 xwem-time-digit-width xwem-time-dockapp-height
996 (xwem-time-update win)))
998 (defun xwem-time-update-time (win new-time)
999 "Update WIN to display NEW-TIME."
1000 (let ((st (or (xwem-time-get-state win 'time) '(-1 -1 -1 -1 -1)))
1002 (mapc (lambda (t1 t2)
1004 (xwem-time-update-digit win dpos t2))
1007 (xwem-time-set-state win 'time new-time)))
1009 (defun xwem-time-update-load (win new-load)
1010 "Update WIN to display NEW-LOAD."
1011 (let ((sl (or (xwem-time-get-state win 'load) -1)))
1012 (unless (= sl new-load)
1013 (let ((off (xwem-time-format-offset 'load)))
1014 (XCopyArea (xwem-dpy) (xwem-time-load-get-mask win new-load)
1015 (xwem-time-mask win) xwem-misc-mask-fgc 0 0
1016 xwem-time-load-width xwem-time-dockapp-height
1018 (XCopyArea (xwem-dpy) (xwem-time-load-get-pix win new-load)
1019 (xwem-time-pixmap win) (XDefaultGC (xwem-dpy)) 0 0
1020 xwem-time-load-width xwem-time-dockapp-height
1022 (xwem-time-update win)))
1023 (xwem-time-set-state win 'load new-load)))
1025 (defun xwem-time-update-mail (win new-mail)
1026 "Update WIN to display NEW-MAIL."
1027 (let ((sl (xwem-time-get-state win 'mail)))
1028 (unless (eq sl new-mail)
1029 (let ((off (xwem-time-format-offset 'mail)))
1030 (XCopyArea (xwem-dpy) (xwem-time-mail-get-mask win new-mail)
1031 (xwem-time-mask win) xwem-misc-mask-fgc 0 0
1032 xwem-time-mail-width xwem-time-dockapp-height
1034 (XCopyArea (xwem-dpy) (xwem-time-mail-get-pix win new-mail)
1035 (xwem-time-pixmap win) (XDefaultGC (xwem-dpy)) 0 0
1036 xwem-time-mail-width xwem-time-dockapp-height
1038 (xwem-time-update win)))
1039 (xwem-time-set-state win 'mail new-mail)))
1041 (defun xwem-time-create-win (xdpy)
1042 "On display XDPY create time dockapp window."
1043 (let ((gc-cons-threshold most-positive-fixnum) ; inhibit gc
1044 (win (XCreateWindow xdpy (XDefaultRootWindow xdpy)
1045 0 0 (xwem-time-format-width)
1046 (xwem-time-format-height) 0
1048 (make-X-Attr :event-mask (Xmask-or XM-Exposure XM-StructureNotify
1049 XM-ButtonPress XM-ButtonRelease)
1050 :override-redirect t))))
1051 ;; Create mask pixmap and bs pixmap
1052 (setf (xwem-time-mask win)
1053 (XCreatePixmap (xwem-dpy) (make-X-Pixmap :dpy (xwem-dpy) :id (X-Dpy-get-id (xwem-dpy)))
1054 win 1 (xwem-time-format-width) (xwem-time-format-height)))
1055 (XFillRectangle (xwem-dpy) (xwem-time-mask win)
1056 xwem-misc-mask-bgc 0 0 (xwem-time-format-width) (xwem-time-format-height))
1058 (setf (xwem-time-pixmap win)
1059 (XCreatePixmap (xwem-dpy) (make-X-Pixmap :dpy (xwem-dpy)
1060 :id (X-Dpy-get-id (xwem-dpy)))
1061 win (XDefaultDepth (xwem-dpy))
1062 (xwem-time-format-width) (xwem-time-format-height)))
1063 (when xwem-misc-turbo-mode
1064 (XSetWindowBackgroundPixmap (xwem-dpy) win (xwem-time-pixmap win)))
1066 ; (XFillRectangle (xwem-dpy) (xwem-time-pixmap win)
1067 ; (XDefaultGC (xwem-dpy)) 0 0
1068 ; (xwem-time-format-width) (xwem-time-format-height))
1070 ;; Load digits pixmaps
1071 (mapc (lambda (digit)
1072 (let* ((sym (intern (format "xwem-time-xpm-time%c" digit)))
1073 (sval (symbol-value sym)))
1074 (xwem-time-digit-add
1075 win digit (X:xpm-pixmap-from-data xdpy win (eval sval))
1076 (X:xpm-pixmap-from-data xdpy win (eval sval) t))))
1078 ;; Empty digit and Colon
1079 (xwem-time-digit-add win ?\x20 (X:xpm-pixmap-from-data xdpy win xwem-time-xpm-empty-digit)
1080 (X:xpm-pixmap-from-data xdpy win xwem-time-xpm-empty-digit t))
1081 (xwem-time-digit-add win ?: (X:xpm-pixmap-from-data xdpy win (eval xwem-time-xpm-dp))
1082 (X:xpm-pixmap-from-data xdpy win (eval xwem-time-xpm-dp) t))
1084 ;; Load load pixmaps
1085 (mapc (lambda (load)
1086 (let* ((sym (intern (format "xwem-time-xpm-load%.2d" load)))
1087 (sval (symbol-value sym)))
1089 win load (X:xpm-pixmap-from-data xdpy win sval)
1090 (X:xpm-pixmap-from-data xdpy win sval t))))
1091 (loop for i from 0 to 55 by 5 collect i))
1093 ;; Load mail pixmaps
1094 (xwem-time-mail-add win 'letter (X:xpm-pixmap-from-data xdpy win xwem-time-xpm-letter)
1095 (X:xpm-pixmap-from-data xdpy win xwem-time-xpm-letter t))
1096 (xwem-time-mail-add win 'no-letter (X:xpm-pixmap-from-data xdpy win xwem-time-xpm-no-letter)
1097 (X:xpm-pixmap-from-data xdpy win xwem-time-xpm-no-letter t))
1099 ;; Install event handler
1100 (X-Win-EventHandler-add win 'xwem-time-event-handler nil
1101 (list X-Expose X-MapNotify X-DestroyNotify
1102 X-ButtonPress X-ButtonRelease))
1104 ;; Set default time window
1105 (unless xwem-time-win
1106 (setq xwem-time-win win))
1109 (XFillRectangle xdpy (xwem-time-mask win) xwem-misc-mask-bgc 0 0
1110 (xwem-time-format-width) (xwem-time-format-height))
1111 (X-XShapeMask (xwem-dpy) win X-XShape-Bounding X-XShapeSet 0 0
1112 (xwem-time-mask win))
1116 (defun xwem-time-maybe-update (win)
1118 (when (memq 'time xwem-time-format)
1119 (xwem-time-update-time win (xwem-time-get-time)))
1120 (when (memq 'load xwem-time-format)
1121 (xwem-time-update-load win (xwem-time-get-load)))
1122 (when (memq 'mail xwem-time-format)
1123 (xwem-time-update-mail win (xwem-time-get-mail)))
1125 (unless (xwem-time-itimer win)
1126 (setf (xwem-time-itimer win)
1127 (start-itimer "xwem-time-update" 'xwem-time-maybe-update
1128 xwem-time-update-interval xwem-time-update-interval
1131 (defun xwem-time-remove (win &optional no-destroy)
1133 (when (xwem-time-itimer win)
1134 (delete-itimer (xwem-time-itimer win))
1135 (setf (xwem-time-itimer win) nil))
1138 (XFreePixmap (xwem-dpy) (car (cdr pp)))
1139 (XFreePixmap (xwem-dpy) (cdr (cdr pp))))
1140 (append (xwem-time-digits-pixmaps win)
1141 (xwem-time-load-pixmaps win)
1142 (xwem-time-mail-pixmaps win)))
1144 (XFreePixmap (xwem-dpy) (xwem-time-mask win))
1145 (XFreePixmap (xwem-dpy) (xwem-time-pixmap win))
1147 (setf (xwem-time-digits-pixmaps win) nil
1148 (xwem-time-load-pixmaps win) nil
1149 (xwem-time-mail-pixmaps win) nil
1150 (xwem-time-mask win) nil
1151 (xwem-time-pixmap win) nil
1152 (xwem-time-saved-state win) nil)
1154 ;; Remove event handler
1155 (X-Win-EventHandler-rem win 'xwem-time-event-handler)
1157 ;; Unset default xwem-time-win
1158 (when (eq xwem-time-win win)
1159 (setq xwem-time-win nil))
1162 (XDestroyWindow (xwem-dpy) win)))
1164 (defun xwem-time-event-handler (xdpy win xev)
1165 "On display XDPY and window WIN handle event XEV."
1167 (:X-MapNotify (xwem-time-maybe-update win))
1168 (:X-Expose (xwem-time-update win))
1169 (:X-DestroyNotify (xwem-time-remove win t))
1170 ((:X-ButtonPress :X-ButtonRelease)
1171 (let ((xwem-override-local-map xwem-time-map))
1172 (xwem-dispatch-command-xevent xev)))))
1175 (defun xwem-time (&optional dockid dockgroup dockalign)
1176 "Start xwem time window in system tray."
1178 (xwem-XTrayInit (xwem-dpy) (xwem-time-create-win (xwem-dpy))
1179 dockid dockgroup dockalign)
1182 (define-xwem-command xwem-time-show-current-time-and-date ()
1183 "Display current time and date in the minibuffer."
1185 (xwem-message 'info "Time: %s, Load: %S"
1186 (current-time-string) (load-average)))
1188 (define-xwem-command xwem-time-popup-menu ()
1189 "Popup menu for time dockapp."
1192 (unless (button-event-p xwem-last-event)
1193 (error 'xwem-error "`xwem-time-popup-menu' must be bound to mouse event"))
1198 (vector "Show Time" 'xwem-time-show-current-time-and-date)
1200 (vector "Destroy" `(xwem-time-remove , (X-Event-win xwem-last-xevent))))))
1203 (provide 'xwem-time)
1205 ;;; xwem-time.el ends here