Mercurial > emacs
comparison src/xfaces.c @ 2391:226dcdb8ab67
*** empty log message ***
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Sat, 27 Mar 1993 18:32:23 +0000 |
parents | f881f2936eec |
children | b513de4de386 |
comparison
equal
deleted
inserted
replaced
2390:e611237d4420 | 2391:226dcdb8ab67 |
---|---|
1 /* Must define frame->faces, frame->n_faces, | |
2 FRAME_NORMAL_FACE, FRAME_MODELINE_FACE. */ | |
3 | |
4 /* "Face" primitives | 1 /* "Face" primitives |
5 Copyright (C) 1992, 1993 Free Software Foundation. | 2 Copyright (C) 1992, 1993 Free Software Foundation. |
6 | 3 |
7 This file is part of GNU Emacs. | 4 This file is part of GNU Emacs. |
8 | 5 |
18 | 15 |
19 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
20 along with GNU Emacs; see the file COPYING. If not, write to | 17 along with GNU Emacs; see the file COPYING. If not, write to |
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | 18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ |
22 | 19 |
23 struct face | 20 /* This derived from work by Lucid (some parts very loosely so). */ |
24 { | |
25 unsigned char underline; | |
26 unsigned char hilited; | |
27 unsigned char modif; | |
28 GC facegc; | |
29 XFontStruct * font; | |
30 unsigned long foreground; | |
31 unsigned long background; | |
32 Pixmap back_pixmap; | |
33 unsigned int pixmap_w, pixmap_h /* , pixmap_depth */; | |
34 }; | |
35 | 21 |
36 #include <sys/types.h> | 22 #include <sys/types.h> |
37 #include <sys/stat.h> | 23 #include <sys/stat.h> |
38 | 24 |
39 #include "config.h" | 25 #include "config.h" |
40 #include "lisp.h" | 26 #include "lisp.h" |
41 | 27 |
42 #include "xterm.h" | 28 #include "xterm.h" |
43 #include "buffer.h" | 29 #include "buffer.h" |
30 #include "dispextern.h" | |
44 #include "frame.h" | 31 #include "frame.h" |
45 #include "window.h" | 32 /* #include "window.h" */ |
46 #include "indent.h" | |
47 | 33 |
48 /* Display Context for the icons */ | 34 /* Display Context for the icons */ |
49 #include <X11/Intrinsic.h> | 35 #include <X11/Intrinsic.h> |
50 #include <X11/StringDefs.h> | 36 #include <X11/StringDefs.h> |
51 #include <X11/Xmu/Drawing.h> | 37 #include <X11/Xmu/Drawing.h> |
52 #include <X11/Xos.h> | 38 #include <X11/Xos.h> |
53 | 39 |
54 /* We use face structures in two ways: | 40 /* We use face structures in two ways: |
55 At the frame level, each frame has a vector of faces. (f->faces). | 41 At the frame level, each frame has a vector of faces (FRAME_FACES). |
56 Face number 0 is the normal face (for normal text). | 42 Face number 0 is the default face (for normal text). |
57 Face number 1 is the mode line face. | 43 Face number 1 is the mode line face. |
58 Higher face numbers have no built-in meaning. | 44 Higher face numbers have no built-in meaning. |
59 The faces in these vectors are called "frame faces". | 45 The faces in these vectors are called "frame faces". |
60 | 46 |
61 Faces number 0 and 1 have graphics contexts. | 47 Faces number 0 and 1 have graphics contexts. |
79 /* The number of face-id's in use (same for all frames). */ | 65 /* The number of face-id's in use (same for all frames). */ |
80 int next_face_id; | 66 int next_face_id; |
81 | 67 |
82 #define FACE_DEFAULT (~0) | 68 #define FACE_DEFAULT (~0) |
83 | 69 |
70 #define xfree free | |
71 | |
72 Lisp_Object Qface, Qwindow, Qpriority; | |
73 | |
84 static struct face *allocate_face (); | 74 static struct face *allocate_face (); |
85 static void build_face (); | 75 static void build_face (); |
76 static int sort_overlays (); | |
77 static struct face *get_display_face (); | |
78 static Lisp_Object face_name_id_number (); | |
86 | 79 |
87 /* Make a new face that's a copy of an existing one. */ | 80 /* Make a new face that's a copy of an existing one. */ |
88 | 81 |
89 static struct face * | 82 static struct face * |
90 copy_face (face) | 83 copy_face (face) |
93 struct face *result = allocate_face (); | 86 struct face *result = allocate_face (); |
94 | 87 |
95 result->font = face->font; | 88 result->font = face->font; |
96 result->foreground = face->foreground; | 89 result->foreground = face->foreground; |
97 result->background = face->background; | 90 result->background = face->background; |
98 result->back_pixmap = face->back_pixmap; | 91 result->stipple = face->stipple; |
99 result->underline = face->underline; | 92 result->underline = face->underline; |
100 | 93 |
101 return result; | 94 return result; |
102 } | 95 } |
103 | 96 |
106 struct face *face1, *face2; | 99 struct face *face1, *face2; |
107 { | 100 { |
108 return (face1->font == face2->font | 101 return (face1->font == face2->font |
109 && face1->foreground == face2->foreground | 102 && face1->foreground == face2->foreground |
110 && face1->background == face2->background | 103 && face1->background == face2->background |
111 && face1->back_pixmap == face2->back_pixmap | 104 && face1->stipple == face2->stipple |
112 && face1->underline == face2->underline); | 105 && face1->underline == face2->underline); |
113 } | 106 } |
114 | 107 |
115 /* Return the unique display face corresponding to the user-level face FACE. | 108 /* Return the unique display face corresponding to the user-level face FACE. |
116 | 109 |
121 get_cached_face (f, face) | 114 get_cached_face (f, face) |
122 struct frame *f; | 115 struct frame *f; |
123 struct face *face; | 116 struct face *face; |
124 { | 117 { |
125 int i, empty = -1; | 118 int i, empty = -1; |
119 struct face *result; | |
126 | 120 |
127 /* Look for an existing display face that does the job. | 121 /* Look for an existing display face that does the job. |
128 Also find an empty slot if any. */ | 122 Also find an empty slot if any. */ |
129 for (i = 0; i < nfaces; i++) | 123 for (i = 0; i < nfaces; i++) |
130 { | 124 { |
165 void | 159 void |
166 clear_face_vector () | 160 clear_face_vector () |
167 { | 161 { |
168 Lisp_Object rest; | 162 Lisp_Object rest; |
169 Display *dpy = x_current_display; | 163 Display *dpy = x_current_display; |
164 int i; | |
170 | 165 |
171 BLOCK_INPUT; | 166 BLOCK_INPUT; |
172 /* Free the display faces in the face_vector. */ | 167 /* Free the display faces in the face_vector. */ |
173 for (i = 0; i < nfaces; i++) | 168 for (i = 0; i < nfaces; i++) |
174 { | 169 { |
175 struct face *face = face_vector[i]; | 170 struct face *face = face_vector[i]; |
176 if (face->facegc) | 171 if (face->gc) |
177 XFreeGC (dpy, face->facegc); | 172 XFreeGC (dpy, face->gc); |
178 xfree (face); | 173 xfree (face); |
179 } | 174 } |
180 nfaces = 0; | 175 nfaces = 0; |
181 | 176 |
182 UNBLOCK_INPUT; | 177 UNBLOCK_INPUT; |
183 } | 178 } |
184 | 179 |
185 /* Make a graphics context for face FACE, which is on frame F. */ | 180 /* Make a graphics context for face FACE, which is on frame F, |
181 if that can be done. */ | |
186 | 182 |
187 static void | 183 static void |
188 build_face (f, face) | 184 build_face (f, face) |
189 struct frame* f; | 185 struct frame* f; |
190 struct face* face; | 186 struct face* face; |
191 { | 187 { |
192 GC gc; | 188 GC gc; |
193 XGCValues xgcv; | 189 XGCValues xgcv; |
194 unsigned long mask; | 190 unsigned long mask; |
195 | 191 |
196 xgcv.foreground = face->foreground; | 192 if (face->foreground != FACE_DEFAULT) |
197 xgcv.background = face->background; | 193 xgcv.foreground = face->foreground; |
198 xgcv.font = face->font->fid; | 194 else |
195 xgcv. foreground = f->display.x->foreground_pixel; | |
196 if (face->background != FACE_DEFAULT) | |
197 xgcv.background = face->background; | |
198 else | |
199 xgcv. background = f->display.x->background_pixel; | |
200 if (face->font && (int) face->font != FACE_DEFAULT) | |
201 xgcv.font = face->font->fid; | |
202 else | |
203 xgcv.font = f->display.x->font->fid; | |
199 xgcv.graphics_exposures = 0; | 204 xgcv.graphics_exposures = 0; |
200 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; | 205 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; |
201 gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f), | 206 gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f), |
202 mask, &xgcv); | 207 mask, &xgcv); |
203 #if 0 | 208 #if 0 |
204 if (face->back_pixmap && face->back_pixmap != FACE_DEFAULT) | 209 if (face->stipple && face->stipple != FACE_DEFAULT) |
205 XSetStipple (XtDisplay (f->display.x->widget), gc, face->back_pixmap); | 210 XSetStipple (x_current_display, gc, face->stipple); |
206 #endif | 211 #endif |
207 face->facegc = gc; | 212 face->gc = gc; |
208 } | 213 } |
209 | 214 |
210 /* Modify face TO by copying from FROM all properties which have | 215 /* Modify face TO by copying from FROM all properties which have |
211 nondefault settings. */ | 216 nondefault settings. */ |
212 | 217 |
220 } | 225 } |
221 if (from->foreground != FACE_DEFAULT) | 226 if (from->foreground != FACE_DEFAULT) |
222 to->foreground = from->foreground; | 227 to->foreground = from->foreground; |
223 if (from->background != FACE_DEFAULT) | 228 if (from->background != FACE_DEFAULT) |
224 to->background = from->background; | 229 to->background = from->background; |
225 if (from->back_pixmap != FACE_DEFAULT) | 230 if (from->stipple != FACE_DEFAULT) |
226 to->back_pixmap = from->back_pixmap; | 231 to->stipple = from->stipple; |
227 if (from->underline) | 232 if (from->underline) |
228 to->underline = from->underline; | 233 to->underline = from->underline; |
229 } | 234 } |
235 | |
236 struct sortvec | |
237 { | |
238 Lisp_Object overlay; | |
239 int beg, end; | |
240 int priority; | |
241 }; | |
230 | 242 |
231 /* Return the display face associated with a buffer position POS. | 243 /* Return the display face associated with a buffer position POS. |
232 Store into *ENDPTR the position at which a different face is needed. | 244 Store into *ENDPTR the position at which a different face is needed. |
233 This does not take account of glyphs that specify their own face codes. | 245 This does not take account of glyphs that specify their own face codes. |
234 F is the frame in use for display. */ | 246 F is the frame in use for display, and W is the window. */ |
235 | 247 |
236 struct face * | 248 struct face * |
237 compute_char_face (f, pos, endptr) | 249 compute_char_face (f, w, pos, endptr) |
238 struct frame *f; | 250 struct frame *f; |
251 struct window *w; | |
239 int pos; | 252 int pos; |
240 int *endptr; | 253 int *endptr; |
241 { | 254 { |
242 struct face face; | 255 struct face face; |
243 Lisp_Object prop, position, length; | 256 Lisp_Object prop, position, length; |
245 int i, j, noverlays; | 258 int i, j, noverlays; |
246 int facecode; | 259 int facecode; |
247 int endpos; | 260 int endpos; |
248 Lisp_Object *overlay_vec; | 261 Lisp_Object *overlay_vec; |
249 int len; | 262 int len; |
263 struct sortvec *sortvec; | |
264 Lisp_Object frame; | |
265 | |
266 XSET (frame, Lisp_Frame, f); | |
250 | 267 |
251 XFASTINT (position) = pos; | 268 XFASTINT (position) = pos; |
252 prop = Fget_text_property (position, Qface); | 269 prop = Fget_text_property (position, Qface); |
253 | 270 |
254 len = 10; | 271 len = 10; |
255 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object)); | 272 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object)); |
256 noverlays = overlays_at (pos, &overlay_vec, &len, &endpos); | 273 noverlays = overlays_at (pos, &overlay_vec, &len, &endpos); |
257 | 274 |
258 /* Optimize the default case. */ | 275 /* Optimize the default case. */ |
259 if (noverlays == 0 && NILP (prop)) | 276 if (noverlays == 0 && NILP (prop)) |
260 return FRAME_NORMAL_FACE (f); | 277 return FRAME_DEFAULT_FACE (f); |
261 | 278 |
262 bcopy (FRAME_NORMAL_FACE (f), &face, sizeof (struct face)); | 279 bcopy (FRAME_DEFAULT_FACE (f), &face, sizeof (struct face)); |
263 | 280 |
264 if (!NILP (prop)) | 281 if (!NILP (prop)) |
265 { | 282 { |
266 facecode = Fface_name_id_number (prop); | 283 facecode = face_name_id_number (frame, prop); |
267 if (facecode >= 0 && facecode < f->n_faces && f->faces[facecode] != 0) | 284 if (facecode >= 0 && facecode < FRAME_N_FACES (f) |
268 merge_faces (f->faces[facecode], &face); | 285 && FRAME_FACES (f) [facecode] != 0) |
269 } | 286 merge_faces (FRAME_FACES (f) [facecode], &face); |
270 | 287 } |
271 /* Discard invalid overlays from the vector. */ | 288 |
289 /* Put the valid and relevant overlays into sortvec. */ | |
290 sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec)); | |
291 | |
272 for (i = 0, j = 0; i < noverlays; i++) | 292 for (i = 0, j = 0; i < noverlays; i++) |
273 { | 293 { |
274 overlay = overlay_vec[i]; | 294 overlay = overlay_vec[i]; |
275 | 295 |
276 if (OVERLAY_VALID (overlay) | 296 if (OVERLAY_VALID (overlay) |
277 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 | 297 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 |
278 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) | 298 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) |
279 overlay_vec[j++] = overlay; | 299 { |
300 Lisp_Object window; | |
301 window = Foverlay_get (overlay, Qwindow); | |
302 | |
303 /* Also ignore overlays limited to one window | |
304 if it's not the window we are using. */ | |
305 if (NILP (window) || XWINDOW (window) == w) | |
306 { | |
307 Lisp_Object tem; | |
308 | |
309 /* This overlay is good and counts: | |
310 put it in sortvec. */ | |
311 sortvec[j].overlay = overlay; | |
312 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay)); | |
313 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay)); | |
314 tem = Foverlay_get (overlay, Qpriority); | |
315 if (INTEGERP (tem)) | |
316 sortvec[j].priority = XINT (tem); | |
317 else | |
318 sortvec[j].priority = 0; | |
319 j++; | |
320 } | |
321 } | |
280 } | 322 } |
281 noverlays = j; | 323 noverlays = j; |
282 | 324 |
283 /* Sort the overlays into the proper order. */ | 325 /* Sort the overlays into the proper order: increasing priority. */ |
326 | |
327 qsort (sortvec, noverlays, sizeof (struct sortvec), sort_overlays); | |
284 | 328 |
285 /* Now merge the overlay data in that order. */ | 329 /* Now merge the overlay data in that order. */ |
286 | 330 |
287 for (i = 0; i < noverlays; i++) | 331 for (i = 0; i < noverlays; i++) |
288 { | 332 { |
290 if (!NILP (prop)) | 334 if (!NILP (prop)) |
291 { | 335 { |
292 Lisp_Object oend; | 336 Lisp_Object oend; |
293 int oendpos; | 337 int oendpos; |
294 | 338 |
295 facecode = Fface_name_id_number (prop); | 339 facecode = face_name_id_number (frame, prop); |
296 if (facecode >= 0 && facecode < f->n_faces | 340 if (facecode >= 0 && facecode < FRAME_N_FACES (f) |
297 && f->faces[facecode] != 0) | 341 && FRAME_FACES (f) [facecode] != 0) |
298 merge_faces (f->faces[facecode], &face); | 342 merge_faces (FRAME_FACES (f) [facecode], &face); |
299 | 343 |
300 oend = OVERLAY_END (overlay_vec[i]); | 344 oend = OVERLAY_END (overlay_vec[i]); |
301 oendpos = OVERLAY_POSITION (oend); | 345 oendpos = OVERLAY_POSITION (oend); |
302 if (oendpos > endpos) | 346 if (oendpos > endpos) |
303 endpos = oendpos; | 347 endpos = oendpos; |
309 *endptr = endpos; | 353 *endptr = endpos; |
310 | 354 |
311 return get_display_face (f, &face); | 355 return get_display_face (f, &face); |
312 } | 356 } |
313 | 357 |
358 int | |
359 sort_overlays (s1, s2) | |
360 struct sortvec *s1, *s2; | |
361 { | |
362 if (s1->priority != s2->priority) | |
363 return s1->priority - s2->priority; | |
364 if (s1->beg != s2->beg) | |
365 return s1->beg - s2->beg; | |
366 if (s1->end != s2->end) | |
367 return s2->end - s1->end; | |
368 return 0; | |
369 } | |
370 | |
314 /* Return the display face to use to display a special glyph | 371 /* Return the display face to use to display a special glyph |
315 which selects FACE_CODE as the face ID, | 372 which selects FACE_CODE as the face ID, |
316 assuming that ordinarily the face would be BASIC_FACE. | 373 assuming that ordinarily the face would be BASIC_FACE. |
317 F is the frame. */ | 374 F is the frame. */ |
318 | 375 |
324 { | 381 { |
325 struct face face; | 382 struct face face; |
326 | 383 |
327 bcopy (basic_face, &face, sizeof (struct face)); | 384 bcopy (basic_face, &face, sizeof (struct face)); |
328 | 385 |
329 if (face_code >= 0 && face_code < f->n_faces && f->faces[face_code] != 0) | 386 if (face_code >= 0 && face_code < FRAME_N_FACES (f) |
330 merge_faces (f->faces[face_code], &face); | 387 && FRAME_FACES (f) [face_code] != 0) |
388 merge_faces (FRAME_FACES (f) [face_code], &face); | |
331 | 389 |
332 return get_display_face (f, &face); | 390 return get_display_face (f, &face); |
333 } | 391 } |
334 | 392 |
335 /* Given a frame face, return an equivalent display face | 393 /* Given a frame face, return an equivalent display face |
341 struct face *face; | 399 struct face *face; |
342 { | 400 { |
343 struct face *result; | 401 struct face *result; |
344 | 402 |
345 /* Does the face have a GC already? */ | 403 /* Does the face have a GC already? */ |
346 if (face->facegc) | 404 if (face->gc) |
347 return face; | 405 return face; |
348 | 406 |
349 /* If it's equivalent to the normal face, use that. */ | 407 /* If it's equivalent to the default face, use that. */ |
350 if (face->font == FRAME_NORMAL_FACE (f)->font | 408 if (face->font == FRAME_DEFAULT_FACE (f)->font |
351 && face->foreground == FRAME_NORMAL_FACE (f)->foreground | 409 && face->foreground == FRAME_DEFAULT_FACE (f)->foreground |
352 && face->background == FRAME_NORMAL_FACE (f)->background | 410 && face->background == FRAME_DEFAULT_FACE (f)->background |
353 && face->back_pixmap == FRAME_NORMAL_FACE (f)->back_pixmap | 411 && face->stipple == FRAME_DEFAULT_FACE (f)->stipple |
354 && face->underline == FRAME_NORMAL_FACE (f)->underline) | 412 && face->underline == FRAME_DEFAULT_FACE (f)->underline) |
355 { | 413 { |
356 if (!FRAME_NORMAL_FACE (f)->framegc) | 414 if (!FRAME_DEFAULT_FACE (f)->gc) |
357 build_frame (f, FRAME_NORMAL_FACE (f)); | 415 build_face (f, FRAME_DEFAULT_FACE (f)); |
358 return FRAME_NORMAL_FACE (f); | 416 return FRAME_DEFAULT_FACE (f); |
359 } | 417 } |
360 | 418 |
361 /* If it's equivalent to the mode line face, use that. */ | 419 /* If it's equivalent to the mode line face, use that. */ |
362 if (face->font == FRAME_MODELINE_FACE (f)->font | 420 if (face->font == FRAME_MODE_LINE_FACE (f)->font |
363 && face->foreground == FRAME_MODELINE_FACE (f)->foreground | 421 && face->foreground == FRAME_MODE_LINE_FACE (f)->foreground |
364 && face->background == FRAME_MODELINE_FACE (f)->background | 422 && face->background == FRAME_MODE_LINE_FACE (f)->background |
365 && face->back_pixmap == FRAME_MODELINE_FACE (f)->back_pixmap | 423 && face->stipple == FRAME_MODE_LINE_FACE (f)->stipple |
366 && face->underline == FRAME_MODELINE_FACE (f)->underline) | 424 && face->underline == FRAME_MODE_LINE_FACE (f)->underline) |
367 { | 425 { |
368 if (!FRAME_MODELINE_FACE (f)->framegc) | 426 if (!FRAME_MODE_LINE_FACE (f)->gc) |
369 build_frame (f, FRAME_MODELINE_FACE (f)); | 427 build_face (f, FRAME_MODE_LINE_FACE (f)); |
370 return FRAME_MODELINE_FACE (f); | 428 return FRAME_MODE_LINE_FACE (f); |
371 } | 429 } |
372 | 430 |
373 /* Get a specialized display face. */ | 431 /* Get a specialized display face. */ |
374 return get_cached_face (f, face); | 432 return get_cached_face (f, face); |
375 } | 433 } |
382 struct face *result = (struct face *) xmalloc (sizeof (struct face)); | 440 struct face *result = (struct face *) xmalloc (sizeof (struct face)); |
383 bzero (result, sizeof (struct face)); | 441 bzero (result, sizeof (struct face)); |
384 result->font = (XFontStruct *) FACE_DEFAULT; | 442 result->font = (XFontStruct *) FACE_DEFAULT; |
385 result->foreground = FACE_DEFAULT; | 443 result->foreground = FACE_DEFAULT; |
386 result->background = FACE_DEFAULT; | 444 result->background = FACE_DEFAULT; |
387 result->back_pixmap = FACE_DEFAULT; | 445 result->stipple = FACE_DEFAULT; |
388 return result; | 446 return result; |
389 } | 447 } |
390 | 448 |
391 /* Make face id ID valid on frame F. */ | 449 /* Make face id ID valid on frame F. */ |
392 | 450 |
393 void | 451 void |
394 ensure_face_ready (f, id) | 452 ensure_face_ready (f, id) |
395 struct frame *f; | 453 struct frame *f; |
396 int id; | 454 int id; |
397 { | 455 { |
398 if (f->n_faces <= id) | 456 if (FRAME_N_FACES (f) <= id) |
399 { | 457 { |
400 int n = id + 10; | 458 int n = id + 10; |
401 int i; | 459 int i; |
402 if (!f->n_faces) | 460 if (!FRAME_N_FACES (f)) |
403 f->faces = (struct face **) xmalloc (sizeof (struct face *) * n); | 461 FRAME_FACES (f) |
462 = (struct face **) xmalloc (sizeof (struct face *) * n); | |
404 else | 463 else |
405 f->faces | 464 FRAME_FACES (f) |
406 = (struct face **) xrealloc (f->faces, sizeof (struct face *) * n); | 465 = (struct face **) xrealloc (FRAME_FACES (f), |
407 | 466 sizeof (struct face *) * n); |
408 f->n_faces = n; | 467 |
409 } | 468 bzero (FRAME_FACES (f) + FRAME_N_FACES (f), |
410 | 469 (n - FRAME_N_FACES (f)) * sizeof (struct face *)); |
411 f->faces[id] = allocate_face (); | 470 FRAME_N_FACES (f) = n; |
471 } | |
472 | |
473 if (FRAME_FACES (f) [id] == 0) | |
474 FRAME_FACES (f) [id] = allocate_face (); | |
412 } | 475 } |
413 | 476 |
414 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */ | 477 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */ |
415 | 478 |
416 #ifdef HAVE_X_WINDOWS | 479 #ifdef HAVE_X_WINDOWS |
457 int result; | 520 int result; |
458 | 521 |
459 if (NILP (name)) | 522 if (NILP (name)) |
460 return FACE_DEFAULT; | 523 return FACE_DEFAULT; |
461 | 524 |
462 cmap = DefaultColormapOfScreen (x_screen); | 525 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display)); |
463 | 526 |
464 CHECK_STRING (name, 0); | 527 CHECK_STRING (name, 0); |
465 BLOCK_INPUT; | 528 BLOCK_INPUT; |
466 result = XParseColor (dpy, cmap, (char *) XSTRING (name)->data, &color); | 529 result = XParseColor (dpy, cmap, (char *) XSTRING (name)->data, &color); |
467 UNBLOCK_INPUT; | 530 UNBLOCK_INPUT; |
484 { | 547 { |
485 Colormap cmap; | 548 Colormap cmap; |
486 Display *dpy = x_current_display; | 549 Display *dpy = x_current_display; |
487 if (pixel == FACE_DEFAULT) | 550 if (pixel == FACE_DEFAULT) |
488 return; | 551 return; |
489 cmap = DefaultColormapOfScreen (x_screen); | 552 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display)); |
490 BLOCK_INPUT; | 553 BLOCK_INPUT; |
491 XFreeColors (dpy, cmap, &pixel, 1, 0); | 554 XFreeColors (dpy, cmap, &pixel, 1, 0); |
492 UNBLOCK_INPUT; | 555 UNBLOCK_INPUT; |
493 } | 556 } |
494 | 557 |
497 | 560 |
498 /* frames */ | 561 /* frames */ |
499 | 562 |
500 void | 563 void |
501 init_frame_faces (f) | 564 init_frame_faces (f) |
502 struct frame f; | 565 struct frame *f; |
503 { | 566 { |
504 struct frame *other_frame = 0; | 567 struct frame *other_frame = 0; |
505 Lisp_Object rest; | 568 Lisp_Object rest; |
506 | 569 |
507 for (rest = Vframe_list; !NILP (rest); rest = Fcdr (rest)) | 570 for (rest = Vframe_list; !NILP (rest); rest = Fcdr (rest)) |
508 { | 571 { |
509 struct frame *f2 = XFRAME (Fcar (rest)); | 572 struct frame *f2 = XFRAME (Fcar (rest)); |
510 if (f2 != f && FRAME_IS_X (f2)) | 573 if (f2 != f && FRAME_X_P (f2)) |
511 { | 574 { |
512 other_frame = f2; | 575 other_frame = f2; |
513 break; | 576 break; |
514 } | 577 } |
515 } | 578 } |
516 | 579 |
517 if (other_frame) | 580 if (other_frame) |
518 { | 581 { |
519 /* Make sure this frame's face vector is as big as the others. */ | 582 /* Make sure this frame's face vector is as big as the others. */ |
520 f->n_faces = other_frame->n_faces; | 583 FRAME_N_FACES (f) = FRAME_N_FACES (other_frame); |
521 f->faces = (struct face **) xmalloc (f->n_faces * sizeof (struct face *)); | 584 FRAME_FACES (f) |
585 = (struct face **) xmalloc (FRAME_N_FACES (f) * sizeof (struct face *)); | |
522 | 586 |
523 /* Make sure the frame has the two basic faces. */ | 587 /* Make sure the frame has the two basic faces. */ |
524 FRAME_NORMAL_FACE (f) | 588 FRAME_DEFAULT_FACE (f) |
525 = copy_face (FRAME_NORMAL_FACE (other_frame)); | 589 = copy_face (FRAME_DEFAULT_FACE (other_frame)); |
526 FRAME_MODELINE_FACE (f) | 590 FRAME_MODE_LINE_FACE (f) |
527 = copy_face (FRAME_MODELINE_FACE (other_frame)); | 591 = copy_face (FRAME_MODE_LINE_FACE (other_frame)); |
528 } | 592 } |
529 } | 593 } |
530 | 594 |
531 | 595 |
532 /* Called from Fdelete_frame? */ | 596 /* Called from Fdelete_frame? */ |
536 struct frame *f; | 600 struct frame *f; |
537 { | 601 { |
538 Display *dpy = x_current_display; | 602 Display *dpy = x_current_display; |
539 int i; | 603 int i; |
540 | 604 |
541 for (i = 0; i < f->n_faces; i++) | 605 for (i = 0; i < FRAME_N_FACES (f); i++) |
542 { | 606 { |
543 struct face *face = f->faces [i]; | 607 struct face *face = FRAME_FACES (f) [i]; |
544 if (! face) | 608 if (! face) |
545 continue; | 609 continue; |
546 if (face->facegc) | 610 if (face->gc) |
547 XFreeGC (dpy, face->facegc); | 611 XFreeGC (dpy, face->gc); |
548 unload_font (f, face->font); | 612 unload_font (f, face->font); |
549 unload_color (f, face->foreground); | 613 unload_color (f, face->foreground); |
550 unload_color (f, face->background); | 614 unload_color (f, face->background); |
551 unload_pixmap (f, face->back_pixmap); | 615 #if 0 |
616 unload_pixmap (f, face->stipple); | |
617 #endif | |
552 xfree (face); | 618 xfree (face); |
553 } | 619 } |
554 xfree (f->faces); | 620 xfree (FRAME_FACES (f)); |
555 f->faces = 0; | 621 FRAME_FACES (f) = 0; |
556 f->n_faces = 0; | 622 FRAME_N_FACES (f) = 0; |
557 } | 623 } |
558 | 624 |
559 | 625 |
560 /* Lisp interface */ | 626 /* Lisp interface */ |
561 | 627 |
585 Lisp_Object face_id; | 651 Lisp_Object face_id; |
586 { | 652 { |
587 Lisp_Object rest; | 653 Lisp_Object rest; |
588 int id = XINT (face_id); | 654 int id = XINT (face_id); |
589 | 655 |
590 CHECK_FIXNUM (face_id, 0); | 656 CHECK_NUMBER (face_id, 0); |
591 if (id < 0) | 657 if (id < 0 || id >= next_face_id) |
592 error ("Face id must be nonnegative"); | 658 error ("Face id out of range"); |
593 | 659 |
594 for (rest = Vframe_list; !NILP (rest); rest = XCONS (rest)->cdr) | 660 for (rest = Vframe_list; !NILP (rest); rest = XCONS (rest)->cdr) |
595 { | 661 { |
596 struct frame *f = XFRAME (XCONS (rest)->car); | 662 struct frame *f = XFRAME (XCONS (rest)->car); |
597 ensure_face_ready (f, id); | 663 ensure_face_ready (f, id); |
609 struct frame *f; | 675 struct frame *f; |
610 int magic_p; | 676 int magic_p; |
611 int id; | 677 int id; |
612 | 678 |
613 CHECK_FRAME (frame, 0); | 679 CHECK_FRAME (frame, 0); |
614 CHECK_FIXNUM (face_id, 0); | 680 CHECK_NUMBER (face_id, 0); |
615 CHECK_SYMBOL (attr_name, 0); | 681 CHECK_SYMBOL (attr_name, 0); |
616 | 682 |
617 f = XFRAME (frame); | 683 f = XFRAME (frame); |
618 id = XINT (face_id); | 684 id = XINT (face_id); |
619 if (id < 0) | 685 if (id < 0 || id >= next_face_id) |
620 Fsignal (Qerror, Fcons (build_string ("invalid face id"), | 686 error ("Face id out of range"); |
621 Fcons (face_id, Fcons (frame, Qnil)))); | |
622 | 687 |
623 ensure_face_ready (f, id); | 688 ensure_face_ready (f, id); |
624 face = f->faces [XFASTINT (face_id)]; | 689 face = FRAME_FACES (f) [XFASTINT (face_id)]; |
625 if (! face) abort (); | |
626 | |
627 magic_p = (NILP (attr_value) && XFASTINT (face_id) <= 1); | |
628 | 690 |
629 if (EQ (attr_name, intern ("font"))) | 691 if (EQ (attr_name, intern ("font"))) |
630 { | 692 { |
631 #ifdef HAVE_X_WINDOWS | 693 XFontStruct *font = load_font (f, attr_value); |
632 XFontStruct *font; | |
633 if (magic_p) | |
634 error ("font of the `normal' or `modeline' face may not be nil"); | |
635 font = load_font (f, attr_value); | |
636 unload_font (f, face->font); | 694 unload_font (f, face->font); |
637 face->font = font; | 695 face->font = font; |
638 #endif /* HAVE_X_WINDOWS */ | |
639 } | 696 } |
640 else if (EQ (attr_name, intern ("foreground"))) | 697 else if (EQ (attr_name, intern ("foreground"))) |
641 { | 698 { |
642 #ifdef HAVE_X_WINDOWS | 699 unsigned long new_color = load_color (f, attr_value); |
643 unsigned long new_color; | |
644 if (magic_p) | |
645 error ("forground color of the `normal' or `modeline' face may not be nil"); | |
646 new_color = load_color (f, attr_value); | |
647 unload_color (f, face->foreground); | 700 unload_color (f, face->foreground); |
648 face->foreground = new_color; | 701 face->foreground = new_color; |
649 #endif /* HAVE_X_WINDOWS */ | |
650 } | 702 } |
651 else if (EQ (attr_name, intern ("background"))) | 703 else if (EQ (attr_name, intern ("background"))) |
652 { | 704 { |
653 #ifdef HAVE_X_WINDOWS | 705 unsigned long new_color = load_color (f, attr_value); |
654 unsigned long new_color; | |
655 if (magic_p) | |
656 error ("background color of the `normal' or `modeline' face may not be nil"); | |
657 new_color = load_color (f, attr_value); | |
658 unload_color (f, face->background); | 706 unload_color (f, face->background); |
659 face->background = new_color; | 707 face->background = new_color; |
660 #endif /* HAVE_X_WINDOWS */ | |
661 } | 708 } |
662 #if 0 | 709 #if 0 |
663 else if (EQ (attr_name, intern ("background-pixmap"))) | 710 else if (EQ (attr_name, intern ("background-pixmap"))) |
664 { | 711 { |
665 #ifdef HAVE_X_WINDOWS | |
666 unsigned int w, h, d; | 712 unsigned int w, h, d; |
667 unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h, &d, 0); | 713 unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h, &d, 0); |
668 unload_pixmap (f, face->back_pixmap); | 714 unload_pixmap (f, face->stipple); |
669 if (magic_p) new_pixmap = 0; | 715 if (NILP (attr_value)) |
670 face->back_pixmap = new_pixmap; | 716 new_pixmap = 0; |
717 face->stipple = new_pixmap; | |
671 face->pixmap_w = w; | 718 face->pixmap_w = w; |
672 face->pixmap_h = h; | 719 face->pixmap_h = h; |
673 /* face->pixmap_depth = d; */ | 720 /* face->pixmap_depth = d; */ |
674 #endif /* HAVE_X_WINDOWS */ | |
675 } | 721 } |
676 #endif /* 0 */ | 722 #endif /* 0 */ |
677 else if (EQ (attr_name, intern ("underline"))) | 723 else if (EQ (attr_name, intern ("underline"))) |
678 { | 724 { |
679 int new = !NILP (attr_value); | 725 int new = !NILP (attr_value); |
683 error ("unknown face attribute"); | 729 error ("unknown face attribute"); |
684 | 730 |
685 if (id == 0) | 731 if (id == 0) |
686 { | 732 { |
687 BLOCK_INPUT; | 733 BLOCK_INPUT; |
688 XFreeGC (dpy, FRAME_NORMAL_FACE (f)->facegc); | 734 if (FRAME_DEFAULT_FACE (f)->gc != 0) |
689 build_face (f, FRAME_NORMAL_FACE (f)); | 735 XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc); |
736 build_face (f, FRAME_DEFAULT_FACE (f)); | |
690 UNBLOCK_INPUT; | 737 UNBLOCK_INPUT; |
691 } | 738 } |
692 | 739 |
693 if (id == 1) | 740 if (id == 1) |
694 { | 741 { |
695 BLOCK_INPUT; | 742 BLOCK_INPUT; |
696 XFreeGC (dpy, FRAME_NORMAL_FACE (f)->facegc); | 743 if (FRAME_MODE_LINE_FACE (f)->gc != 0) |
697 build_face (f, FRAME_NORMAL_FACE (f)); | 744 XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc); |
745 build_face (f, FRAME_MODE_LINE_FACE (f)); | |
698 UNBLOCK_INPUT; | 746 UNBLOCK_INPUT; |
699 } | 747 } |
700 | 748 |
701 return Qnil; | 749 return Qnil; |
702 } | 750 } |
705 0, 0, 0, "") | 753 0, 0, 0, "") |
706 () | 754 () |
707 { | 755 { |
708 return make_number (next_face_id++); | 756 return make_number (next_face_id++); |
709 } | 757 } |
758 | |
759 /* Return the face id for name NAME on frame FRAME. | |
760 (It should be the same for all frames, | |
761 but it's as easy to use the "right" frame to look it up | |
762 as to use any other one.) */ | |
763 | |
764 static Lisp_Object | |
765 face_name_id_number (frame, name) | |
766 Lisp_Object frame, name; | |
767 { | |
768 Lisp_Object tem; | |
769 | |
770 CHECK_FRAME (frame, 0); | |
771 tem = Fcdr (Fassq (name, XFRAME (frame)->face_alist)); | |
772 CHECK_VECTOR (tem, 0); | |
773 tem = XVECTOR (tem)->contents[2]; | |
774 CHECK_NUMBER (tem, 0); | |
775 return XINT (tem); | |
776 } | |
710 | 777 |
711 void | 778 void |
712 syms_of_faces () | 779 syms_of_xfaces () |
713 { | 780 { |
781 Qwindow = intern ("window"); | |
782 staticpro (&Qwindow); | |
783 Qface = intern ("face"); | |
784 staticpro (&Qface); | |
785 Qpriority = intern ("priority"); | |
786 staticpro (&Qpriority); | |
787 | |
714 defsubr (&Sframe_face_alist); | 788 defsubr (&Sframe_face_alist); |
715 defsubr (&Sset_frame_face_alist); | 789 defsubr (&Sset_frame_face_alist); |
716 defsubr (&Smake_face_internal); | 790 defsubr (&Smake_face_internal); |
717 defsubr (&Sset_face_attribute_internal); | 791 defsubr (&Sset_face_attribute_internal); |
718 defsubr (&Sinternal_next_face_id); | 792 defsubr (&Sinternal_next_face_id); |