;; gnus-bitmap.el -- bitmap utilities for gnus. ;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. ;; Author: KORIYAMA Naohiro ;; Katsumi Yamaoka ;; Tatsuya Ichikawa ;; Created: 1999/08/20 ;; Revised: 2001/02/02 ;; Keywords: bitmap, x-face, splash, gnus ;; This file is part of BITMAP-MULE. ;; 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: ;; How to use: ;; If you would like to splash the startup screen with bitmap image, ;; put the following lines in your .emacs file before gnus is loaded. ;; ;; ;; It must be placed in .emacs file before gnus.el(c) is loaded. ;; (if window-system ;; (progn ;; (autoload 'gnus-bitmap-splash "gnus-bitmap") ;; (add-hook 'gnus-load-hook 'gnus-bitmap-splash))) ;; ;; Or you can inhibit the use of bitmap images (except for X-Face) as ;; follows. ;; ;; (setq gnus-bitmap-splash-image nil ;; gnus-bitmap-modeline-image nil) ;;; Code: (eval-when-compile (require 'cl) (require 'static)) (require 'pcustom) (require 'alist) (require 'bitmap) (require 'x-face-mule) ;;; Internal variables and the related functions. ;; (eval-when-compile (defmacro gnus-bitmap-splash-image-internal () (let ((file (expand-file-name "gnus.xbm" (if (string-match "/tm/$" default-directory) "../bitmap-mule/";; tm-8 "./")))) (if (file-exists-p file) (progn (message " ++ decoding internal image for splashing...") (bitmap-decode-xbm (bitmap-read-xbm-file file))) (byte-compile-warn "Warning: file \"gnus.xbm\" not found.") nil))) (defmacro gnus-bitmap-modeline-image-internal () (let ((file (expand-file-name "gnus-pointer.xbm" (if (string-match "/tm/$" default-directory) "../bitmap-mule/";; tm-8 "./")))) (if (file-exists-p file) (progn (message " ++ decoding internal image for modeline identifier...") (bitmap-decode-xbm (bitmap-read-xbm-file file))) (byte-compile-warn "Warning: file \"gnus-pointer.xbm\" not found.") nil))) (defmacro gnus-bitmap-xbm-to-bitmap (cmp) (` (let ((cmp (, cmp))) (if cmp (let ((len (length cmp)) (bitmap (bitmap-compose (aref cmp 0))) (i 1)) (while (< i len) (setq bitmap (concat bitmap "\n" (bitmap-compose (aref cmp i))) i (1+ i))) bitmap)))))) (defconst gnus-bitmap-splash-image-internal (gnus-bitmap-xbm-to-bitmap (gnus-bitmap-splash-image-internal))) (defconst gnus-bitmap-modeline-image-internal (gnus-bitmap-xbm-to-bitmap (gnus-bitmap-modeline-image-internal))) (defvar gnus-bitmap-splash-image-data nil) (defvar gnus-bitmap-modeline-identifier nil) (eval-when-compile (makunbound 'gnus-bitmap-broken-facility-check) (defcustom gnus-bitmap-broken-facility-check t "The value t means `:set' does not work at the loading time. For instance it will be occurred under Mule 2.3 based on Emacs 19.34 using custom-1.9962." :set (function (lambda (symbol value) (set-default symbol nil))))) (static-if gnus-bitmap-broken-facility-check (progn (defun gnus-bitmap-set-splash-image-data (arg) (setq gnus-bitmap-splash-image-data (cond ((eq 'internal arg) gnus-bitmap-splash-image-internal) ((and (stringp arg) (file-exists-p arg)) (gnus-bitmap-xbm-to-bitmap arg))))) (defun gnus-bitmap-set-modeline-image-data (arg) (setq gnus-bitmap-modeline-identifier (cond ((eq 'internal arg) gnus-bitmap-modeline-image-internal) ((and (stringp arg) (file-exists-p arg)) (gnus-bitmap-xbm-to-bitmap arg)))))) (defmacro gnus-bitmap-set-splash-image-data (arg) (` (setq gnus-bitmap-splash-image-data (cond ((eq 'internal (, arg)) gnus-bitmap-splash-image-internal) ((and (stringp (, arg)) (file-exists-p (, arg))) (gnus-bitmap-xbm-to-bitmap (, arg))))))) (defmacro gnus-bitmap-set-modeline-image-data (arg) (` (setq gnus-bitmap-modeline-identifier (cond ((eq 'internal (, arg)) gnus-bitmap-modeline-image-internal) ((and (stringp (, arg)) (file-exists-p (, arg))) (gnus-bitmap-xbm-to-bitmap (, arg)))))))) ;;; Options. ;; (defcustom x-face-mule-gnus-force-decode-headers nil "If non-nil, display X-Face even if `gnus-show-mime' is nil." :type 'boolean :group 'x-face-mule) (defcustom gnus-bitmap-splash-image 'internal "If it is the symbol `internal', use the internal image for splashing the startup screen. It can also be a name of XBM file. If it is nil, bitmap image is not used." :type (list 'radio (list 'const :tag (concat "Internal image\n" gnus-bitmap-splash-image-internal) 'internal) '(file :tag "XBM file") '(const :tag "Off" nil)) :set (function (lambda (symbol value) (gnus-bitmap-set-splash-image-data value) (set-default symbol value))) :group 'bitmap-mule :group 'gnus-start) (defcustom gnus-bitmap-modeline-image 'internal "If it is the symbol `internal', use the internal image for displaying a nifty image in the modeline. It can also be a name of XBM file. If it is nil or the value of `emacs-major-version' is less than 20, bitmap image is not used." :type (list 'radio (list 'const :tag (concat "Internal image [" gnus-bitmap-modeline-image-internal "]") 'internal) '(file :tag "XBM file") '(const :tag "Off" nil)) :set (function (lambda (symbol value) (gnus-bitmap-set-modeline-image-data value) (set-default symbol value))) :group 'bitmap-mule :group 'gnus-start) (static-when gnus-bitmap-broken-facility-check (gnus-bitmap-set-splash-image-data gnus-bitmap-splash-image) (gnus-bitmap-set-modeline-image-data gnus-bitmap-modeline-image)) ;;; Avoid byte compile warnings. ;; (defvar gnus-article-buffer) (defvar gnus-article-display-hook) (defvar gnus-article-x-face-command) (defvar gnus-ignored-headers) (defvar gnus-mule-bitmap-image-file) (defvar gnus-simple-splash) (defvar gnus-strict-mime) (defvar gnus-treat-display-xface) (defvar gnus-treat-hide-headers) (defvar gnus-version) (defvar gnus-visible-headers) (defvar last) (eval-when-compile (fset 'gnus-bitmap-original-gnus-group-startup-message 'ignore) (autoload 'article-goto-body "gnus-art") (autoload 'gnus-indent-rigidly "gnus") (autoload 'gnus-splash "gnus") (autoload 'gnus-summary-select-article "gnus-sum")) ;;; X-Face functions. ;; ;;;###autoload (defun x-face-mule-gnus-article-display-x-face (&rest args) "Decode and show X-Face. The buffer is expected to be narrowed to just the headers of the article. If `gnus-article-x-face-command' is set to the symbol of this function, gnus will call it for each X-Face fields. So we set the bound variable `last' to T in order to make good use of time." (when window-system (let ((x-face-mule-highlight-x-face-style (if (and (eq x-face-mule-highlight-x-face-style 'xmas) (memq this-command '(gnus-summary-toggle-mime))) 'default x-face-mule-highlight-x-face-style)) x-face-mule-preserve-original-from-field) (x-face-mule-x-face-decode-message-header-1) (x-face-mule-highlight-header))) (setq last t)) (defun x-face-mule-gnus-highlight-headers-if-no-mime () "Decode and show X-Face even if `gnus-show-mime' is nil. It is controlled by the value of `x-face-mule-gnus-force-decode-headers'." (when (and x-face-mule-gnus-force-decode-headers (eq major-mode 'gnus-article-mode) (memq x-face-mule-highlight-x-face-position '(from x-face))) (x-face-decode-message-header))) ;;; Splash the startup screen. ;; (defun gnus-bitmap-sit-for-0 () (remove-hook 'gnus-startup-hook 'gnus-bitmap-sit-for-0) (sit-for 0)) (defun gnus-bitmap-startup-message (&optional x y) "Insert startup message in current buffer." (if (null gnus-bitmap-splash-image-data) (gnus-bitmap-original-gnus-group-startup-message x y) (erase-buffer) (insert gnus-version "\n") (let ((fill-column (1- (window-width)))) (center-region (point-min) (point-max))) (let ((start (point)) width) ;; Insert an image. (insert gnus-bitmap-splash-image-data) (setq width (current-column)) (insert "\n") ;; And then hack it. (gnus-indent-rigidly start (point) (/ (max (- (window-width) (or x (1- width))) 0) 2)) (goto-char start) (insert-char ?\n (/ (max 0 (- (window-height) (count-lines start (point-max)))) 2))) ;; Fontify some. (put-text-property (point-min) (point-max) 'face 'gnus-splash-face) (goto-char (point-min)) (setq mode-line-buffer-identification gnus-version) (setq gnus-simple-splash nil) (set-buffer-modified-p t) ;; Redisplay after `gnus-startup-hook' is evaluated. (add-hook 'gnus-startup-hook 'gnus-bitmap-sit-for-0 'append))) ;;; Modeline identification. ;; (defun gnus-bitmap-mode-line-buffer-identification (line) (let ((l (car line))) (if (and (stringp l) gnus-bitmap-modeline-identifier) (list gnus-bitmap-modeline-identifier (if (string-match "^Gnus: *" l) (substring l (match-end 0)) l)) line))) ;;; Setup. ;; (set-alist 'x-face-mule-highlight-x-face-refresh-method-alist 'gnus-summary-mode (function (lambda () (gnus-summary-select-article nil t)))) (when window-system (add-hook 'gnus-exit-gnus-hook 'x-face-mule-save-cache-file)) (defun gnus-bitmap-redefine (&optional splash) "Redifine variables and functions for the use of BITMAP-MULE. If SPLASH is non-nil, the function `gnus-group-startup-message' is also redefined and splashing the startup screen with a bitmap image." (require 'gnus-art) (setq gnus-strict-mime nil) ;; Modify `gnus-visible-headers' and `gnus-ignored-headers'. (cond ((stringp gnus-visible-headers) (let ((xf (string-match gnus-visible-headers "X-Face:")) (xfi (string-match gnus-visible-headers "X-Face-Img:"))) (cond ((not (or xf xfi)) (setq gnus-visible-headers (format "\\(%s\\)\\|^X-Face:\\|^X-Face-Img:" gnus-visible-headers))) ((not xf) (setq gnus-visible-headers (format "\\(%s\\)\\|^X-Face:" gnus-visible-headers))) ((not xfi) (setq gnus-visible-headers (format "\\(%s\\)\\|^X-Face-Img:" gnus-visible-headers)))))) ((consp gnus-visible-headers) (unless (member "^X-Face:" gnus-visible-headers) (setq gnus-visible-headers (append gnus-visible-headers '("^X-Face:")))) (unless (member "^X-Face-Img:" gnus-visible-headers) (setq gnus-visible-headers (append gnus-visible-headers '("^X-Face-Img:"))))) ((stringp gnus-ignored-headers) (let ((regexp (format "\\\\|%s\\|%s\\\\|%s" "\\^?X-Face\\(-Img\\)?:" "\\^?X-Face\\(-Img\\)?:" "\\^?X-Face\\(-Img\\)?:"))) (while (string-match regexp gnus-ignored-headers) (setq gnus-ignored-headers (concat (substring gnus-ignored-headers 0 (match-beginning 0)) (substring gnus-ignored-headers (match-end 0))))))) ((consp gnus-ignored-headers) (when (member "^X-Face:" gnus-ignored-headers) (setq gnus-ignored-headers (delete "^X-Face:" gnus-ignored-headers))) (when (member "^X-Face-Img:" gnus-ignored-headers) (setq gnus-ignored-headers (delete "^X-Face-Img:" gnus-ignored-headers))))) (when (boundp 'gnus-treat-display-xface) (if (not (stringp gnus-article-x-face-command)) ;; Don't touch any user options. nil ;; Pterodactyl Gnus, T-gnus 6.10.064 or later. (setq gnus-treat-display-xface (if (and (featurep 'running-pterodactyl-gnus-0_73-or-later); T-gnus (not x-face-mule-gnus-force-decode-headers)) '(and mime head) 'head) gnus-treat-hide-headers 'head gnus-article-x-face-command 'x-face-mule-gnus-article-display-x-face))) ;; Advise the hiding function. (defadvice article-hide-headers (after x-face-mule-highlight-header activate) "Highlight X-Face field(s) after `article-hide-headers' is done." (x-face-mule-highlight-header)) ;; Gnus 5.7, Semi-gnus 6.10, Nana-gnus 6.13 or earlier. (when (and (boundp 'gnus-article-display-hook) (or (memq 'gnus-article-hide-headers-if-wanted gnus-article-display-hook) (memq 'gnus-article-maybe-highlight gnus-article-display-hook))) (remove-hook 'gnus-article-display-hook 'gnus-article-display-x-face) (add-hook 'gnus-article-display-hook 'x-face-mule-gnus-highlight-headers-if-no-mime 'append)) ;; Redifine the splash function. (when splash (unless (fboundp 'gnus-bitmap-original-gnus-group-startup-message) (fset 'gnus-bitmap-original-gnus-group-startup-message (symbol-function 'gnus-group-startup-message))) (fset 'gnus-group-startup-message 'gnus-bitmap-startup-message) ;; Splash the screen when `gnus' is being loaded. (unless (featurep 'gnus) (gnus-splash))) ;; Invalidate the old style splashing feature. (when (boundp 'gnus-mule-bitmap-image-file) (setq gnus-mule-bitmap-image-file nil)) (when (>= emacs-major-version 20) ;; Redifine the modeline identify function. (fset 'gnus-mode-line-buffer-identification 'gnus-bitmap-mode-line-buffer-identification))) ;;;###autoload (defun gnus-bitmap-splash () "Splash the startup screen. This function has only limited use for `gnus-load-hook' which should be set before `gnus' is loaded." (when (and window-system (not (featurep 'gnus)) gnus-bitmap-splash-image-data) ;; Suppress splashing with an ascii picture. (setq this-command nil) (let ((fns (cdr (assoc "gnus" after-load-alist)))) (if fns (put-alist 'gnus-bitmap-redefine '(t) fns) (eval-after-load "gnus" '(gnus-bitmap-redefine 'splash)))))) (eval-and-compile (autoload 'smiley-toggle-buffer "smiley-mule")) ;;;###autoload (defun gnus-smiley-display (&optional arg) "Display \"smileys\" as small graphical icons. With arg, turn displaying on if and only if arg is positive." (interactive "P") (if window-system (save-excursion (set-buffer gnus-article-buffer) (save-restriction (widen) (article-goto-body) (narrow-to-region (point) (point-max)) (let ((inhibit-read-only t) buffer-read-only) (smiley-toggle-buffer arg)))) (when (interactive-p) (message "You're not under window system.")))) (provide 'gnus-bitmap) ;; gnus-bitmap.el ends here