;;; xwem-faces.el --- XWEM can handle Emacs faces. ;; Copyright (C) 2003-2005 by XWEM Org. ;; Author: Zajcev Evgeny ;; Steve Youngs ;; Created: Mon Dec 29 12:04:19 MSK 2003 ;; Keywords: xwem ;; X-CVS: $Id: xwem-faces.el,v 1.12 2005-04-04 19:54:11 lg Exp $ ;; This file is part of XWEM. ;; XWEM 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. ;; XWEM 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 XEmacs; see the file COPYING. If not, write to the Free ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ;; 02111-1307, USA. ;;; Synched up with: Not in FSF ;;; Commentary: ;; Faces support. Main purpose of `xwem-faces' is easify interface to ;; X-Gc. ;;; Code: (require 'cus-face) ; for `custom-face-get-spec' (require 'xlib-xlib) (require 'xwem-struct) (require 'xwem-loaddefs) ;;; Customisation (defgroup xwem-faces nil "*Group to customize faces used by XWEM." :prefix "xwem-face-" :group 'xwem) (defcustom xwem-background-mode-bound 72000 "Number which is used to determine whether color has `dark' or `light' background mode. Normally you should'nt modify it." :type '(choice (const :tag "Default" 65536) (const :tag "Low" 50000) (const :tag "Medium" 72000) (const :tag "High" 94000)) :group 'xwem-faces) ;;; Internal variables ;;;###xwem-autoload (defun xwem-get-background-mode (color) "Return `dark' or `light' according to COLOR. COLOR is color instance, color name or list of color components." (if (< (apply '+ (or (and (listp color) color) (color-instance-rgb-components (or (and (color-instance-p color) color) (make-color-instance color))))) xwem-background-mode-bound) 'dark 'light)) ;;; TODO: ;; - Create xwem-face widget for customisation. (define-specifier-tag 'default) (defsubst xwem-face-foreground-specifier (face) (get face 'xwem-face-foreground-specifier)) (defsubst xwem-face-background-specifier (face) (get face 'xwem-face-background-specifier)) (defsubst xwem-face-font-specifier (face) (get face 'xwem-face-font-specifier)) (defsubst xwem-face-line-style-specifier (face) (get face 'xwem-face-line-style-specifier)) (defsubst xwem-face-line-width-specifier (face) (get face 'xwem-face-line-width-specifier)) (defsubst xwem-face-cap-style-specifier (face) (get face 'xwem-face-cap-style-specifier)) (defsubst xwem-face-join-style-specifier (face) (get face 'xwem-face-join-style-specifier)) (defsubst xwem-face-function-specifier (face) (get face 'xwem-face-function-specifier)) (defsubst xwem-face-subwindow-mode-specifier (face) (get face 'xwem-face-subwindow-mode-specifier)) (defsubst xwem-face-graphics-exposures-specifier (face) (get face 'xwem-face-graphics-exposures-specifier)) (defsubst xwem-face-x-gc-specifier (face) (get face 'xwem-face-x-gc-specifier)) (defun xwem-face-sort-tag-set (tag-set) (sort tag-set #'(lambda (t1 t2) (string-lessp (symbol-name t1) (symbol-name t2))))) (defun xwem-custom-declare-face (face spec doc &rest args) "Define new FACE to be used in xwem. SPEC is face specification, it should be an alist in form \\((DISPLAY ATTRS) ...\\)." (unless (get face 'xwem-face-spec) (put face 'xwem-face-spec spec) (unless (find-face face) (make-empty-face face) ; (face-display-set face spec nil '(custom)) (put face 'xwem-face-font-specifier (make-specifier-and-init 'generic `((global ((default) . ,(face-font-name 'default)))) t)) (put face 'xwem-face-background-specifier (make-specifier-and-init 'generic `((global ((default) . "black"))) t)) (put face 'xwem-face-foreground-specifier (make-specifier-and-init 'generic `((global ((default) . "white"))) t)) (put face 'xwem-face-line-style-specifier (make-specifier-and-init 'generic `((global ((default) . ,X-LineSolid))) t)) (put face 'xwem-face-line-width-specifier (make-specifier-and-init 'generic `((global ((default) . 0))) t)) (put face 'xwem-face-cap-style-specifier (make-specifier-and-init 'generic `((global ((default) . ,X-CapButt))) t)) (put face 'xwem-face-join-style-specifier (make-specifier-and-init 'generic `((global ((default) . ,X-JoinMiter))) t)) (put face 'xwem-face-function-specifier (make-specifier-and-init 'generic `((global ((default) . ,X-GXCopy))) t)) (put face 'xwem-face-subwindow-mode-specifier (make-specifier-and-init 'generic `((global ((default) . ,X-ClipByChildren))) t)) (put face 'xwem-face-graphics-exposures-specifier (make-specifier-and-init 'generic `((global ((default) . ,X-False))) t)) (put face 'xwem-face-x-gc-specifier (make-specifier 'generic)) ;; Setup face (let (tag-set tag-set-plist tval font) (while spec (setq tag-set (caar spec)) (setq tag-set-plist (cadr (car spec))) (cond ((eq tag-set t) (setq tag-set '(default))) ((listp tag-set) ;; Define new tags (setq tag-set (xwem-face-sort-tag-set tag-set)) (mapc 'define-specifier-tag tag-set)) (t (error 'xwem-error "Inavild TAG-SET specification"))) ;; Setup face params (when (setq tval (plist-get tag-set-plist :foreground)) (add-spec-list-to-specifier (xwem-face-foreground-specifier face) `((global ,(cons tag-set tval))) 'remove-tag-set-prepend)) (when (setq tval (plist-get tag-set-plist :background)) (add-spec-list-to-specifier (xwem-face-background-specifier face) `((global ,(cons tag-set tval))) 'remove-tag-set-prepend)) ;; Play with font ;;; Old stuff commented out, because of limitations ; (unless (setq font (plist-get tag-set-plist :font)) ; (setq font (face-font-name 'default))) ; (if (plist-get tag-set-plist :bold) ; (setq font (or (x-make-font-bold font) font)) ; (setq font (or (x-make-font-unbold font) font))) ; (if (plist-get tag-set-plist :italic) ; (setq font (or (x-make-font-italic font) font)) ; (setq font (or (x-make-font-unitalic font) font))) (unless (setq font (plist-get tag-set-plist :font)) (setq font (face-font-name 'default))) (when font (set-face-font face font)) (flet ((booleanp (arg) (or (eq arg t) (null arg)))) (mapc #'(lambda (kw-pre) (let* ((kw (car kw-pre)) (kv (assq kw custom-face-attributes)) (rv (plist-get tag-set-plist kw))) (when (and kv (funcall (cadr kw-pre) rv)) (funcall (caddr kv) face rv)))) '((:size numberp) (:family stringp) (:dim booleanp) (:bold booleanp) (:italic booleanp) (:underline booleanp)))) (setq font (face-font-name face)) (add-spec-list-to-specifier (xwem-face-font-specifier face) `((global ,(cons tag-set font))) 'remove-tag-set-prepend) ;; Other params (when (setq tval (plist-get tag-set-plist :line-style)) (add-spec-list-to-specifier (xwem-face-line-style-specifier face) `((global ,(cons tag-set tval))) 'remove-tag-set-prepend)) (when (setq tval (plist-get tag-set-plist :line-width)) (add-spec-list-to-specifier (xwem-face-line-width-specifier face) `((global ,(cons tag-set tval))) 'remove-tag-set-prepend)) (when (setq tval (plist-get tag-set-plist :cap-style)) (add-spec-list-to-specifier (xwem-face-cap-style-specifier face) `((global ,(cons tag-set tval))) 'remove-tag-set-prepend)) (when (setq tval (plist-get tag-set-plist :join-style)) (add-spec-list-to-specifier (xwem-face-join-style-specifier face) `((global ,(cons tag-set tval))) 'remove-tag-set-prepend)) (when (setq tval (plist-get tag-set-plist :function)) (add-spec-list-to-specifier (xwem-face-function-specifier face) `((global ,(cons tag-set tval))) 'remove-tag-set-prepend)) (when (setq tval (plist-get tag-set-plist :subwindow-mode)) (add-spec-list-to-specifier (xwem-face-subwindow-mode-specifier face) `((global ,(cons tag-set tval))) 'remove-tag-set-prepend)) (when (setq tval (plist-get tag-set-plist :graphics-exposures)) (add-spec-list-to-specifier (xwem-face-graphics-exposures-specifier face) `((global ,(cons tag-set tval))) 'remove-tag-set-prepend)) (setq spec (cdr spec)))) (unless (and doc (not (face-doc-string face))) (set-face-doc-string face doc)) (custom-handle-all-keywords face args 'custom-face) face))) (defmacro define-xwem-face (face spec doc &rest args) "Define new xwem face." `(xwem-custom-declare-face (quote ,face) ,spec ,doc ,@args)) (defun xwem-copy-face (old-face new-face) "Create NEW-FACE as copy of OLD-FACE." (xwem-custom-declare-face new-face (get old-face 'xwem-face-spec) (format "Copy of `%S' face." (face-name old-face))) ) (define-xwem-face xwem-face-white `((t (:foreground "white" :background "black"))) "White color face." :group 'xwem-faces) (define-xwem-face xwem-face-black `((t (:foreground "black" :background "black"))) "Black color face." :group 'xwem-faces) (define-xwem-face xwem-face-red `((t (:foreground "red" :background "black"))) "Red color face." :group 'xwem-faces) (define-xwem-face xwem-face-green `((t (:foreground "green" :background "black"))) "Green color face." :group 'xwem-faces) (define-xwem-face xwem-face-blue `((t (:foreground "blue" :background "black"))) "Blue color face." :group 'xwem-faces) (define-xwem-face xwem-face-yellow `((t (:foreground "yellow" :background "black"))) "Yellow color face." :group 'xwem-faces) (define-xwem-face xwem-face-cyan `((t (:foreground "cyan" :background "black"))) "Cyan color face." :group 'xwem-faces) (define-xwem-face xwem-face-magenta `((t (:foreground "magenta" :background "black"))) "Magenta color face." :group 'xwem-faces) (define-xwem-face xwem-face-darkgray `((t (:foreground "gray20" :background "black"))) "DarkGray color face." :group 'xwem-faces) (define-xwem-face xwem-face-lightgray `((t (:foreground "gray80" :background "black"))) "LightGray color face." :group 'xwem-faces) (define-xwem-face xwem-face-gray `((t (:foreground "gray50" :background "black"))) "Gray color face." :group 'xwem-faces) (define-xwem-face xwem-face-outline1 `((t (:foreground "red" :background "black"))) "Face used to outline something." :group 'xwem-faces) (define-xwem-face xwem-face-outline2 `((t (:foreground "blue" :background "black"))) "Face used to outline something." :group 'xwem-faces) (define-xwem-face xwem-face-outline3 `((t (:foreground "cyan" :background "black"))) "Face used to outline something." :group 'xwem-faces) (defun xwem-face-get-domain-face (face &optional domain) "Adjust FACE using DOMAIN." (cond ((null domain) (or (and (xwem-cl-selected) (xwem-face-get-domain-face face (xwem-cl-selected))) face)) ((xwem-cl-p domain) (or (cdr (assq face (xwem-cl-get-sys-prop domain 'domain-faces))) (and (xwem-cl-win domain) (xwem-face-get-domain-face face (xwem-cl-win domain))))) ((xwem-win-p domain) (or (cdr (assq face (xwem-win-get-prop domain 'domain-faces))) (xwem-face-get-domain-face face (xwem-win-frame domain)))) ((xwem-frame-p domain) (cdr (assq face (xwem-frame-get-prop domain 'domain-faces)))) ((eq domain 'nodomain) face) (t (error 'xwem-error "Invalid domain" domain)))) ;;; Functions (defun xwem-face-generic-specifier (face spcname &optional tag-set domain) "Return FACE's SPCNAME specifier value in TAG-SET. SPCNAME is one of 'foreground, 'background, 'font, 'line-style, 'line-width, 'cap-style, 'join-style, 'function, 'subwindow-mode, 'graphics-exposures or 'x-gc. DOMAIN is either xwem window, xwem client or xwem frame." (if (and tag-set (listp tag-set)) (setq tag-set (xwem-face-sort-tag-set tag-set)) (setq tag-set '(default))) ;; Adjust face according to DOMAIN, for get operation (setq face (or (xwem-face-get-domain-face face domain) face)) (let* ((fn (cond ((eq spcname 'foreground) 'xwem-face-foreground-specifier) ((eq spcname 'background) 'xwem-face-background-specifier) ((eq spcname 'font) 'xwem-face-font-specifier) ((eq spcname 'line-style) 'xwem-face-line-style-specifier) ((eq spcname 'line-width) 'xwem-face-line-width-specifier) ((eq spcname 'cap-style) 'xwem-face-cap-style-specifier) ((eq spcname 'join-style) 'xwem-face-join-style-specifier) ((eq spcname 'function) 'xwem-face-function-specifier) ((eq spcname 'subwindow-mode) 'xwem-face-subwindow-mode-specifier) ((eq spcname 'graphics-exposures) 'xwem-face-graphics-exposures-specifier) ((eq spcname 'x-gc) 'xwem-face-x-gc-specifier) (t (error 'xwem-error "Invalid SPCNAME" spcname)))) (spec (funcall fn face))) (when (specifierp spec) (setq spec (specifier-spec-list spec nil tag-set t)) (cdr (car (cdr (car spec))))))) ;; Getters (defsubst xwem-face-foreground (face &optional tag-set domain) "Return FACE foreground color in TAG-SET." (or (xwem-face-generic-specifier face 'foreground tag-set domain) (xwem-face-generic-specifier face 'foreground) (face-foreground-name face))) (defsubst xwem-face-background (face &optional tag-set domain) "Return FACE background color in TAG-SET." (or (xwem-face-generic-specifier face 'background tag-set domain) (xwem-face-generic-specifier face 'background) (face-background-name face))) (defsubst xwem-face-font (face &optional tag-set domain) "Return FACE font in TAG-SET." (or (xwem-face-generic-specifier face 'font tag-set domain) (xwem-face-generic-specifier face 'font) (face-font-name face))) (defsubst xwem-face-line-style (face &optional tag-set domain) "Return FACE's line style in TAG-SET." (or (xwem-face-generic-specifier face 'line-style tag-set domain) (xwem-face-generic-specifier face 'line-style))) (defsubst xwem-face-line-width (face &optional tag-set domain) "Return FACE's line width TAG-SET." (or (xwem-face-generic-specifier face 'line-width tag-set domain) (xwem-face-generic-specifier face 'line-width))) (defsubst xwem-face-cap-style (face &optional tag-set domain) "Return FACE's cap style in TAG-SET." (or (xwem-face-generic-specifier face 'cap-style tag-set domain) (xwem-face-generic-specifier face 'cap-style))) (defsubst xwem-face-join-style (face &optional tag-set domain) "Return FACE's join style in TAG-SET." (or (xwem-face-generic-specifier face 'join-style tag-set domain) (xwem-face-generic-specifier face 'join-style))) (defsubst xwem-face-function (face &optional tag-set domain) "Return FACE's function in TAG-SET." (or (xwem-face-generic-specifier face 'function tag-set domain) (xwem-face-generic-specifier face 'function))) (defsubst xwem-face-subwindow-mode (face &optional tag-set domain) "Return FACE's cap style in TAG-SET." (or (xwem-face-generic-specifier face 'subwindow-mode tag-set domain) (xwem-face-generic-specifier face 'subwindow-mode))) (defsubst xwem-face-graphics-exposures (face &optional tag-set domain) "Return FACE's graphics exposures in TAG-SET." (or (xwem-face-generic-specifier face 'graphics-exposures tag-set domain) (xwem-face-generic-specifier face 'graphics-exposures) X-False)) (defsubst xwem-face-x-gc (face &optional tag-set domain) "Return FACE's X-Gc in TAG-SET." (or (face-property face (xwem-face-generic-specifier face 'x-gc tag-set domain)) (face-property face 'xwem-x-gc))) ;; Setters (defun xwem-face-set-domain-face (face &optional domain) (cond ((null domain) (xwem-face-get-domain-face face)) ((xwem-cl-p domain) (or (cdr (assq face (xwem-cl-get-sys-prop domain 'domain-faces))) (let ((nface (intern (symbol-name (gensym "xwem-cl-domain-face"))))) (xwem-cl-put-sys-prop domain 'domain-faces (cons (cons face (xwem-copy-face face nface)) (xwem-cl-get-sys-prop domain 'domain-faces))) nface))) ((xwem-win-p domain) (or (cdr (assq face (xwem-win-get-prop domain 'domain-faces))) (let ((nface (intern (symbol-name (gensym "xwem-win-domain-face"))))) (xwem-win-put-prop domain 'domain-faces (cons (cons face (xwem-copy-face face nface)) (xwem-win-get-prop domain 'domain-faces))) nface))) ((xwem-frame-p domain) (or (cdr (assq face (xwem-frame-get-prop domain 'domain-faces))) (let ((nface (intern (symbol-name (gensym "xwem-frame-domain-face"))))) (xwem-frame-put-prop domain 'domain-faces (cons (cons face (xwem-copy-face face nface)) (xwem-frame-get-prop domain 'domain-faces))) nface))) ((eq domain 'nodomain) face) (t (error 'xwem-error "Invalid domain" domain)))) (defun xwem-face-set-generic-specifier (face spcname value &optional tag-set domain) "Set FACE's SPCNAME specifier to VALUE in TAG-SET." (if (and tag-set (listp tag-set)) (setq tag-set (xwem-face-sort-tag-set tag-set)) (setq tag-set '(default))) ;; Adjust face according to DOMAIN, for set operation (setq face (or (xwem-face-set-domain-face face domain) face)) (let* ((fn (cond ((eq spcname 'foreground) 'xwem-face-foreground-specifier) ((eq spcname 'background) 'xwem-face-background-specifier) ((eq spcname 'font) 'xwem-face-font-specifier) ((eq spcname 'line-style) 'xwem-face-line-style-specifier) ((eq spcname 'line-width) 'xwem-face-line-width-specifier) ((eq spcname 'cap-style) 'xwem-face-cap-style-specifier) ((eq spcname 'join-style) 'xwem-face-join-style-specifier) ((eq spcname 'function) 'xwem-face-function-specifier) ((eq spcname 'subwindow-mode) 'xwem-face-subwindow-mode-specifier) ((eq spcname 'graphics-exposures) 'xwem-face-graphics-exposures-specifier) ((eq spcname 'x-gc) 'xwem-face-x-gc-specifier) (t (error 'xwem-error "Invalid SPCNAME" spcname)))) (spec (funcall fn face)) xgc) (if (specifierp spec) ;; Update specifier (add-spec-list-to-specifier spec `((global ,(cons tag-set value))) 'remove-tag-set-prepend) ;; Or update face directly (non xwem face) (cond ((eq spcname 'foreground) (set-face-foreground face value)) ((eq spcname 'background) (set-face-background face value)) ((eq spcname 'font) (set-face-font face value)))) ;; Update X Gc if needed (when (and (not (eq spcname 'x-gc)) (setq xgc (xwem-face-x-gc face tag-set 'nodomain))) (cond ((eq spcname 'foreground) ;; Free color, is this really needed? ; (XFreeColors (xwem-dpy) (XDefaultColormap (xwem-dpy)) (list (X-Gc-foreground xgc)) 0) (setf (X-Gc-foreground xgc) (XAllocColor (xwem-dpy) (XDefaultColormap (xwem-dpy)) (xwem-make-color value)))) ((eq spcname 'background) ;; Free color, is this really needed? ; (XFreeColors (xwem-dpy) (XDefaultColormap (xwem-dpy)) (list (X-Gc-background xgc)) 0) (setf (X-Gc-background xgc) (XAllocColor (xwem-dpy) (XDefaultColormap (xwem-dpy)) (xwem-make-color value)))) ((eq spcname 'font) (setf (X-Gc-font xgc) (X-Font-get (xwem-dpy) value))) ((eq spcname 'line-style) (setf (X-Gc-line-style xgc) value)) ((eq spcname 'line-width) (setf (X-Gc-line-width xgc) value)) ((eq spcname 'cap-style) (setf (X-Gc-cap-style xgc) value)) ((eq spcname 'join-style) (setf (X-Gc-join-style xgc) value)) ((eq spcname 'function) (setf (X-Gc-function xgc) value)) ((eq spcname 'subwindow-mode) (setf (X-Gc-subwindow-mode xgc) value)) ((eq spcname 'graphics-exposures) (setf (X-Gc-graphics-exposures xgc) value))) (XChangeGC (xwem-dpy) xgc)) )) (defsubst xwem-set-face-foreground (face new-fg &optional tag-set domain) "Set FACE's foreground color to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'foreground new-fg tag-set domain)) (defsubst xwem-set-face-background (face new-bg &optional tag-set domain) "Set FACE's background color to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'background new-bg tag-set domain)) (defsubst xwem-set-face-font (face new-font &optional tag-set domain) "Set FACE's font to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'font new-font tag-set domain)) (defsubst xwem-set-face-line-style (face new-ls &optional tag-set domain) "Set FACE's line style to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'line-style new-ls tag-set domain)) (defsubst xwem-set-face-line-width (face new-lw &optional tag-set domain) "Set FACE's line width to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'line-width new-lw tag-set domain)) (defsubst xwem-set-face-cap-style (face new-cs &optional tag-set domain) "Set FACE's cap style to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'cap-style new-cs tag-set domain)) (defsubst xwem-set-face-join-style (face new-js &optional tag-set domain) "Set FACE's join style to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'join-style new-js tag-set domain)) (defsubst xwem-set-face-function (face new-fun &optional tag-set domain) "Set FACE's function to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'function new-fun tag-set domain)) (defsubst xwem-set-face-subwindow-mode (face new-sm &optional tag-set domain) "Set FACE's subwindow mode to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'subwindow-mode new-sm tag-set domain)) (defsubst xwem-set-face-graphics-exposures (face new-ge &optional tag-set domain) "Set FACE's graphics exposures to NEW-FG in TAG-SET." (xwem-face-set-generic-specifier face 'graphics-exposures new-ge tag-set domain)) ;; Font attributes (defun xwem-set-face-font-attribute (face attr-fun value &optional tag-set domain) (let ((font (xwem-face-font face tag-set domain))) (set-face-font face font) (funcall attr-fun face value) (xwem-set-face-font face (face-font-name face) tag-set domain))) (defsubst xwem-set-face-font-family (face font-family &optional tag-set domain) "Set FACE's font famility to FONT-FAMILY in TAG-SET of DOMAIN." (xwem-set-face-font-attribute face 'custom-set-face-font-family font-family tag-set domain)) (defsubst xwem-set-face-font-size (face font-size &optional tag-set domain) "Set FACE's font famility to FONT-FAMILY in TAG-SET of DOMAIN." (xwem-set-face-font-attribute face 'custom-set-face-font-size font-size tag-set domain)) (defsubst xwem-set-face-bold (face bold-p &optional tag-set domain) "Set bold FACE's attribute to BOLD-P in TAG-SET of DOMAIN." (xwem-set-face-font-attribute face 'custom-set-face-bold bold-p tag-set domain)) (defsubst xwem-set-face-italic (face italic-p &optional tag-set domain) "Set italic FACE's attribute to ITALIC-P in TAG-SET of DOMAIN." (xwem-set-face-font-attribute face 'custom-set-face-italic italic-p tag-set domain)) (defsubst xwem-set-face-x-gc (face new-gc &optional tag-set domain) "Set FACE's X-Gc to NEW-FG in TAG-SET." ;; NOTE: Ugly thing, we can't store NEW-GC directly in specifier, ;; because it uses `copy-tree' to ensure to not share sequence. So ;; workaround is to create unique FACE property, which will store ;; our NEW-GC and specifier will store property name. (if (specifierp (xwem-face-x-gc-specifier face)) (let ((sym (gensym "*xwem-x-gc-"))) (set-face-property face sym new-gc) (xwem-face-set-generic-specifier face 'x-gc sym tag-set domain)) ;; No, specifier, it mean that FACE is normal emacs face, not ;; defined by `define-xwem-face'. (set-face-property face 'xwem-x-gc new-gc))) ;;;###xwem-autoload (defun xwem-face-get-gc (face &optional tag-set domain d) "Return X-Gc for FACE in TAG-SET. D - X drawable default is `XDefaultRootWindow'." (setq face (or (xwem-face-get-domain-face face domain) face)) (or (xwem-face-x-gc face tag-set 'nodomain) (let* ((xdpy (xwem-dpy)) (cmap (XDefaultColormap xdpy)) (gc (XCreateGC xdpy (or (and (X-Drawable-p d) d) (XDefaultRootWindow xdpy)) (make-X-Gc :dpy xdpy :id (X-Dpy-get-id xdpy) :line-style (xwem-face-line-style face tag-set 'nodomain) :line-width (xwem-face-line-width face tag-set 'nodomain) :cap-style (xwem-face-cap-style face tag-set 'nodomain) :join-style (xwem-face-join-style face tag-set 'nodomain) :function (xwem-face-function face tag-set 'nodomain) :subwindow-mode (xwem-face-subwindow-mode face tag-set 'nodomain) :graphics-exposures (xwem-face-graphics-exposures face tag-set 'nodomain) :foreground (let ((fc (xwem-face-foreground face tag-set 'nodomain))) (if (stringp fc) (XAllocColor xdpy cmap (xwem-make-color fc)) fc)) :background (let ((bc (xwem-face-background face tag-set 'nodomain))) (if (stringp bc) (XAllocColor xdpy cmap (xwem-make-color bc)) bc)) :font (X-Font-get xdpy (xwem-face-font face tag-set 'nodomain)))))) (xwem-set-face-x-gc face gc tag-set 'nodomain) gc))) (put 'xwem-face-get-gc 'lisp-indent-function 1) (provide 'xwem-faces) ;;; xwem-faces.el ends here