comparison lisp/faces.el @ 17522:209c61e51bd0

(frame-set-background-mode): New function. (frame-background-mode): New variable. (x-create-frame-with-faces): Rearrangement of order of font processing. Handle custom-faces here. (face-doc-string, set-face-doc-string): New functions. (set-face-bold-p, set-face-italic-p): New functions. (face-bold-p, face-italic-p): New function. (face-spec-set, face-spec-set-1, face-spec-set-match-display): New functions.
author Richard M. Stallman <rms@gnu.org>
date Mon, 21 Apr 1997 03:56:57 +0000
parents b251c8820860
children 1f4d7f741932
comparison
equal deleted inserted replaced
17521:ddce9ecc6f6a 17522:209c61e51bd0
106 If the optional argument FRAME is given, report on face FACE in that frame. 106 If the optional argument FRAME is given, report on face FACE in that frame.
107 If FRAME is t, report on the defaults for face FACE (for new frames). 107 If FRAME is t, report on the defaults for face FACE (for new frames).
108 If FRAME is omitted or nil, use the selected frame." 108 If FRAME is omitted or nil, use the selected frame."
109 (aref (internal-get-face face frame) 7)) 109 (aref (internal-get-face face frame) 7))
110 110
111 (defun face-bold-p (face &optional frame)
112 "Return non-nil if the font of FACE is bold.
113 If the optional argument FRAME is given, report on face FACE in that frame.
114 If FRAME is t, report on the defaults for face FACE (for new frames).
115 The font default for a face is either nil, or a list
116 of the form (bold), (italic) or (bold italic).
117 If FRAME is omitted or nil, use the selected frame."
118 (let ((font (face-font face frame)))
119 (if (stringp font)
120 (not (eq font (x-make-font-unbold font)))
121 (memq 'bold font))))
122
123 (defun face-italic-p (face &optional frame)
124 "Return non-nil if the font of FACE is italic.
125 If the optional argument FRAME is given, report on face FACE in that frame.
126 If FRAME is t, report on the defaults for face FACE (for new frames).
127 The font default for a face is either nil, or a list
128 of the form (bold), (italic) or (bold italic).
129 If FRAME is omitted or nil, use the selected frame."
130 (let ((font (face-font face frame)))
131 (if (stringp font)
132 (not (eq font (x-make-font-unitalic font)))
133 (memq 'italic font))))
134
135 (defun face-doc-string (face)
136 "Get the documentation string for FACE."
137 (get face 'face-documentation))
111 138
112 ;;; Mutators. 139 ;;; Mutators.
113 140
114 (defun set-face-font (face font &optional frame) 141 (defun set-face-font (face font &optional frame)
115 "Change the font of face FACE to FONT (a string). 142 "Change the font of face FACE to FONT (a string).
189 "Specify whether face FACE is underlined. (Yes if UNDERLINE-P is non-nil.) 216 "Specify whether face FACE is underlined. (Yes if UNDERLINE-P is non-nil.)
190 If the optional FRAME argument is provided, change only 217 If the optional FRAME argument is provided, change only
191 in that frame; otherwise change each frame." 218 in that frame; otherwise change each frame."
192 (interactive (internal-face-interactive "underline-p" "underlined")) 219 (interactive (internal-face-interactive "underline-p" "underlined"))
193 (internal-set-face-1 face 'underline underline-p 7 frame)) 220 (internal-set-face-1 face 'underline underline-p 7 frame))
221
222 (defun set-face-bold-p (face bold-p &optional frame)
223 "Specify whether face FACE is bold. (Yes if BOLD-P is non-nil.)
224 If the optional FRAME argument is provided, change only
225 in that frame; otherwise change each frame."
226 (cond ((eq bold-p nil) (make-face-unbold face frame t))
227 (t (make-face-bold face frame t))))
228
229 (defun set-face-italic-p (face italic-p &optional frame)
230 "Specify whether face FACE is italic. (Yes if ITALIC-P is non-nil.)
231 If the optional FRAME argument is provided, change only
232 in that frame; otherwise change each frame."
233 (cond ((eq italic-p nil) (make-face-unitalic face frame t))
234 (t (make-face-italic face frame t))))
235
236 (defun set-face-doc-string (face string)
237 "Set the documentation string for FACE to STRING."
238 (put face 'face-documentation string))
194 239
195 (defun modify-face-read-string (face default name alist) 240 (defun modify-face-read-string (face default name alist)
196 (let ((value 241 (let ((value
197 (completing-read 242 (completing-read
198 (if default 243 (if default
1073 (let ((face (car (car rest)))) 1118 (let ((face (car (car rest))))
1074 (or (face-differs-from-default-p face) 1119 (or (face-differs-from-default-p face)
1075 (face-fill-in face (cdr (car rest)) frame))) 1120 (face-fill-in face (cdr (car rest)) frame)))
1076 (setq rest (cdr rest))))) 1121 (setq rest (cdr rest)))))
1077 (setq frames (cdr frames))))) 1122 (setq frames (cdr frames)))))
1078 1123
1124 ;;; Setting a face based on a SPEC.
1125
1126 (defun face-spec-set (face spec &optional frame)
1127 "Set FACE's face attributes according to the first matching entry in SPEC.
1128 If optional FRAME is non-nil, set it for that frame only.
1129 If it is nil, then apply SPEC to each frame individually.
1130 See `defface' for information about SPEC."
1131 (let ((tail spec))
1132 (while tail
1133 (let* ((entry (car tail))
1134 (display (nth 0 entry))
1135 (attrs (nth 1 entry)))
1136 (setq tail (cdr tail))
1137 (modify-face face nil nil nil nil nil nil frame)
1138 (when (face-spec-set-match-display display frame)
1139 (face-spec-set-1 face frame attrs ':foreground 'set-face-foreground)
1140 (face-spec-set-1 face frame attrs ':background 'set-face-background)
1141 (face-spec-set-1 face frame attrs ':stipple 'set-face-stipple)
1142 (face-spec-set-1 face frame attrs ':bold 'set-face-bold-p)
1143 (face-spec-set-1 face frame attrs ':italic 'set-face-italic-p)
1144 (face-spec-set-1 face frame attrs ':underline 'set-face-underline-p)
1145 (setq tail nil)))))
1146 (if (null frame)
1147 (let ((frames (frame-list))
1148 frame)
1149 (while frames
1150 (setq frame (car frames)
1151 frames (cdr frames))
1152 (face-spec-set face (or (get face 'saved-face)
1153 (get face 'face-defface-spec))
1154 frame)
1155 (face-spec-set face spec frame)))))
1156
1157 (defun face-spec-set-1 (face frame plist property function)
1158 (while (and plist (not (eq (car plist) property)))
1159 (setq plist (cdr (cdr plist))))
1160 (if plist
1161 (funcall function face (nth 1 plist) frame)))
1162
1163 (defun face-spec-set-match-display (display frame)
1164 "Non-nil iff DISPLAY matches FRAME.
1165 DISPLAY is part of a spec such as can be used in `defface'.
1166 If FRAME is nil, the current FRAME is used."
1167 (let* ((conjuncts display)
1168 conjunct req options
1169 ;; t means we have succeeded against all
1170 ;; the conjunts in DISPLAY that have been tested so far.
1171 (match t))
1172 (if (eq conjuncts t)
1173 (setq conjuncts nil))
1174 (while (and conjuncts match)
1175 (setq conjunct (car conjuncts)
1176 conjuncts (cdr conjuncts)
1177 req (car conjunct)
1178 options (cdr conjunct)
1179 match (cond ((eq req 'type)
1180 (memq window-system options))
1181 ((eq req 'class)
1182 (memq (frame-parameter frame 'display-type) options))
1183 ((eq req 'background)
1184 (memq (frame-parameter frame 'background-mode)
1185 options))
1186 (t
1187 (error "Unknown req `%S' with options `%S'"
1188 req options)))))
1189 match))
1079 1190
1080 ;; Like x-create-frame but also set up the faces. 1191 ;; Like x-create-frame but also set up the faces.
1081 1192
1082 (defun x-create-frame-with-faces (&optional parameters) 1193 (defun x-create-frame-with-faces (&optional parameters)
1083 ;; Read this frame's geometry resource, if it has an explicit name, 1194 ;; Read this frame's geometry resource, if it has an explicit name,
1096 ;; Put the geometry parameters at the end. 1207 ;; Put the geometry parameters at the end.
1097 ;; Copy default-frame-alist so that they go after it. 1208 ;; Copy default-frame-alist so that they go after it.
1098 (setq parameters (append parameters default-frame-alist parsed))))) 1209 (setq parameters (append parameters default-frame-alist parsed)))))
1099 (let (frame) 1210 (let (frame)
1100 (if (null global-face-data) 1211 (if (null global-face-data)
1101 (setq frame (x-create-frame parameters)) 1212 (progn
1213 (setq frame (x-create-frame parameters))
1214 (frame-set-background-mode frame))
1102 (let* ((visibility-spec (assq 'visibility parameters)) 1215 (let* ((visibility-spec (assq 'visibility parameters))
1103 (faces (copy-alist global-face-data)) 1216 success faces rest)
1104 success
1105 (rest faces))
1106 (setq frame (x-create-frame (cons '(visibility . nil) parameters))) 1217 (setq frame (x-create-frame (cons '(visibility . nil) parameters)))
1218 (frame-set-background-mode frame)
1107 (unwind-protect 1219 (unwind-protect
1108 (progn 1220 (progn
1221
1222 ;; Copy the face alist, copying the face vectors
1223 ;; and emptying out their attributes.
1224 (setq faces
1225 (mapcar '(lambda (elt)
1226 (cons (car elt)
1227 (vector 'face
1228 (face-name (cdr elt))
1229 (face-id (cdr elt))
1230 nil nil nil nil nil)))
1231 global-face-data))
1109 (set-frame-face-alist frame faces) 1232 (set-frame-face-alist frame faces)
1110 1233
1234 ;; Handle the reverse-video frame parameter
1235 ;; and X resource. x-create-frame does not handle this one.
1111 (if (cdr (or (assq 'reverse parameters) 1236 (if (cdr (or (assq 'reverse parameters)
1112 (assq 'reverse default-frame-alist) 1237 (assq 'reverse default-frame-alist)
1113 (let ((resource (x-get-resource "reverseVideo" 1238 (let ((resource (x-get-resource "reverseVideo"
1114 "ReverseVideo"))) 1239 "ReverseVideo")))
1115 (if resource 1240 (if resource
1128 (modify-frame-parameters frame 1253 (modify-frame-parameters frame
1129 (list (cons 'mouse-color fg)))) 1254 (list (cons 'mouse-color fg))))
1130 (if (equal bg (cdr (assq 'cursor-color params))) 1255 (if (equal bg (cdr (assq 'cursor-color params)))
1131 (modify-frame-parameters frame 1256 (modify-frame-parameters frame
1132 (list (cons 'cursor-color fg)))))) 1257 (list (cons 'cursor-color fg))))))
1133 ;; Copy the vectors that represent the faces. 1258
1134 ;; Also fill them in from X resources. 1259 ;; Set up faces from the defface information
1260 (mapcar (lambda (symbol)
1261 (let ((spec (or (get symbol 'saved-face)
1262 (get symbol 'face-defface-spec))))
1263 (when spec
1264 (face-spec-set symbol spec frame))))
1265 (face-list))
1266
1267 ;; Set up faces from the global face data.
1268 (setq rest faces)
1135 (while rest 1269 (while rest
1136 (let ((global (cdr (car rest)))) 1270 (let* ((face (car (car rest)))
1137 (setcdr (car rest) (vector 'face 1271 (global (cdr (assq face global-face-data))))
1138 (face-name (cdr (car rest))) 1272 (face-fill-in face global frame))
1139 (face-id (cdr (car rest))) 1273 (setq rest (cdr rest)))
1140 nil nil nil nil nil)) 1274
1141 (face-fill-in (car (car rest)) global frame)) 1275 ;; Set up faces from the X resources.
1276 (setq rest faces)
1277 (while rest
1142 (make-face-x-resource-internal (cdr (car rest)) frame t) 1278 (make-face-x-resource-internal (cdr (car rest)) frame t)
1143 (setq rest (cdr rest))) 1279 (setq rest (cdr rest)))
1280
1281 ;; Make the frame visible, if desired.
1144 (if (null visibility-spec) 1282 (if (null visibility-spec)
1145 (make-frame-visible frame) 1283 (make-frame-visible frame)
1146 (modify-frame-parameters frame (list visibility-spec))) 1284 (modify-frame-parameters frame (list visibility-spec)))
1147 (setq success t)) 1285 (setq success t))
1148 (or success 1286 (or success
1149 (delete-frame frame))))) 1287 (delete-frame frame)))))
1150 ;; Set up the background-mode frame parameter
1151 ;; so that programs can decide good ways of highlighting
1152 ;; on this frame.
1153 (let ((bg-resource (x-get-resource ".backgroundMode"
1154 "BackgroundMode"))
1155 (params (frame-parameters frame))
1156 (bg-mode))
1157 (setq bg-mode
1158 (cond (bg-resource (intern (downcase bg-resource)))
1159 ((< (apply '+ (x-color-values
1160 (cdr (assq 'background-color params))
1161 frame))
1162 ;; Just looking at the screen,
1163 ;; colors whose values add up to .6 of the white total
1164 ;; still look dark to me.
1165 (* (apply '+ (x-color-values "white" frame)) .6))
1166 'dark)
1167 (t 'light)))
1168 (modify-frame-parameters frame
1169 (list (cons 'background-mode bg-mode)
1170 (cons 'display-type
1171 (cond ((x-display-color-p frame)
1172 'color)
1173 ((x-display-grayscale-p frame)
1174 'grayscale)
1175 (t 'mono))))))
1176 frame)) 1288 frame))
1289
1290 (defcustom frame-background-mode nil
1291 "*The brightness of the background.
1292 Set this to the symbol dark if your background color is dark, light if
1293 your background is light, or nil (default) if you want Emacs to
1294 examine the brightness for you."
1295 :group 'faces
1296 :type '(choice (choice-item dark)
1297 (choice-item light)
1298 (choice-item :tag "default" nil)))
1299
1300 (defun frame-set-background-mode (frame)
1301 "Set up the `background-mode' and `display-type' frame parameters for FRAME."
1302 (let ((bg-resource (x-get-resource ".backgroundMode"
1303 "BackgroundMode"))
1304 (params (frame-parameters frame))
1305 (bg-mode))
1306 (setq bg-mode
1307 (cond (frame-background-mode)
1308 (bg-resource (intern (downcase bg-resource)))
1309 ((< (apply '+ (x-color-values
1310 (cdr (assq 'background-color params))
1311 frame))
1312 ;; Just looking at the screen,
1313 ;; colors whose values add up to .6 of the white total
1314 ;; still look dark to me.
1315 (* (apply '+ (x-color-values "white" frame)) .6))
1316 'dark)
1317 (t 'light)))
1318 (modify-frame-parameters frame
1319 (list (cons 'background-mode bg-mode)
1320 (cons 'display-type
1321 (cond ((x-display-color-p frame)
1322 'color)
1323 ((x-display-grayscale-p frame)
1324 'grayscale)
1325 (t 'mono)))))))
1177 1326
1178 ;; Update a frame's faces when we change its default font. 1327 ;; Update a frame's faces when we change its default font.
1179 (defun frame-update-faces (frame) 1328 (defun frame-update-faces (frame)
1180 (let* ((faces global-face-data) 1329 (let* ((faces global-face-data)
1181 (rest faces)) 1330 (rest faces))