comparison src/xfaces.c @ 3074:96b4623fdeb3

* xterm.h: New section for declarations for xfaces.c. (init_frame_faces, free_frame_faces, intern_face, face_name_id_number, same_size_fonts, recompute_basic_faces, compute_char_face, compute_glyph_face): Declare these here. * xfaces.c (same_size_fonts): We can now remove this extern declaration. * xfns.c (face_name_id_number): Likewise. * xterm.c (intern_face): Likewise. * xfaces.c (build_face, unload_font, free_frame_faces): Don't forget to block input while making X calls. Treat faces as structures specifying modifications to the frame's parameters, rather than things which need to specify a complete set of parameters by themselves. * xfaces.c (init_frame_faces): Don't set up the two frame display faces by querying the GC - just leave all their fields blank, and call recompute_basic_faces, letting build_face do the work of consulting the frame when necessary. (recompute_basic_faces): New function. (compute_base_faces): New function for obtaining the "identity" for compute_char_face and compute_glyph_face. (compute_char_face, compute_glyph_face): Call it, instead of copying FRAME_DEFAULT_FACE. * xfns.c (x_make_gc): No need to call init_frame_faces here. * xfaces.c (intern_frame_face): This can be static. * dispextern.h (struct face): New field - `copy', to help us with resource allocation. * xfaces.c (free_frame_faces): Do free the first two faces; don't free anything from a face that's a copy. (intern_frame_face): Mark every face we intern as a copy; its resources are actually a combination of the real faces. (Fset_face_attribute_internal): No need to check if we're trying to free one of the frame's GC's; they never enter into the picture. * xfns.c (Fx_list_fonts): New function. (face_name_id_number): Add extern declaration for this. * xfaces.c (face_name_id_number): Make this externally visible, and make the FRAME argument a FRAME_PTR, not a Lisp_Object. (compute_char_face): Call face_name_id_number properly.
author Jim Blandy <jimb@redhat.com>
date Tue, 25 May 1993 14:02:58 +0000
parents fff06093b756
children 564f748751ea
comparison
equal deleted inserted replaced
3073:905f9fda79b8 3074:96b4623fdeb3
59 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors 59 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
60 to use with the face, 60 to use with the face,
61 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't 61 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
62 use right now, and 62 use right now, and
63 UNDERLINE-P is non-nil if the face should be underlined. 63 UNDERLINE-P is non-nil if the face should be underlined.
64 If any of these elements are nil, that allows the frame's parameters to
65 show through.
64 (lisp/faces.el maintains these association lists.) 66 (lisp/faces.el maintains these association lists.)
65 67
66 The frames' private alists hold the frame-local definitions for the 68 The frames' private alists hold the frame-local definitions for the
67 faces. The lisp variable global-face-data contains the global 69 faces. The lisp variable global-face-data contains the global
68 defaults for faces. (See lisp/faces.el for this too.) 70 defaults for faces. (See lisp/faces.el for this too.)
134 int next_face_id; 136 int next_face_id;
135 137
136 /* The number of the face to use to indicate the region. */ 138 /* The number of the face to use to indicate the region. */
137 int region_face; 139 int region_face;
138 140
139 /* Return non-zero if FONT1 and FONT2 have the same size bounding box.
140 We assume that they're both character-cell fonts. */
141 extern int same_size_fonts ();
142
143 /* This is what appears in a slot in a face to signify that the face 141 /* This is what appears in a slot in a face to signify that the face
144 does not specify that display aspect. */ 142 does not specify that display aspect. */
145 #define FACE_DEFAULT (~0) 143 #define FACE_DEFAULT (~0)
146 144
147 Lisp_Object Qface, Qwindow, Qpriority; 145 Lisp_Object Qface, Qwindow, Qpriority;
316 { 314 {
317 GC gc; 315 GC gc;
318 XGCValues xgcv; 316 XGCValues xgcv;
319 unsigned long mask; 317 unsigned long mask;
320 318
319 BLOCK_INPUT;
320
321 if (face->foreground != FACE_DEFAULT) 321 if (face->foreground != FACE_DEFAULT)
322 xgcv.foreground = face->foreground; 322 xgcv.foreground = face->foreground;
323 else 323 else
324 xgcv. foreground = f->display.x->foreground_pixel; 324 xgcv.foreground = f->display.x->foreground_pixel;
325
325 if (face->background != FACE_DEFAULT) 326 if (face->background != FACE_DEFAULT)
326 xgcv.background = face->background; 327 xgcv.background = face->background;
327 else 328 else
328 xgcv. background = f->display.x->background_pixel; 329 xgcv.background = f->display.x->background_pixel;
330
329 if (face->font && (int) face->font != FACE_DEFAULT) 331 if (face->font && (int) face->font != FACE_DEFAULT)
330 xgcv.font = face->font->fid; 332 xgcv.font = face->font->fid;
331 else 333 else
332 xgcv.font = f->display.x->font->fid; 334 xgcv.font = f->display.x->font->fid;
335
333 xgcv.graphics_exposures = 0; 336 xgcv.graphics_exposures = 0;
337
334 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; 338 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
335 gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f), 339 gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
336 mask, &xgcv); 340 mask, &xgcv);
341
337 #if 0 342 #if 0
338 if (face->stipple && face->stipple != FACE_DEFAULT) 343 if (face->stipple && face->stipple != FACE_DEFAULT)
339 XSetStipple (x_current_display, gc, face->stipple); 344 XSetStipple (x_current_display, gc, face->stipple);
340 #endif 345 #endif
346
341 face->gc = gc; 347 face->gc = gc;
348
349 UNBLOCK_INPUT;
342 } 350 }
343 351
344 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */ 352 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */
345 353
346 static XFontStruct * 354 static XFontStruct *
369 struct frame *f; 377 struct frame *f;
370 XFontStruct *font; 378 XFontStruct *font;
371 { 379 {
372 if (!font || font == ((XFontStruct *) FACE_DEFAULT)) 380 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
373 return; 381 return;
382
383 BLOCK_INPUT;
374 XFreeFont (x_current_display, font); 384 XFreeFont (x_current_display, font);
385 UNBLOCK_INPUT;
375 } 386 }
376 387
377 static unsigned long 388 static unsigned long
378 load_color (f, name) 389 load_color (f, name)
379 struct frame *f; 390 struct frame *f;
430 #endif 441 #endif
431 } 442 }
432 443
433 /* Initializing face arrays for frames. */ 444 /* Initializing face arrays for frames. */
434 445
435 /* Set up faces 0 and 1 based on the normal text and modeline GC's.
436 This gets called whenever the parameters stored in the frame itself
437 (i.e. font, background color, etcetera) change.
438
439 Note that the first two faces just contain references to the
440 frame's own resources. We shouldn't free them. */
441 void 446 void
442 init_frame_faces (f) 447 init_frame_faces (f)
443 struct frame *f; 448 FRAME_PTR f;
444 { 449 {
445 ensure_face_ready (f, 0); 450 ensure_face_ready (f, 0);
446 {
447 XGCValues gcv;
448 struct face *face = FRAME_FACES (f) [0];
449
450 XGetGCValues (x_current_display, f->display.x->normal_gc,
451 GCForeground | GCBackground | GCFont, &gcv);
452 face->gc = f->display.x->normal_gc;
453 face->foreground = gcv.foreground;
454 face->background = gcv.background;
455 face->font = f->display.x->font;
456 face->stipple = 0;
457 face->underline = 0;
458 }
459
460 ensure_face_ready (f, 1); 451 ensure_face_ready (f, 1);
461 { 452
462 XGCValues gcv; 453 recompute_basic_faces (f);
463 struct face *face = FRAME_FACES (f) [1]; 454 }
464 455
465 XGetGCValues (x_current_display, f->display.x->reverse_gc,
466 GCForeground | GCBackground | GCFont, &gcv);
467 face->gc = f->display.x->reverse_gc;
468 face->foreground = gcv.foreground;
469 face->background = gcv.background;
470 face->font = f->display.x->font;
471 face->stipple = 0;
472 face->underline = 0;
473 }
474 }
475 456
476 /* Called from Fdelete_frame. */ 457 /* Called from Fdelete_frame. */
477 void 458 void
478 free_frame_faces (f) 459 free_frame_faces (f)
479 struct frame *f; 460 struct frame *f;
480 { 461 {
481 Display *dpy = x_current_display; 462 Display *dpy = x_current_display;
482 int i; 463 int i;
483 464
484 /* The first two faces on the frame are just made of resources which 465 BLOCK_INPUT;
485 we borrowed from the frame's GC's, so don't free them. Let 466
486 them get freed by the x_destroy_window code. */ 467 for (i = 0; i < FRAME_N_FACES (f); i++)
487 for (i = 2; i < FRAME_N_FACES (f); i++)
488 { 468 {
489 struct face *face = FRAME_FACES (f) [i]; 469 struct face *face = FRAME_FACES (f) [i];
490 if (! face) 470 if (face)
491 continue; 471 {
492 if (face->gc) 472 if (face->gc)
493 XFreeGC (dpy, face->gc); 473 XFreeGC (dpy, face->gc);
494 unload_font (f, face->font); 474 if (! face->copy)
495 unload_color (f, face->foreground); 475 {
496 unload_color (f, face->background); 476 unload_font (f, face->font);
477 unload_color (f, face->foreground);
478 unload_color (f, face->background);
497 #if 0 479 #if 0
498 unload_pixmap (f, face->stipple); 480 unload_pixmap (f, face->stipple);
499 #endif 481 #endif
500 xfree (face); 482 }
483 xfree (face);
484 }
501 } 485 }
502 xfree (FRAME_FACES (f)); 486 xfree (FRAME_FACES (f));
503 FRAME_FACES (f) = 0; 487 FRAME_FACES (f) = 0;
504 FRAME_N_FACES (f) = 0; 488 FRAME_N_FACES (f) = 0;
489
490 UNBLOCK_INPUT;
505 } 491 }
506 492
507 /* Interning faces in a frame's face array. */ 493 /* Interning faces in a frame's face array. */
508 494
509 /* Find a match for NEW_FACE in a FRAME's face array, and add it if we don't 495 /* Find a match for NEW_FACE in a FRAME's face array, and add it if we don't
510 find one. */ 496 find one. */
511 int 497 static int
512 intern_frame_face (frame, new_face) 498 intern_frame_face (frame, new_face)
513 struct frame *frame; 499 struct frame *frame;
514 struct face *new_face; 500 struct face *new_face;
515 { 501 {
516 int len = FRAME_N_FACES (frame); 502 int len = FRAME_N_FACES (frame);
528 /* We didn't find one; add a new one. */ 514 /* We didn't find one; add a new one. */
529 i = next_face_id++; 515 i = next_face_id++;
530 516
531 ensure_face_ready (frame, i); 517 ensure_face_ready (frame, i);
532 bcopy (new_face, FRAME_FACES (frame)[i], sizeof (*new_face)); 518 bcopy (new_face, FRAME_FACES (frame)[i], sizeof (*new_face));
519 FRAME_FACES (frame)[i]->copy = 1;
533 520
534 return i; 521 return i;
535 } 522 }
536 523
537 /* Make face id ID valid on frame F. */ 524 /* Make face id ID valid on frame F. */
561 if (FRAME_FACES (f) [id] == 0) 548 if (FRAME_FACES (f) [id] == 0)
562 FRAME_FACES (f) [id] = allocate_face (); 549 FRAME_FACES (f) [id] = allocate_face ();
563 } 550 }
564 551
565 /* Computing faces appropriate for a given piece of text in a buffer. */ 552 /* Computing faces appropriate for a given piece of text in a buffer. */
553
554 /* Return non-zero if FONT1 and FONT2 have the same size bounding box.
555 We assume that they're both character-cell fonts. */
556 int
557 same_size_fonts (font1, font2)
558 XFontStruct *font1, *font2;
559 {
560 XCharStruct *bounds1 = &font1->min_bounds;
561 XCharStruct *bounds2 = &font2->min_bounds;
562
563 return (bounds1->width == bounds2->width
564 && bounds1->ascent == bounds2->ascent
565 && bounds1->descent == bounds2->descent);
566 }
566 567
567 /* Modify face TO by copying from FROM all properties which have 568 /* Modify face TO by copying from FROM all properties which have
568 nondefault settings. */ 569 nondefault settings. */
569 static void 570 static void
570 merge_faces (from, to) 571 merge_faces (from, to)
582 to->stipple = from->stipple; 583 to->stipple = from->stipple;
583 if (from->underline) 584 if (from->underline)
584 to->underline = from->underline; 585 to->underline = from->underline;
585 } 586 }
586 587
588 /* Set up the basic set of facial parameters, based on the frame's
589 data; all faces are deltas applied to this. */
590 static void
591 compute_base_face (f, face)
592 FRAME_PTR f;
593 struct face *face;
594 {
595 struct x_display *d = f->display.x;
596
597 face->gc = 0;
598 face->foreground = d->foreground_pixel;
599 face->background = d->background_pixel;
600 face->font = d->font;
601 face->underline = 0;
602 }
603
604
587 struct sortvec 605 struct sortvec
588 { 606 {
589 Lisp_Object overlay; 607 Lisp_Object overlay;
590 int beg, end; 608 int beg, end;
591 int priority; 609 int priority;
678 /* Optimize the default case. */ 696 /* Optimize the default case. */
679 if (noverlays == 0 && NILP (prop) 697 if (noverlays == 0 && NILP (prop)
680 && !(pos >= region_beg && pos < region_end)) 698 && !(pos >= region_beg && pos < region_end))
681 return 0; 699 return 0;
682 700
683 bcopy (FRAME_DEFAULT_FACE (f), &face, sizeof (struct face)); 701 compute_base_face (f, &face);
684 face.gc = 0;
685 702
686 if (!NILP (prop)) 703 if (!NILP (prop))
687 { 704 {
688 facecode = face_name_id_number (f, prop); 705 facecode = face_name_id_number (f, prop);
689 if (facecode >= 0 && facecode < FRAME_N_FACES (f) 706 if (facecode >= 0 && facecode < FRAME_N_FACES (f)
775 struct frame *f; 792 struct frame *f;
776 int face_code; 793 int face_code;
777 { 794 {
778 struct face face; 795 struct face face;
779 796
780 bcopy (FRAME_DEFAULT_FACE (f), &face, sizeof (face)); 797 compute_base_face (f, &face);
781 face.gc = 0;
782 798
783 if (face_code >= 0 && face_code < FRAME_N_FACES (f) 799 if (face_code >= 0 && face_code < FRAME_N_FACES (f)
784 && FRAME_FACES (f) [face_code] != 0) 800 && FRAME_FACES (f) [face_code] != 0)
785 merge_faces (FRAME_FACES (f) [face_code], &face); 801 merge_faces (FRAME_FACES (f) [face_code], &face);
786 802
787 return intern_frame_face (f, &face); 803 return intern_frame_face (f, &face);
788 } 804 }
805
806
807 /* Recompute the GC's for the default and modeline faces.
808 We call this after changing frame parameters on which those GC's
809 depend. */
810 void
811 recompute_basic_faces (f)
812 FRAME_PTR f;
813 {
814 /* If the frame's faces haven't been initialized yet, don't worry about
815 this stuff. */
816 if (FRAME_N_FACES (f) < 2)
817 return;
818
819 BLOCK_INPUT;
820
821 if (FRAME_DEFAULT_FACE (f)->gc)
822 XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc);
823 build_face (f, FRAME_DEFAULT_FACE (f));
824
825 if (FRAME_MODE_LINE_FACE (f)->gc)
826 XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc);
827 build_face (f, FRAME_MODE_LINE_FACE (f));
828
829 UNBLOCK_INPUT;
830 }
831
832
789 833
790 /* Lisp interface. */ 834 /* Lisp interface. */
791 835
792 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0, 836 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
793 "") 837 "")
898 error ("unknown face attribute"); 942 error ("unknown face attribute");
899 943
900 if (id == 0) 944 if (id == 0)
901 { 945 {
902 BLOCK_INPUT; 946 BLOCK_INPUT;
903 if (FRAME_DEFAULT_FACE (f)->gc != 0 947 if (FRAME_DEFAULT_FACE (f)->gc != 0)
904 && FRAME_DEFAULT_FACE (f)->gc != f->display.x->normal_gc
905 && FRAME_DEFAULT_FACE (f)->gc != f->display.x->reverse_gc)
906 XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc); 948 XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc);
907 build_face (f, FRAME_DEFAULT_FACE (f)); 949 build_face (f, FRAME_DEFAULT_FACE (f));
908 UNBLOCK_INPUT; 950 UNBLOCK_INPUT;
909 } 951 }
910 952
911 if (id == 1) 953 if (id == 1)
912 { 954 {
913 BLOCK_INPUT; 955 BLOCK_INPUT;
914 if (FRAME_MODE_LINE_FACE (f)->gc != 0 956 if (FRAME_MODE_LINE_FACE (f)->gc != 0)
915 && FRAME_MODE_LINE_FACE (f)->gc != f->display.x->normal_gc
916 && FRAME_MODE_LINE_FACE (f)->gc != f->display.x->reverse_gc)
917 XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc); 957 XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc);
918 build_face (f, FRAME_MODE_LINE_FACE (f)); 958 build_face (f, FRAME_MODE_LINE_FACE (f));
919 UNBLOCK_INPUT; 959 UNBLOCK_INPUT;
920 } 960 }
921 961