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);