aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Blandy1993-06-22 07:25:42 +0000
committerJim Blandy1993-06-22 07:25:42 +0000
commit7b00de84fddc2fb043dff9be613b34401a23f952 (patch)
treee4c064c5b7746de9b391e80fbe11ddfc0ab4c084
parenta081bd37248abe85b193f4fdd59506b0b6a6f6ee (diff)
downloademacs-7b00de84fddc2fb043dff9be613b34401a23f952.tar.gz
emacs-7b00de84fddc2fb043dff9be613b34401a23f952.zip
Separate parameter faces (those created and modified by the user)
from the computed faces (the combinations created by compute_char_face), so that we don't waste global face id's. * xterm.h (struct x_display): Replace the fields faces and n_faces with fields param_faces, n_param_faces, computed_faces, n_computed_faces, and size_computed_faces. (FRAME_FACES, FRAME_N_FACES): Replaced by... (FRAME_COMPUTED_FACES, FRAME_N_COMPUTED_FACES, FRAME_PARAM_FACES, FRAME_N_PARAM_FACES): New macros. * xfaces.c: Doc fixes. (init_frame_faces): Call new_computed_face to create entries for the default and mode line faces. Use the FRAME...PARAM_FACES macros. (free_frame_faces): Use the FRAME...PARAM_FACES and FRAME...COMPUTED_FACES macros. Don't use the copy flag; all parameter faces have real X resources, and all computed faces just have copies. Free both the parameter and computed face arrays. (new_computed_face): New function. (intern_computed_face): Renamed from intern_frame_face; callers changed. Call new_computed_face. (ensure_face_ready, compute_char_face, compute_glyph_face): Use the FRAME...PARAM_FACES macros. (recompute_basic_faces): Use the FRAME...PARAM_FACES and FRAME...COMPUTED_FACES macros. Produce the computed faces by starting with the base faces and merging in the parameter faces. (Fset_face_attribute_internal): Use the FRAME...PARAM_FACES macros. Just call recompute_basic_faces if the default or mode line faces have changed. * xfns.c (Fx_list_fonts): Use the FRAME...PARAM_FACES macros. * xterm.c (dumpglyphs): Use the FRAME...COMPUTED_FACES macros. * dispextern.h (struct face): Remove the copy member. This is no longer necessary; all computed faces are copies, and no parameter faces are. * xfaces.c (face_vector, nfaces, nfaces_allocated): Make these static.
-rw-r--r--src/xfaces.c287
1 files changed, 159 insertions, 128 deletions
diff --git a/src/xfaces.c b/src/xfaces.c
index b5ef4169dc2..de7b66036de 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -55,11 +55,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
55 55
56/* ========================= Face Data Structures ========================= 56/* ========================= Face Data Structures =========================
57 57
58 All lisp code uses symbols as face names. 58 Let FACE-NAME be a symbol naming a face.
59 59
60 Each frame has a face_alist member (with the frame-face-alist and 60 Let FACE-VECTOR be (assq FACE-NAME (frame-face-alist FRAME))
61 set-frame-face-alist accessors), associating the face names with 61 FACE-VECTOR is either nil, or a vector of the form
62 vectors of the form
63 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P] 62 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
64 where 63 where
65 face is the symbol `face', 64 face is the symbol `face',
@@ -71,53 +70,67 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
71 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't 70 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
72 use right now, and 71 use right now, and
73 UNDERLINE-P is non-nil if the face should be underlined. 72 UNDERLINE-P is non-nil if the face should be underlined.
74 If any of these elements are nil, that allows the frame's parameters to 73 If any of these elements are nil, that parameter is considered
75 show through. 74 unspecified; parameters from faces specified by lower-priority
76 (lisp/faces.el maintains these association lists.) 75 overlays or text properties, or the parameters of the frame itself,
77 76 can show through. (lisp/faces.el maintains these lists.)
78 The frames' private alists hold the frame-local definitions for the 77
79 faces. The lisp variable global-face-data contains the global 78 (assq FACE-NAME global-face-data) returns a vector describing the
80 defaults for faces. (See lisp/faces.el for this too.) 79 global parameters for that face.
81 80
82 In the C code, we also have a `struct face' with the elements 81 Let PARAM-FACE be FRAME->display.x->param_faces[Faref (FACE-VECTOR, 2)].
83 `foreground', `background', `font', and `underline', 82 PARAM_FACE is a struct face whose members are the Xlib analogues of
84 which specify its visual appearance, and elements 83 the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
85 `gc' and `cached_index'; 84 nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
86 `gc' may be an X GC which has been built for the given display 85 These faces are called "parameter faces", because they're the ones
87 parameters. Faces with GC's are called `display faces'. Whether 86 lisp manipulates to control what gets displayed. Elements 0 and 1
88 or not a face has a GC depends on what data structure the face is 87 of FRAME->display.x->param_faces are special - they describe the
89 in; we explain these more below. (See src/dispextern.h.) 88 default and mode line faces. None of the faces in param_faces have
90 89 GC's. (See src/dispextern.h for the definiton of struct face.
91 Each frame also has members called `faces' and `n_faces' (with the 90 lisp/faces.el maintains the isomorphism between face_alist and
92 accessors FRAME_FACES and FRAME_N_FACES), which define an array of 91 param_faces.)
93 struct face pointers, indexed by face ID (element 2 of the 92
94 vector). These are called "frame faces". 93 The functions compute_char_face and compute_glyph_face find and
95 Element 0 is the default face --- the one used for normal text. 94 combine the parameter faces associated with overlays and text
96 Element 1 is the modeline face. 95 properties. The resulting faces are called "computed faces"; none
97 These faces have their GC's set; the rest do not. 96 of their members are FACE_DEFAULT; they are completely specified.
98 If faces[i] is filled in (i.e. non-zero) on one frame, then it must 97 They then call intern_compute_face to search
99 be filled in on all frames. Code assumes that face ID's can be 98 FRAME->display.x->computed_faces for a matching face, add one if
100 used on any frame. (See src/xterm.h.) 99 none is found, and return the index into
101 100 FRAME->display.x->computed_faces. FRAME's glyph matrices use these
102 The global variables `face_vector' and `nfaces' define another 101 indices to record the faces of the matrix characters, and the X
103 array of struct face pointers, with their GC's set. This array 102 display hooks consult compute_faces to decide how to display these
104 acts as a cache of GC's to be used by all frames. The function 103 characters. Elements 0 and 1 of computed_faces always describe the
105 `intern_face', passed a struct face *, searches face_vector for a 104 default and mode-line faces.
106 struct face with the same parameters, adds a new one with a GC if 105
107 it doesn't find one, and returns it. If you have a `struct face', 106 Elements 0 and 1 of computed_faces have GC's; all the other faces
108 and you want a GC for it, call intern_face on that struct, and it 107 in computed_faces do not. The global array face_vector contains
109 will return a `struct face *' with its GC set. The faces in 108 faces with their GC's set. Given a computed_face, the function
110 face_vector are called `cached faces.' (See src/xfaces.c.) 109 intern_face finds (or adds) an element of face_vector with
111 110 equivalent parameters, and returns a pointer to that face, whose GC
112 The `GLYPH' data type is an unsigned integer type; the bottom byte 111 can then be used for display.
113 is a character code, and the byte above that is a face id. The 112
114 `struct frame_glyphs' structure, used to describe frames' current 113 Constraints:
115 or desired contents, is essentially a matrix of GLYPHs; the face 114
116 ID's in a struct frame_glyphs are indices into FRAME_FACES. (See 115 Symbols naming faces must have associations on all frames; for any
117 src/dispextern.h.) 116 FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
117 FRAME)) is non-nil, it must be non-nil for all frames.
118
119 Analogously, indices into param_faces must be valid on all frames;
120 if param_faces[i] is a non-zero face pointer on one frame, then it
121 must be filled in on all frames. Code assumes that face ID's can
122 be used on any frame.
118 123
119 Some subtleties: 124 Some subtleties:
120 125
126 Why do we keep param_faces and computed_faces separate?
127 computed_faces contains an element for every combination of facial
128 parameters we have ever displayed. indices into param_faces have
129 to be valid on all frames. If they were the same array, then that
130 array would grow very large on all frames, because any facial
131 combination displayed on any frame would need to be a valid entry
132 on all frames.
133
121 Since face_vector is just a cache --- there are no pointers into it 134 Since face_vector is just a cache --- there are no pointers into it
122 from the rest of the code, and everyone accesses it through 135 from the rest of the code, and everyone accesses it through
123 intern_face --- we could just free its GC's and throw the whole 136 intern_face --- we could just free its GC's and throw the whole
@@ -127,7 +140,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
127 refill it as needed. The function clear_face_vector performs this 140 refill it as needed. The function clear_face_vector performs this
128 purge. 141 purge.
129 142
130 We're often applying intern_face to faces in frames' local arrays - 143 We're often applying intern_face to faces in computed_faces -
131 for example, we do this while sending GLYPHs from a struct 144 for example, we do this while sending GLYPHs from a struct
132 frame_glyphs to X during redisplay. It would be nice to avoid 145 frame_glyphs to X during redisplay. It would be nice to avoid
133 searching all of face_vector every time we intern a frame's face. 146 searching all of face_vector every time we intern a frame's face.
@@ -139,11 +152,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
139/* Definitions and declarations. */ 152/* Definitions and declarations. */
140 153
141/* A table of display faces. */ 154/* A table of display faces. */
142struct face **face_vector; 155static struct face **face_vector;
143/* The length in use of the table. */ 156/* The length in use of the table. */
144int nfaces; 157static int nfaces;
145/* The allocated length of the table. */ 158/* The allocated length of the table. */
146int nfaces_allocated; 159static int nfaces_allocated;
147 160
148/* The number of face-id's in use (same for all frames). */ 161/* The number of face-id's in use (same for all frames). */
149int next_face_id; 162int next_face_id;
@@ -161,6 +174,8 @@ static void build_face ( /* FRAME_PTR, struct face * */ );
161int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ ); 174int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
162 175
163struct face *intern_face ( /* FRAME_PTR, struct face * */ ); 176struct face *intern_face ( /* FRAME_PTR, struct face * */ );
177static int new_computed_face ( /* FRAME_PTR, struct face * */ );
178static int intern_computed_face ( /* FRAME_PTR, struct face * */ );
164static void ensure_face_ready ( /* FRAME_PTR, int id */ ); 179static void ensure_face_ready ( /* FRAME_PTR, int id */ );
165void recompute_basic_faces ( /* FRAME_PTR f */ ); 180void recompute_basic_faces ( /* FRAME_PTR f */ );
166 181
@@ -259,7 +274,7 @@ get_cached_face (f, face)
259 return result; 274 return result;
260} 275}
261 276
262/* Given a frame face, return an equivalent display face 277/* Given a computed face, return an equivalent display face
263 (one which has a graphics context). */ 278 (one which has a graphics context). */
264 279
265struct face * 280struct face *
@@ -455,7 +470,7 @@ unload_color (f, pixel)
455#endif 470#endif
456} 471}
457 472
458/* Initializing face arrays for frames. */ 473/* Managing parameter face arrays for frames. */
459 474
460void 475void
461init_frame_faces (f) 476init_frame_faces (f)
@@ -464,6 +479,8 @@ init_frame_faces (f)
464 ensure_face_ready (f, 0); 479 ensure_face_ready (f, 0);
465 ensure_face_ready (f, 1); 480 ensure_face_ready (f, 1);
466 481
482 new_computed_face (f, FRAME_PARAM_FACES (f)[0]);
483 new_computed_face (f, FRAME_PARAM_FACES (f)[1]);
467 recompute_basic_faces (f); 484 recompute_basic_faces (f);
468 485
469 /* Find another X frame. */ 486 /* Find another X frame. */
@@ -486,8 +503,8 @@ init_frame_faces (f)
486 if (FRAMEP (result)) 503 if (FRAMEP (result))
487 { 504 {
488 int i; 505 int i;
489 int n_faces = XFRAME (result)->display.x->n_faces; 506 int n_faces = FRAME_N_PARAM_FACES (XFRAME (result));
490 struct face **faces = XFRAME (result)->display.x->faces; 507 struct face **faces = FRAME_PARAM_FACES (XFRAME (result));
491 508
492 for (i = 2; i < n_faces; i++) 509 for (i = 2; i < n_faces; i++)
493 if (faces[i]) 510 if (faces[i])
@@ -507,89 +524,112 @@ free_frame_faces (f)
507 524
508 BLOCK_INPUT; 525 BLOCK_INPUT;
509 526
510 for (i = 0; i < FRAME_N_FACES (f); i++) 527 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
511 { 528 {
512 struct face *face = FRAME_FACES (f) [i]; 529 struct face *face = FRAME_PARAM_FACES (f) [i];
513 if (face) 530 if (face)
514 { 531 {
515 if (face->gc) 532 if (face->gc)
516 XFreeGC (dpy, face->gc); 533 XFreeGC (dpy, face->gc);
517 if (! face->copy) 534 unload_font (f, face->font);
518 { 535 unload_color (f, face->foreground);
519 unload_font (f, face->font); 536 unload_color (f, face->background);
520 unload_color (f, face->foreground);
521 unload_color (f, face->background);
522#if 0 537#if 0
523 unload_pixmap (f, face->stipple); 538 unload_pixmap (f, face->stipple);
524#endif 539#endif
525 }
526 xfree (face); 540 xfree (face);
527 } 541 }
528 } 542 }
529 xfree (FRAME_FACES (f)); 543 xfree (FRAME_PARAM_FACES (f));
530 FRAME_FACES (f) = 0; 544 FRAME_PARAM_FACES (f) = 0;
531 FRAME_N_FACES (f) = 0; 545 FRAME_N_PARAM_FACES (f) = 0;
546
547 /* All faces in FRAME_COMPUTED_FACES use resources copied from
548 FRAME_PARAM_FACES; we can free them without fuss. */
549 xfree (FRAME_COMPUTED_FACES (f));
550 FRAME_COMPUTED_FACES (f) = 0;
551 FRAME_N_COMPUTED_FACES (f) = 0;
532 552
533 UNBLOCK_INPUT; 553 UNBLOCK_INPUT;
534} 554}
535 555
536/* Interning faces in a frame's face array. */ 556/* Interning faces in a frame's face array. */
537 557
538/* Find a match for NEW_FACE in a FRAME's face array, and add it if we don't
539 find one. */
540static int 558static int
541intern_frame_face (frame, new_face) 559new_computed_face (f, new_face)
542 struct frame *frame; 560 struct frame *f;
561 struct face *new_face;
562{
563 int i = FRAME_N_COMPUTED_FACES (f);
564
565 if (i >= FRAME_SIZE_COMPUTED_FACES (f))
566 {
567 int new_size = i + 32;
568
569 FRAME_COMPUTED_FACES (f)
570 = (struct face **)
571 (FRAME_SIZE_COMPUTED_FACES (f) == 0
572 ? xmalloc (new_size * sizeof (struct face *))
573 : xrealloc (FRAME_COMPUTED_FACES (f),
574 new_size * sizeof (struct face *)));
575 FRAME_SIZE_COMPUTED_FACES (f) = new_size;
576 }
577
578 i = FRAME_N_COMPUTED_FACES (f)++;
579 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
580 return i;
581}
582
583
584/* Find a match for NEW_FACE in a FRAME's computed face array, and add
585 it if we don't find one. */
586static int
587intern_computed_face (f, new_face)
588 struct frame *f;
543 struct face *new_face; 589 struct face *new_face;
544{ 590{
545 int len = FRAME_N_FACES (frame); 591 int len = FRAME_N_COMPUTED_FACES (f);
546 int i; 592 int i;
547 593
548 /* Search for a face already on FRAME equivalent to FACE. */ 594 /* Search for a computed face already on F equivalent to FACE. */
549 for (i = 0; i < len; i++) 595 for (i = 0; i < len; i++)
550 { 596 {
551 struct face *frame_face = FRAME_FACES (frame)[i]; 597 if (! FRAME_COMPUTED_FACES (f)[i])
552 598 abort ();
553 if (frame_face && face_eql (new_face, frame_face)) 599 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
554 return i; 600 return i;
555 } 601 }
556 602
557 /* We didn't find one; add a new one. */ 603 /* We didn't find one; add a new one. */
558 i = next_face_id++; 604 return new_computed_face (f, new_face);
559
560 ensure_face_ready (frame, i);
561 bcopy (new_face, FRAME_FACES (frame)[i], sizeof (*new_face));
562 FRAME_FACES (frame)[i]->copy = 1;
563
564 return i;
565} 605}
566 606
567/* Make face id ID valid on frame F. */ 607/* Make parameter face id ID valid on frame F. */
568 608
569static void 609static void
570ensure_face_ready (f, id) 610ensure_face_ready (f, id)
571 struct frame *f; 611 struct frame *f;
572 int id; 612 int id;
573{ 613{
574 if (FRAME_N_FACES (f) <= id) 614 if (FRAME_N_PARAM_FACES (f) <= id)
575 { 615 {
576 int n = id + 10; 616 int n = id + 10;
577 int i; 617 int i;
578 if (!FRAME_N_FACES (f)) 618 if (!FRAME_N_PARAM_FACES (f))
579 FRAME_FACES (f) 619 FRAME_PARAM_FACES (f)
580 = (struct face **) xmalloc (sizeof (struct face *) * n); 620 = (struct face **) xmalloc (sizeof (struct face *) * n);
581 else 621 else
582 FRAME_FACES (f) 622 FRAME_PARAM_FACES (f)
583 = (struct face **) xrealloc (FRAME_FACES (f), 623 = (struct face **) xrealloc (FRAME_PARAM_FACES (f),
584 sizeof (struct face *) * n); 624 sizeof (struct face *) * n);
585 625
586 bzero (FRAME_FACES (f) + FRAME_N_FACES (f), 626 bzero (FRAME_PARAM_FACES (f) + FRAME_N_PARAM_FACES (f),
587 (n - FRAME_N_FACES (f)) * sizeof (struct face *)); 627 (n - FRAME_N_PARAM_FACES (f)) * sizeof (struct face *));
588 FRAME_N_FACES (f) = n; 628 FRAME_N_PARAM_FACES (f) = n;
589 } 629 }
590 630
591 if (FRAME_FACES (f) [id] == 0) 631 if (FRAME_PARAM_FACES (f) [id] == 0)
592 FRAME_FACES (f) [id] = allocate_face (); 632 FRAME_PARAM_FACES (f) [id] = allocate_face ();
593} 633}
594 634
595/* Computing faces appropriate for a given piece of text in a buffer. */ 635/* Computing faces appropriate for a given piece of text in a buffer. */
@@ -757,9 +797,9 @@ compute_char_face (f, w, pos, region_beg, region_end, endptr)
757 if (!NILP (prop)) 797 if (!NILP (prop))
758 { 798 {
759 facecode = face_name_id_number (f, prop); 799 facecode = face_name_id_number (f, prop);
760 if (facecode >= 0 && facecode < FRAME_N_FACES (f) 800 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
761 && FRAME_FACES (f) [facecode] != 0) 801 && FRAME_PARAM_FACES (f) [facecode] != 0)
762 merge_faces (FRAME_FACES (f) [facecode], &face); 802 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
763 } 803 }
764 804
765 /* Put the valid and relevant overlays into sortvec. */ 805 /* Put the valid and relevant overlays into sortvec. */
@@ -814,9 +854,9 @@ compute_char_face (f, w, pos, region_beg, region_end, endptr)
814 int oendpos; 854 int oendpos;
815 855
816 facecode = face_name_id_number (f, prop); 856 facecode = face_name_id_number (f, prop);
817 if (facecode >= 0 && facecode < FRAME_N_FACES (f) 857 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
818 && FRAME_FACES (f) [facecode] != 0) 858 && FRAME_PARAM_FACES (f) [facecode] != 0)
819 merge_faces (FRAME_FACES (f) [facecode], &face); 859 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
820 860
821 oend = OVERLAY_END (sortvec[i].overlay); 861 oend = OVERLAY_END (sortvec[i].overlay);
822 oendpos = OVERLAY_POSITION (oend); 862 oendpos = OVERLAY_POSITION (oend);
@@ -830,12 +870,12 @@ compute_char_face (f, w, pos, region_beg, region_end, endptr)
830 if (region_end < endpos) 870 if (region_end < endpos)
831 endpos = region_end; 871 endpos = region_end;
832 if (region_face >= 0 && region_face < next_face_id) 872 if (region_face >= 0 && region_face < next_face_id)
833 merge_faces (FRAME_FACES (f) [region_face], &face); 873 merge_faces (FRAME_PARAM_FACES (f) [region_face], &face);
834 } 874 }
835 875
836 *endptr = endpos; 876 *endptr = endpos;
837 877
838 return intern_frame_face (f, &face); 878 return intern_computed_face (f, &face);
839} 879}
840 880
841/* Return the face ID to use to display a special glyph which selects 881/* Return the face ID to use to display a special glyph which selects
@@ -850,11 +890,11 @@ compute_glyph_face (f, face_code)
850 890
851 compute_base_face (f, &face); 891 compute_base_face (f, &face);
852 892
853 if (face_code >= 0 && face_code < FRAME_N_FACES (f) 893 if (face_code >= 0 && face_code < FRAME_N_PARAM_FACES (f)
854 && FRAME_FACES (f) [face_code] != 0) 894 && FRAME_PARAM_FACES (f) [face_code] != 0)
855 merge_faces (FRAME_FACES (f) [face_code], &face); 895 merge_faces (FRAME_PARAM_FACES (f) [face_code], &face);
856 896
857 return intern_frame_face (f, &face); 897 return intern_computed_face (f, &face);
858} 898}
859 899
860 900
@@ -867,17 +907,23 @@ recompute_basic_faces (f)
867{ 907{
868 /* If the frame's faces haven't been initialized yet, don't worry about 908 /* If the frame's faces haven't been initialized yet, don't worry about
869 this stuff. */ 909 this stuff. */
870 if (FRAME_N_FACES (f) < 2) 910 if (FRAME_N_PARAM_FACES (f) < 2)
871 return; 911 return;
872 912
873 BLOCK_INPUT; 913 BLOCK_INPUT;
874 914
875 if (FRAME_DEFAULT_FACE (f)->gc) 915 if (FRAME_DEFAULT_FACE (f)->gc)
876 XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc); 916 XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc);
877 build_face (f, FRAME_DEFAULT_FACE (f));
878
879 if (FRAME_MODE_LINE_FACE (f)->gc) 917 if (FRAME_MODE_LINE_FACE (f)->gc)
880 XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc); 918 XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc);
919
920 compute_base_face (f, FRAME_DEFAULT_FACE (f));
921 compute_base_face (f, FRAME_MODE_LINE_FACE (f));
922
923 merge_faces (FRAME_DEFAULT_PARAM_FACE (f), FRAME_DEFAULT_FACE (f));
924 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f), FRAME_MODE_LINE_FACE (f));
925
926 build_face (f, FRAME_DEFAULT_FACE (f));
881 build_face (f, FRAME_MODE_LINE_FACE (f)); 927 build_face (f, FRAME_MODE_LINE_FACE (f));
882 928
883 UNBLOCK_INPUT; 929 UNBLOCK_INPUT;
@@ -952,7 +998,7 @@ DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal,
952 return; 998 return;
953 999
954 ensure_face_ready (f, id); 1000 ensure_face_ready (f, id);
955 face = FRAME_FACES (f) [XFASTINT (face_id)]; 1001 face = FRAME_PARAM_FACES (f) [XFASTINT (face_id)];
956 1002
957 if (EQ (attr_name, intern ("font"))) 1003 if (EQ (attr_name, intern ("font")))
958 { 1004 {
@@ -995,23 +1041,8 @@ DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal,
995 else 1041 else
996 error ("unknown face attribute"); 1042 error ("unknown face attribute");
997 1043
998 if (id == 0) 1044 if (id == 0 || id == 1)
999 { 1045 recompute_basic_faces (f);
1000 BLOCK_INPUT;
1001 if (FRAME_DEFAULT_FACE (f)->gc != 0)
1002 XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc);
1003 build_face (f, FRAME_DEFAULT_FACE (f));
1004 UNBLOCK_INPUT;
1005 }
1006
1007 if (id == 1)
1008 {
1009 BLOCK_INPUT;
1010 if (FRAME_MODE_LINE_FACE (f)->gc != 0)
1011 XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc);
1012 build_face (f, FRAME_MODE_LINE_FACE (f));
1013 UNBLOCK_INPUT;
1014 }
1015 1046
1016 /* If we're modifying either of the frame's display faces, that 1047 /* If we're modifying either of the frame's display faces, that
1017 means that we're changing the parameters of a fixed face code; 1048 means that we're changing the parameters of a fixed face code;