aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1994-10-14 05:19:13 +0000
committerRichard M. Stallman1994-10-14 05:19:13 +0000
commit42120bc769f1cd7335ed5070a9c70b40da7335b3 (patch)
treee2406a43584f358c616f1fbb2666143622f49d68 /src
parent8e3d10a98706b7d70c1d55a5052c0a69536988db (diff)
downloademacs-42120bc769f1cd7335ed5070a9c70b40da7335b3.tar.gz
emacs-42120bc769f1cd7335ed5070a9c70b40da7335b3.zip
Eliminate the "display faces"; store GCs in the "computed faces".
(face_vector, nfaces, nfaces_allocated): Vars deleted. (free_frame_faces): Free GCs in the computed faces. Free the computed faces themselves. (clear_face_cache): Renamed from clear_face_vector and completely rewritten to free GCs in the computed faces. (get_cached_face): Function deleted. (build_face): Function deleted; code moved into intern_face. (intern_face): Don't treat default and modeline faces specially. (recompute_basic_faces): Call intern_face, not build_face. (intern_face, clear_face_vector, load_font, unload_font) (load_color, free_frame_faces, recompute_basic_faces): Use FRAME_X_DISPLAY.
Diffstat (limited to 'src')
-rw-r--r--src/xfaces.c237
1 files changed, 71 insertions, 166 deletions
diff --git a/src/xfaces.c b/src/xfaces.c
index a96085ee2ba..250732aaefe 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -106,12 +106,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
106 characters. Elements 0 and 1 of computed_faces always describe the 106 characters. Elements 0 and 1 of computed_faces always describe the
107 default and mode-line faces. 107 default and mode-line faces.
108 108
109 Elements 0 and 1 of computed_faces have GC's; all the other faces 109 Computed faces have graphics contexts some of the time.
110 in computed_faces do not. The global array face_vector contains 110 intern_face builds a GC for a specified computed face
111 faces with their GC's set. Given a computed_face, the function 111 if it doesn't have one already.
112 intern_face finds (or adds) an element of face_vector with 112 clear_face_cache clears out the GCs of all computed faces.
113 equivalent parameters, and returns a pointer to that face, whose GC 113 This is done from time to time so that we don't hold on to
114 can then be used for display. 114 lots of GCs that are no longer needed.
115 115
116 Constraints: 116 Constraints:
117 117
@@ -132,35 +132,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
132 to be valid on all frames. If they were the same array, then that 132 to be valid on all frames. If they were the same array, then that
133 array would grow very large on all frames, because any facial 133 array would grow very large on all frames, because any facial
134 combination displayed on any frame would need to be a valid entry 134 combination displayed on any frame would need to be a valid entry
135 on all frames. 135 on all frames. */
136
137 Since face_vector is just a cache --- there are no pointers into it
138 from the rest of the code, and everyone accesses it through
139 intern_face --- we could just free its GC's and throw the whole
140 thing away without breaking anything. This gives us a simple way
141 to garbage-collect old GC's nobody's using any more - we can just
142 purge face_vector, and then let subsequent calls to intern_face
143 refill it as needed. The function clear_face_vector performs this
144 purge.
145
146 We're often applying intern_face to faces in computed_faces -
147 for example, we do this while sending GLYPHs from a struct
148 frame_glyphs to X during redisplay. It would be nice to avoid
149 searching all of face_vector every time we intern a frame's face.
150 So, when intern_face finds a match for FACE in face_vector, it
151 stores the index of the match in FACE's cached_index member, and
152 checks there first next time. */
153
154 136
155/* Definitions and declarations. */ 137/* Definitions and declarations. */
156 138
157/* A table of display faces. */
158static struct face **face_vector;
159/* The length in use of the table. */
160static int nfaces;
161/* The allocated length of the table. */
162static int nfaces_allocated;
163
164/* The number of face-id's in use (same for all frames). */ 139/* The number of face-id's in use (same for all frames). */
165int next_face_id; 140int next_face_id;
166 141
@@ -173,7 +148,6 @@ int region_face;
173 148
174Lisp_Object Qface, Qmouse_face; 149Lisp_Object Qface, Qmouse_face;
175 150
176static void build_face ( /* FRAME_PTR, struct face * */ );
177int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ ); 151int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
178 152
179struct face *intern_face ( /* FRAME_PTR, struct face * */ ); 153struct face *intern_face ( /* FRAME_PTR, struct face * */ );
@@ -224,134 +198,22 @@ face_eql (face1, face2)
224 && face1->underline == face2->underline); 198 && face1->underline == face2->underline);
225} 199}
226 200
227/* Interning faces in the `face_vector' cache, and clearing that cache. */ 201/* Managing graphics contexts of faces. */
228 202
229/* Return the unique display face corresponding to the user-level face FACE. 203/* Given a computed face, construct its graphics context if necessary. */
230 If there isn't one, make one, and find a slot in the face_vector to
231 put it in. */
232static struct face *
233get_cached_face (f, face)
234 struct frame *f;
235 struct face *face;
236{
237 int i, empty = -1;
238 struct face *result;
239
240 /* Perhaps FACE->cached_index is valid; this could happen if FACE is
241 in a frame's face list. */
242 if (face->cached_index >= 0
243 && face->cached_index < nfaces
244 && face_eql (face_vector[face->cached_index], face))
245 return face_vector[face->cached_index];
246
247 /* Look for an existing display face that does the job.
248 Also find an empty slot if any. */
249 for (i = 0; i < nfaces; i++)
250 {
251 if (face_eql (face_vector[i], face))
252 {
253 face->cached_index = i;
254 return face_vector[i];
255 }
256 if (face_vector[i] == 0)
257 empty = i;
258 }
259
260 /* If no empty slots, make one. */
261 if (empty < 0 && nfaces == nfaces_allocated)
262 {
263 int newsize = nfaces + 20;
264 face_vector
265 = (struct face **) xrealloc (face_vector,
266 newsize * sizeof (struct face *));
267 nfaces_allocated = newsize;
268 }
269
270 if (empty < 0)
271 empty = nfaces++;
272
273 /* Put a new display face in the empty slot. */
274 result = copy_face (face);
275 face_vector[empty] = result;
276
277 /* Make a graphics context for it. */
278 build_face (f, result);
279
280 face->cached_index = empty;
281 return result;
282}
283
284/* Given a computed face, return an equivalent display face
285 (one which has a graphics context). */
286 204
287struct face * 205struct face *
288intern_face (f, face) 206intern_face (f, face)
289 struct frame *f; 207 struct frame *f;
290 struct face *face; 208 struct face *face;
291{ 209{
292 /* If it's equivalent to the default face, use that. */
293 if (face_eql (face, FRAME_DEFAULT_FACE (f)))
294 {
295 if (!FRAME_DEFAULT_FACE (f)->gc)
296 build_face (f, FRAME_DEFAULT_FACE (f));
297 return FRAME_DEFAULT_FACE (f);
298 }
299
300 /* If it's equivalent to the mode line face, use that. */
301 if (face_eql (face, FRAME_MODE_LINE_FACE (f)))
302 {
303 if (!FRAME_MODE_LINE_FACE (f)->gc)
304 build_face (f, FRAME_MODE_LINE_FACE (f));
305 return FRAME_MODE_LINE_FACE (f);
306 }
307
308 /* If it's not one of the frame's default faces, it shouldn't have a GC. */
309 if (face->gc)
310 abort ();
311
312 /* Get a specialized display face. */
313 return get_cached_face (f, face);
314}
315
316/* Clear out face_vector and start anew.
317 This should be done from time to time just to avoid
318 keeping too many graphics contexts in face_vector
319 that are no longer needed. */
320
321void
322clear_face_vector ()
323{
324 Lisp_Object rest;
325 Display *dpy = x_current_display;
326 int i;
327
328 BLOCK_INPUT;
329 /* Free the display faces in the face_vector. */
330 for (i = 0; i < nfaces; i++)
331 {
332 struct face *face = face_vector[i];
333 if (face->gc)
334 XFreeGC (dpy, face->gc);
335 xfree (face);
336 }
337 nfaces = 0;
338
339 UNBLOCK_INPUT;
340}
341
342/* Allocating and freeing X resources for display faces. */
343
344/* Make a graphics context for face FACE, which is on frame F,
345 if that can be done. */
346static void
347build_face (f, face)
348 struct frame *f;
349 struct face *face;
350{
351 GC gc; 210 GC gc;
352 XGCValues xgcv; 211 XGCValues xgcv;
353 unsigned long mask; 212 unsigned long mask;
354 213
214 if (face->gc)
215 return face;
216
355 BLOCK_INPUT; 217 BLOCK_INPUT;
356 218
357 if (face->foreground != FACE_DEFAULT) 219 if (face->foreground != FACE_DEFAULT)
@@ -372,19 +234,53 @@ build_face (f, face)
372 xgcv.graphics_exposures = 0; 234 xgcv.graphics_exposures = 0;
373 235
374 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; 236 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
375 gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f), 237 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
376 mask, &xgcv); 238 mask, &xgcv);
377 239
378#if 0 240#if 0
379 if (face->stipple && face->stipple != FACE_DEFAULT) 241 if (face->stipple && face->stipple != FACE_DEFAULT)
380 XSetStipple (x_current_display, gc, face->stipple); 242 XSetStipple (FRAME_X_DISPLAY (f), gc, face->stipple);
381#endif 243#endif
382 244
383 face->gc = gc; 245 face->gc = gc;
384 246
385 UNBLOCK_INPUT; 247 UNBLOCK_INPUT;
248
249 return face;
386} 250}
387 251
252/* Clear out all graphics contexts for all computed faces
253 except for the default and mode line faces.
254 This should be done from time to time just to avoid
255 keeping too many graphics contexts that are no longer needed. */
256
257void
258clear_face_cache ()
259{
260 Lisp_Object tail, frame;
261
262 BLOCK_INPUT;
263 FOR_EACH_FRAME (tail, frame)
264 {
265 FRAME_PTR f = XFRAME (frame);
266 if (FRAME_X_P (f))
267 {
268 int i;
269 Display *dpy = FRAME_X_DISPLAY (f);
270
271 for (i = 2; i < FRAME_N_COMPUTED_FACES (f); i++)
272 {
273 struct face *face = FRAME_COMPUTED_FACES (f) [i];
274 if (face->gc)
275 XFreeGC (dpy, face->gc);
276 face->gc = 0;
277 }
278 }
279 }
280
281 UNBLOCK_INPUT;
282}
283
388/* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */ 284/* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */
389 285
390static XFontStruct * 286static XFontStruct *
@@ -399,7 +295,7 @@ load_font (f, name)
399 295
400 CHECK_STRING (name, 0); 296 CHECK_STRING (name, 0);
401 BLOCK_INPUT; 297 BLOCK_INPUT;
402 font = XLoadQueryFont (x_current_display, (char *) XSTRING (name)->data); 298 font = XLoadQueryFont (FRAME_X_DISPLAY (f), (char *) XSTRING (name)->data);
403 UNBLOCK_INPUT; 299 UNBLOCK_INPUT;
404 300
405 if (! font) 301 if (! font)
@@ -417,7 +313,7 @@ unload_font (f, font)
417 return; 313 return;
418 314
419 BLOCK_INPUT; 315 BLOCK_INPUT;
420 XFreeFont (x_current_display, font); 316 XFreeFont (FRAME_X_DISPLAY (f), font);
421 UNBLOCK_INPUT; 317 UNBLOCK_INPUT;
422} 318}
423 319
@@ -426,7 +322,7 @@ load_color (f, name)
426 struct frame *f; 322 struct frame *f;
427 Lisp_Object name; 323 Lisp_Object name;
428{ 324{
429 Display *dpy = x_current_display; 325 Display *dpy = FRAME_X_DISPLAY (f);
430 Colormap cmap; 326 Colormap cmap;
431 XColor color; 327 XColor color;
432 int result; 328 int result;
@@ -434,7 +330,7 @@ load_color (f, name)
434 if (NILP (name)) 330 if (NILP (name))
435 return FACE_DEFAULT; 331 return FACE_DEFAULT;
436 332
437 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display)); 333 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (dpy));
438 334
439 CHECK_STRING (name, 0); 335 CHECK_STRING (name, 0);
440 BLOCK_INPUT; 336 BLOCK_INPUT;
@@ -465,12 +361,12 @@ unload_color (f, pixel)
465 we'll get the same pixel. */ 361 we'll get the same pixel. */
466#if 0 362#if 0
467 Colormap cmap; 363 Colormap cmap;
468 Display *dpy = x_current_display; 364 Display *dpy = FRAME_X_DISPLAY (f);
469 if (pixel == FACE_DEFAULT 365 if (pixel == FACE_DEFAULT
470 || pixel == BLACK_PIX_DEFAULT 366 || pixel == BLACK_PIX_DEFAULT
471 || pixel == WHITE_PIX_DEFAULT) 367 || pixel == WHITE_PIX_DEFAULT)
472 return; 368 return;
473 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display)); 369 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (dpy));
474 BLOCK_INPUT; 370 BLOCK_INPUT;
475 XFreeColors (dpy, cmap, &pixel, 1, 0); 371 XFreeColors (dpy, cmap, &pixel, 1, 0);
476 UNBLOCK_INPUT; 372 UNBLOCK_INPUT;
@@ -529,7 +425,7 @@ void
529free_frame_faces (f) 425free_frame_faces (f)
530 struct frame *f; 426 struct frame *f;
531{ 427{
532 Display *dpy = x_current_display; 428 Display *dpy = FRAME_X_DISPLAY (f);
533 int i; 429 int i;
534 430
535 BLOCK_INPUT; 431 BLOCK_INPUT;
@@ -539,8 +435,6 @@ free_frame_faces (f)
539 struct face *face = FRAME_PARAM_FACES (f) [i]; 435 struct face *face = FRAME_PARAM_FACES (f) [i];
540 if (face) 436 if (face)
541 { 437 {
542 if (face->gc)
543 XFreeGC (dpy, face->gc);
544 unload_font (f, face->font); 438 unload_font (f, face->font);
545 unload_color (f, face->foreground); 439 unload_color (f, face->foreground);
546 unload_color (f, face->background); 440 unload_color (f, face->background);
@@ -555,7 +449,18 @@ free_frame_faces (f)
555 FRAME_N_PARAM_FACES (f) = 0; 449 FRAME_N_PARAM_FACES (f) = 0;
556 450
557 /* All faces in FRAME_COMPUTED_FACES use resources copied from 451 /* All faces in FRAME_COMPUTED_FACES use resources copied from
558 FRAME_PARAM_FACES; we can free them without fuss. */ 452 FRAME_PARAM_FACES; we can free them without fuss.
453 But we do free the GCs and the face objects themselves. */
454 for (i = 0; i < FRAME_N_COMPUTED_FACES (f); i++)
455 {
456 struct face *face = FRAME_COMPUTED_FACES (f) [i];
457 if (face)
458 {
459 if (face->gc)
460 XFreeGC (dpy, face->gc);
461 xfree (face);
462 }
463 }
559 xfree (FRAME_COMPUTED_FACES (f)); 464 xfree (FRAME_COMPUTED_FACES (f));
560 FRAME_COMPUTED_FACES (f) = 0; 465 FRAME_COMPUTED_FACES (f) = 0;
561 FRAME_N_COMPUTED_FACES (f) = 0; 466 FRAME_N_COMPUTED_FACES (f) = 0;
@@ -971,9 +876,9 @@ recompute_basic_faces (f)
971 BLOCK_INPUT; 876 BLOCK_INPUT;
972 877
973 if (FRAME_DEFAULT_FACE (f)->gc) 878 if (FRAME_DEFAULT_FACE (f)->gc)
974 XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc); 879 XFreeGC (FRAME_X_DISPLAY (f), FRAME_DEFAULT_FACE (f)->gc);
975 if (FRAME_MODE_LINE_FACE (f)->gc) 880 if (FRAME_MODE_LINE_FACE (f)->gc)
976 XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc); 881 XFreeGC (FRAME_X_DISPLAY (f), FRAME_MODE_LINE_FACE (f)->gc);
977 882
978 compute_base_face (f, FRAME_DEFAULT_FACE (f)); 883 compute_base_face (f, FRAME_DEFAULT_FACE (f));
979 compute_base_face (f, FRAME_MODE_LINE_FACE (f)); 884 compute_base_face (f, FRAME_MODE_LINE_FACE (f));
@@ -981,8 +886,8 @@ recompute_basic_faces (f)
981 merge_faces (FRAME_DEFAULT_PARAM_FACE (f), FRAME_DEFAULT_FACE (f)); 886 merge_faces (FRAME_DEFAULT_PARAM_FACE (f), FRAME_DEFAULT_FACE (f));
982 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f), FRAME_MODE_LINE_FACE (f)); 887 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f), FRAME_MODE_LINE_FACE (f));
983 888
984 build_face (f, FRAME_DEFAULT_FACE (f)); 889 intern_face (f, FRAME_DEFAULT_FACE (f));
985 build_face (f, FRAME_MODE_LINE_FACE (f)); 890 intern_face (f, FRAME_MODE_LINE_FACE (f));
986 891
987 UNBLOCK_INPUT; 892 UNBLOCK_INPUT;
988} 893}