1 ;; emchat-xwem.el --- Activity indicator for XWEM tray
3 ;; Copyright (C) 2005 - 2011 Steve Youngs
5 ;; Author: Steve Youngs <steve@emchat.org>
6 ;; Maintainer: Steve Youngs <steve@emchat.org>
7 ;; Created: <2005-10-15>
8 ;; Homepage: http://www.emchat.org/
9 ;; Keywords: emchat, icq, xwem, dock, tray
11 ;; This file is part of EMchat.
13 ;; Redistribution and use in source and binary forms, with or without
14 ;; modification, are permitted provided that the following conditions
17 ;; 1. Redistributions of source code must retain the above copyright
18 ;; notice, this list of conditions and the following disclaimer.
20 ;; 2. Redistributions in binary form must reproduce the above copyright
21 ;; notice, this list of conditions and the following disclaimer in the
22 ;; documentation and/or other materials provided with the distribution.
24 ;; 3. Neither the name of the author nor the names of any contributors
25 ;; may be used to endorse or promote products derived from this
26 ;; software without specific prior written permission.
28 ;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
29 ;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 ;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31 ;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 ;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 ;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 ;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35 ;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36 ;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37 ;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
38 ;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ;; Puts a spiffy activity indicator into the XWEM systray.
43 ;; To use this, add...
45 ;; (require 'emchat-xwem)
46 ;; (add-hook 'xwem-after-init-hook 'emchat-xwem-init)
48 ;; ...to your ~/.xwem/xwemrc.el
53 ;; o Add more XWEM things... can't think of any right now.
57 (require 'font) ;; for font-x-registry-and-encoding-regexp
60 (autoload 'xwem-dpy "xwem-struct" nil nil 'macro)
61 (autoload 'xwem-message "xwem-misc")
62 (autoload 'xwem-misc-find-cl-by-emacs-frame "xwem-misc")
63 (autoload 'xwem-osd-clear "xwem-osd")
64 (autoload 'xwem-osd-create "xwem-osd")
65 (autoload 'xwem-osd-create-dock "xwem-osd")
66 (autoload 'xwem-osd-destroy "xwem-osd")
67 (autoload 'xwem-osd-destroy-instances "xwem-osd")
68 (autoload 'xwem-osd-get-prop "xwem-osd")
69 (autoload 'xwem-osd-hide "xwem-osd")
70 (autoload 'xwem-osd-icon-data-add "xwem-osd")
71 (autoload 'xwem-osd-p "xwem-osd")
72 (autoload 'xwem-osd-put-prop "xwem-osd")
73 (autoload 'xwem-osd-rem-prop "xwem-osd")
74 (autoload 'xwem-osd-set-color "xwem-osd")
75 (autoload 'xwem-osd-set-font "xwem-osd")
76 (autoload 'xwem-osd-show "xwem-osd")
77 (autoload 'xwem-osd-text "xwem-osd")
78 (autoload 'xwem-osd-text-add "xwem-osd")
79 (autoload 'xwem-popup-menu "xwem-mouse")
80 (autoload 'xwem-select-client "xwem-clients")
81 (defvar xwem-current-cl)
84 (defgroup emchat-xwem nil
85 "Group to customize emchat's xwem capabilities."
87 :prefix "emchat-xwem-")
89 (defcustom emchat-xwem-osd-enable t
90 "*Non-nil to show incoming messages in OSD."
94 (defcustom emchat-xwem-dock-enable t
95 "*Non-nil to start emchat dock in system tray."
99 (defcustom emchat-xwem-osd-show-icon t
100 "*Non-nil to show ICQ icon in OSD as well as message."
104 (defcustom emchat-xwem-osd-font
105 (font-create-name (make-font :weight "bold" :size 32))
106 "Font to be used to display OSD message."
108 :type '(restricted-sexp :match-alternatives (nil try-font-name)))
110 (defcustom emchat-xwem-osd-color "magenta3"
111 "*Default color for OSD messages."
115 (defcustom emchat-xwem-osd-group-colors
116 '((:girls . "deeppink")
119 (:friends . "green3"))
120 "*Alist of colors to be used in OSD for emchat groups.
121 Each element is cons in form (GROUP . COLOR)."
123 :type '(repeat (cons (keyword :tag "group") color)))
125 (defcustom emchat-xwem-osd-coordinates '(100 . 700)
126 "*Place on screen for OSD messages."
128 :type '(cons (number :tag "X") (number :tag "Y")))
130 (defcustom emchat-xwem-osd-display-time 3
131 "*Time the OSD to be shown."
135 ;;; Internal variables
137 (defvar emchat-xwem-osd-icon
138 (concat "/* XPM */\n"
139 "static char *icq[] = {\n"
140 "/* columns rows colors chars-per-pixel */\n"
151 "\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.+.++@@@@@@@@@@@@@@@\",\n"
152 "\"@@@@@@@@@@@@@@++++++@@@@@@++. .+@@@@@@@@@@@@@\",\n"
153 "\"@@@@@@@@@@@@@+ .+@@@@+. +@@@@@@@@@@@@\",\n"
154 "\"@@@@@@@@@@@@+ .+@@++ .... .+@@@@@@@@@@@\",\n"
155 "\"@@@@@@@@@@@+ .. +@. oXXXXXo. +@@@@@@@@@@\",\n"
156 "\"@@@@@@@@@@@+ oXXo .+ oXXXXXXXo +@@@@@@@@@@\",\n"
157 "\"@@@@@@@@@@@+ .XXXXo XXXXXXXXXo .+@@@@@@@@@\",\n"
158 "\"@@@@@@@@@@@. oXXXXX. oXXXXXXXXXo .+@@@@@@@@@\",\n"
159 "\"@@@@@@@@@@@. oXXXXXX ooXXXXXXXXX +@@@@@@@@@\",\n"
160 "\"@@@@@@@@@@@+ oXXXXXX. oXXXXXXXXXo .+@@@@@@@@@\",\n"
161 "\"@@@@@@@@@@@+ XXXXXXo .XXXXXXXXX. .@@@@@@@@@@\",\n"
162 "\"@@@@@@@@@@@+ .XXXXoo oXXXXXXXXX ++++++@@@@@\",\n"
163 "\"@@@@@@++...++ oXXXXo .XXXXXXXX .. ..++@@@\",\n"
164 "\"@@@+++ . oXXXo .XXXXXXX. . .+@@\",\n"
165 "\"@@+. oXXX XXXXXX. .+@\",\n"
166 "\"@++ ..... oXX. oXXXXo .ooXo. +@\",\n"
167 "\"@+ XXXXXXo .XXo oXXXo XXXXXXXo .+\",\n"
168 "\"+. .XXXXXXXXo .oo oXXX .XXXXXXXXo .+\",\n"
169 "\"+ XXXXXXXXXXX. . .XX oXXXXXXXXXo .+\",\n"
170 "\"+ .XXXXXXXXXXXXo .. oXXXXXXXXXo +@\",\n"
171 "\". .XXXXXXXXXXXXXX. .oXXXXXXXXXo .+@\",\n"
172 "\". .XXXXXXXXXXXXXX .OOO. .oXXXXXoooo +@@\",\n"
173 "\"+ oXXXXXXXXXXXoo OOOOOOO .oo.. .+@@@\",\n"
174 "\"+. ooXooooo... .OOOOOOO. .+@@@@\",\n"
175 "\"@+. OOOOOOOOO .+@@@\",\n"
176 "\"@@+. OOOOOOOOO +@@\",\n"
177 "\"@@@++. OOOOOOOO. ..ooooo. +@\",\n"
178 "\"@@@@@+ # ### .OOOOOOO. .oXXXXXXXXXXXo. .+\",\n"
179 "\"@@@@+. ######## .OOOOO. oXXXXXXXXXXXXXo +\",\n"
180 "\"@@@+. ######### .OOO. .XXXXXXXXXXXXXX. +\",\n"
181 "\"@@@+ ######### .oXXXoXXXXXXXXo .\",\n"
182 "\"@@@+ ######### . . .oXXXXXXXXXXXo .\",\n"
183 "\"@@@+ ######## XXo ooXo oXXXXXXXXXXo .\",\n"
184 "\"@@@. ###### oXXX oXXX. oXXXXXXXXX. .\",\n"
185 "\"@@@+ oXXXX .XXXX. .XXXXXXXo +\",\n"
186 "\"@@@@+. oXXXXX. oXXXX .ooXXXo ++\",\n"
187 "\"@@@@@++. . ooXXXXX. oXXXXX. .. +@\",\n"
188 "\"@@@@@@@+++++ .XXXXXXX. oXXXXXo .+@@\",\n"
189 "\"@@@@@@@@@@@. XXXXXXXXo .XXXXXo ... ++@@@\",\n"
190 "\"@@@@@@@@@@+ oXXXXXXXX. .XXXXXX. +@++++++@@@@@\",\n"
191 "\"@@@@@@@@@@+ .XXXXXXXXXo XXXXXX. .@@@@@@@@@@@@\",\n"
192 "\"@@@@@@@@@@. .XXXXXXXXXo .XXXXX +@@@@@@@@@@@@\",\n"
193 "\"@@@@@@@@@@. .XXXXXXXXXo .XXXo +@@@@@@@@@@@@\",\n"
194 "\"@@@@@@@@@@+ .XXXXXXXXX. .oo. .+@@@@@@@@@@@@\",\n"
195 "\"@@@@@@@@@@+ XXXXXXXXX +. +@@@@@@@@@@@@@\",\n"
196 "\"@@@@@@@@@@+. .oXXXXXo. .@+.. ..@@@@@@@@@@@@@@\",\n"
197 "\"@@@@@@@@@@@+ ooXo. +@@@++..++@@@@@@@@@@@@@@@\",\n"
198 "\"@@@@@@@@@@@++ +@@@@@@@@@@@@@@@@@@@@@@@@@\",\n"
199 "\"@@@@@@@@@@@@@+. .+@@@@@@@@@@@@@@@@@@@@@@@@@@\",\n"
200 "\"@@@@@@@@@@@@@@++.....++@@@@@@@@@@@@@@@@@@@@@@@@@@@\"\n"
203 (defvar emchat-xwem-active
204 (concat "/* XPM */\n"
205 "static char *noname[] = {\n"
206 "/* columns rows colors chars-per-pixel */\n"
227 "\">>> + %&. >>>\",\n"
228 "\">>> +*$ $**% >>>\",\n"
229 "\">>> *& +**$ >\",\n"
231 "\" O**O O..& .**$ \",\n"
232 "\" &***$ oo O**% \",\n"
233 "\" O$+O #:: . >\",\n"
234 "\"> XX;::oO+++. \",\n"
235 "\"> @--@ #o %***& \",\n"
236 "\"> ==X $.OO +**& \",\n"
237 "\"> $*OO*O O+. \",\n"
238 "\">>> O**+.*& >\",\n"
239 "\">>> %**+ +& >>>>\",\n"
240 "\">>> .&& >>>>>\",\n"
241 "\">>>> >>>>>>>\>\"\n"
244 (defvar emchat-xwem-inactive
245 (concat "/* XPM */\n"
246 "static char *noname[] = {\n"
249 "\". c #000100 s foreground\",\n"
254 "\"o c gray s background\",\n"
257 "\" ..o...oo+. \",\n"
258 "\" .ooo.oooo. \",\n"
259 "\" ..oo.oooo... \",\n"
260 "\" ....oo.ooo..+..\",\n"
261 "\".oooo.o++o.oooo.\",\n"
262 "\".ooooo.@@.oooo..\",\n"
263 "\".oooo.ooo.+.... \",\n"
264 "\" ...#$ooo@oooo+.\",\n"
265 "\" .ooo#.o@.ooooo.\",\n"
266 "\" .oo$oo+oo.oooo.\",\n"
267 "\" ....ooo#oo.oo+.\",\n"
268 "\" .oooo#oo.... \",\n"
274 (defvar emchat-xwem-saved-client nil
275 "Saved selected xwem client.")
277 (defvar emchat-xwem-keymap
278 (let ((map (make-sparse-keymap)))
279 (define-key map [button1] 'emchat-xwem-select-emchat)
280 (define-key map [button3] 'emchat-xwem-restore-client)
282 "*Keymap for emchat dock.")
284 (defvar emchat-xwem-osd nil)
285 (defvar emchat-xwem-dock nil)
288 (defun emchat-xwem-activity-off ()
289 "Make the EMchat/XWEM activity indicator inactive."
290 (emchat-xwem-dock-change-icon emchat-xwem-inactive)
291 (emchat-xwem-osd-hide))
293 (defun emchat-xwem-activity-on ()
294 "Make the EMchat/XWEM activity indicator active."
295 (emchat-xwem-dock-change-icon emchat-xwem-active)
297 ;; NICK and MESSAGE are set by dynamic binding
298 (declare (special nick message))
299 (emchat-xwem-osd-show-message nick message))
301 (defun emchat-xwem-init ()
302 "*Display EMchat activity indicator."
305 ;; Possible create dock
306 (emchat-xwem-dock-change-icon emchat-xwem-inactive)
308 (add-hook 'emchat-track-activity-hook 'emchat-xwem-activity-on)
309 (add-hook 'emchat-track-clear-hook 'emchat-xwem-activity-off))
311 (defun emchat-xwem-fini ()
312 "Remove the EMchat activity indicator from the XWEM systray."
315 (emchat-xwem-dock-destroy)
316 (emchat-xwem-osd-destroy)
318 (remove-hook 'emchat-track-activity-hook 'emchat-xwem-activity-on)
319 (remove-hook 'emchat-track-clear-hook 'emchat-xwem-activity-off))
323 (defun emchat-xwem-osd-create ()
324 "Create OSD for emchat messages."
325 (setq emchat-xwem-osd
326 (xwem-osd-create (xwem-dpy) (car emchat-xwem-osd-coordinates)
327 (cdr emchat-xwem-osd-coordinates)
329 (xwem-osd-set-font emchat-xwem-osd emchat-xwem-osd-font))
331 (defun emchat-xwem-osd-destroy ()
332 "Destroy emchat OSD."
333 (when emchat-xwem-osd
334 (when (itimerp (xwem-osd-get-prop emchat-xwem-osd 'timer))
335 (delete-itimer (xwem-osd-get-prop emchat-xwem-osd 'timer)))
336 (xwem-osd-destroy emchat-xwem-osd)
337 (setq emchat-xwem-osd nil)))
339 (defun emchat-xwem-osd-color-for-nick (nick)
340 "Return OSD color to use for NICK."
341 (let ((groups (plist-get (assoc nick emchat-world) 'group)))
342 (or (cdr (find groups emchat-xwem-osd-group-colors
343 :key #'car :test #'(lambda (g i)
345 emchat-xwem-osd-color)))
347 (defun emchat-xwem-osd-show-message (nick message)
348 "Display NICK and MESSAGE in emchat OSD."
349 (when emchat-xwem-osd-enable
350 (unless emchat-xwem-osd
351 (emchat-xwem-osd-create))
353 ;; Find and set proper color
354 (xwem-osd-set-color emchat-xwem-osd (emchat-xwem-osd-color-for-nick nick))
356 ;; Just make sure OSD is clear
357 (xwem-osd-clear emchat-xwem-osd)
359 (when emchat-xwem-osd-show-icon
360 (xwem-osd-icon-data-add emchat-xwem-osd emchat-xwem-osd-icon))
363 (if emchat-xwem-osd-show-icon
364 (glyph-width (make-glyph `[xpm :data ,emchat-xwem-osd-icon]))
366 (encode-coding-string
367 (format "%s: %s" nick message)
368 (and (string-match font-x-registry-and-encoding-regexp
369 emchat-xwem-osd-font)
370 (intern (downcase (format "%s-%s"
371 (match-string 1 emchat-xwem-osd-font)
372 (match-string 2 emchat-xwem-osd-font)))))
375 (xwem-osd-show emchat-xwem-osd)
377 (when (itimerp (xwem-osd-get-prop emchat-xwem-osd 'timer))
378 (delete-itimer (xwem-osd-get-prop emchat-xwem-osd 'timer)))
379 (xwem-osd-put-prop emchat-xwem-osd 'timer
380 (start-itimer "emchat-osd" #'emchat-xwem-osd-hide
381 emchat-xwem-osd-display-time))))
383 (defun emchat-xwem-osd-hide ()
385 (when (xwem-osd-p emchat-xwem-osd)
386 (xwem-osd-hide emchat-xwem-osd)
387 (xwem-osd-destroy-instances emchat-xwem-osd)
388 (when (itimerp (xwem-osd-get-prop emchat-xwem-osd 'timer))
389 (delete-itimer (xwem-osd-get-prop emchat-xwem-osd 'timer)))
390 (xwem-osd-rem-prop emchat-xwem-osd 'timer)))
393 (defun emchat-xwem-dock-create ()
394 "Create emchat dock."
395 (setq emchat-xwem-dock
396 (xwem-osd-create-dock (xwem-dpy) 16 16
397 (list 'keymap emchat-xwem-keymap)))
398 (xwem-osd-show emchat-xwem-dock))
400 (defun emchat-xwem-dock-destroy ()
401 "Destroy emchat dock."
402 (when (xwem-osd-p emchat-xwem-dock)
403 (xwem-osd-destroy emchat-xwem-dock))
404 (setq emchat-xwem-dock nil))
406 (defun emchat-xwem-dock-change-icon (icon)
407 "Change emchat dock icon to ICON."
408 (when emchat-xwem-dock-enable
409 (unless emchat-xwem-dock
410 (emchat-xwem-dock-create))
411 (xwem-osd-icon-data-add emchat-xwem-dock icon)))
416 ;; Note: we can use ordinary Emacs commands here, because interactive
417 ;; form is empty, for complex commands we must use
418 ;; `define-xwem-command' and `xwem-interactive'.
420 (defun emchat-xwem-select-emchat ()
421 "Make emchat be current client."
423 (let ((eicl (xwem-misc-find-cl-by-emacs-frame emchat-frame)))
424 (setq emchat-xwem-saved-client (xwem-cl-selected))
425 (xwem-select-client eicl)
426 (emchat-show-window)))
428 (defun emchat-xwem-restore-client ()
429 "Display unseen senders."
431 (if (xwem-cl-alive-p emchat-xwem-saved-client)
432 (xwem-select-client emchat-xwem-saved-client)
433 (xwem-message 'warn "EMchat: Saved client dissapeared")))
435 (provide 'emchat-xwem)
436 ;;; emchat-xwem.el ends here