diff options
| author | Jim Blandy | 1993-05-25 14:02:58 +0000 |
|---|---|---|
| committer | Jim Blandy | 1993-05-25 14:02:58 +0000 |
| commit | 660ed6694bde223792ca217f96465662b9b33413 (patch) | |
| tree | 2735cddfacb39ca9ebd849f0c92ab9ca07496250 /src | |
| parent | e5c8436a174dbc531a2c42790f4522def7df546f (diff) | |
| download | emacs-660ed6694bde223792ca217f96465662b9b33413.tar.gz emacs-660ed6694bde223792ca217f96465662b9b33413.zip | |
* 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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfaces.c | 168 |
1 files changed, 104 insertions, 64 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index 9b301e35b79..0c72456b141 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -61,6 +61,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 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 |
| @@ -136,10 +138,6 @@ int next_face_id; | |||
| 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) |
| @@ -318,27 +316,37 @@ build_face (f, face) | |||
| 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. */ |
| @@ -371,7 +379,10 @@ unload_font (f, 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 |
| @@ -432,47 +443,17 @@ unload_color (f, pixel) | |||
| 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]; | ||
| 464 | |||
| 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 | } | 454 | } |
| 475 | 455 | ||
| 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) |
| @@ -481,34 +462,39 @@ free_frame_faces (f) | |||
| 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; |
| @@ -530,6 +516,7 @@ intern_frame_face (frame, new_face) | |||
| 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 | } |
| @@ -564,6 +551,20 @@ ensure_face_ready (f, id) | |||
| 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. */ |
| 566 | 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 | } | ||
| 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 |
| @@ -584,6 +585,23 @@ merge_faces (from, to) | |||
| 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; |
| @@ -680,8 +698,7 @@ compute_char_face (f, w, pos, region_beg, region_end, endptr) | |||
| 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 | { |
| @@ -777,8 +794,7 @@ compute_glyph_face (f, 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) |
| @@ -786,6 +802,34 @@ compute_glyph_face (f, face_code) | |||
| 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 | ||
| @@ -900,9 +944,7 @@ DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal, | |||
| 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; |
| @@ -911,9 +953,7 @@ DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal, | |||
| 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; |