diff options
| author | Gerd Moellmann | 1999-10-06 23:09:44 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 1999-10-06 23:09:44 +0000 |
| commit | c7ae32842a6f9921d9aefd99480b6076e7d87484 (patch) | |
| tree | 1e5b2c7be14c868f3e4291ce96de2cf4a2e065fd /src | |
| parent | 52377a47b0f120f77008cfc73384617870cf4896 (diff) | |
| download | emacs-c7ae32842a6f9921d9aefd99480b6076e7d87484.tar.gz emacs-c7ae32842a6f9921d9aefd99480b6076e7d87484.zip | |
(toplevel) [USE_MOTIF]: Include some Motif headers.
(struct x_resources) [USE_X_TOOLKIT]: New.
(xm_apply_resources, xm_set_menu_resources_from_menu_face)
[USE_MOTIF]: New.
(xl_apply_resources, xl_set_menu_resources_from_menu_face)
[USE_LUCID]: New.
(x_set_menu_resources_from_menu_face) [USE_X_TOOLKIT]: New.
(Qmenu): New.
(syms_of_xfaces): Initialize Qmenu.
(realize_basic_faces): Realize face `menu'.
(resolve_face_name): New.
(lface_from_face_name): Use it.
(Finternal_set_lisp_face_attribute): Ditto.
(Fpixmap_spec_p): Rewritten. Extend doc string.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfaces.c | 317 |
1 files changed, 286 insertions, 31 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index 0367a925c88..48429fcb8e9 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -187,6 +187,10 @@ Boston, MA 02111-1307, USA. */ | |||
| 187 | #ifdef HAVE_X_WINDOWS | 187 | #ifdef HAVE_X_WINDOWS |
| 188 | #include "xterm.h" | 188 | #include "xterm.h" |
| 189 | #include "fontset.h" | 189 | #include "fontset.h" |
| 190 | #ifdef USE_MOTIF | ||
| 191 | #include <Xm/Xm.h> | ||
| 192 | #include <Xm/XmStrDefs.h> | ||
| 193 | #endif /* USE_MOTIF */ | ||
| 190 | #endif | 194 | #endif |
| 191 | 195 | ||
| 192 | #ifdef MSDOS | 196 | #ifdef MSDOS |
| @@ -286,7 +290,7 @@ Lisp_Object Qframe_update_face_colors; | |||
| 286 | /* Names of basic faces. */ | 290 | /* Names of basic faces. */ |
| 287 | 291 | ||
| 288 | Lisp_Object Qdefault, Qmode_line, Qtool_bar, Qregion, Qfringe; | 292 | Lisp_Object Qdefault, Qmode_line, Qtool_bar, Qregion, Qfringe; |
| 289 | Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse;; | 293 | Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu; |
| 290 | 294 | ||
| 291 | /* The symbol `face-alias'. A symbols having that property is an | 295 | /* The symbol `face-alias'. A symbols having that property is an |
| 292 | alias for another face. Value of the property is the name of | 296 | alias for another face. Value of the property is the name of |
| @@ -397,6 +401,7 @@ static int ngcs; | |||
| 397 | struct font_name; | 401 | struct font_name; |
| 398 | struct table_entry; | 402 | struct table_entry; |
| 399 | 403 | ||
| 404 | static Lisp_Object resolve_face_name P_ ((Lisp_Object)); | ||
| 400 | static int may_use_scalable_font_p P_ ((struct font_name *, char *)); | 405 | static int may_use_scalable_font_p P_ ((struct font_name *, char *)); |
| 401 | static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object)); | 406 | static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object)); |
| 402 | static int better_font_p P_ ((int *, struct font_name *, struct font_name *, | 407 | static int better_font_p P_ ((int *, struct font_name *, struct font_name *, |
| @@ -834,31 +839,52 @@ clear_font_table (f) | |||
| 834 | #ifdef HAVE_X_WINDOWS | 839 | #ifdef HAVE_X_WINDOWS |
| 835 | 840 | ||
| 836 | DEFUN ("pixmap-spec-p", Fpixmap_spec_p, Spixmap_spec_p, 1, 1, 0, | 841 | DEFUN ("pixmap-spec-p", Fpixmap_spec_p, Spixmap_spec_p, 1, 1, 0, |
| 837 | "Non-nil if OBJECT is a valid pixmap specification.\n\ | 842 | "Value is non-nil if OBJECT is a valid pixmap specification.\n\ |
| 838 | A pixmap specification is either a string, or a list (WIDTH HEIGHT DATA)\n\ | 843 | A pixmap specification is either a string, a file name, or a list\n\ |
| 839 | where WIDTH is the pixel width of the pixmap, HEIGHT is its height,\n\ | 844 | (WIDTH HEIGHT DATA) where WIDTH is the pixel width of the pixmap,\n\ |
| 840 | and DATA contains the bits of the pixmap.") | 845 | HEIGHT is its height, and DATA is a string containing the bits of\n\ |
| 846 | the pixmap. Bits are stored row by row, each row occupies\n\ | ||
| 847 | (WIDTH + 7)/8 bytes.") | ||
| 841 | (object) | 848 | (object) |
| 842 | Lisp_Object object; | 849 | Lisp_Object object; |
| 843 | { | 850 | { |
| 844 | Lisp_Object height, width; | 851 | int pixmap_p = 0; |
| 852 | |||
| 853 | if (STRINGP (object)) | ||
| 854 | /* If OBJECT is a string, it's a file name. */ | ||
| 855 | pixmap_p = 1; | ||
| 856 | else if (CONSP (object)) | ||
| 857 | { | ||
| 858 | /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and | ||
| 859 | HEIGHT must be integers > 0, and DATA must be string large | ||
| 860 | enough to hold a bitmap of the specified size. */ | ||
| 861 | Lisp_Object width, height, data; | ||
| 862 | |||
| 863 | height = width = data = Qnil; | ||
| 864 | |||
| 865 | if (CONSP (object)) | ||
| 866 | { | ||
| 867 | width = XCAR (object); | ||
| 868 | object = XCDR (object); | ||
| 869 | if (CONSP (object)) | ||
| 870 | { | ||
| 871 | height = XCAR (object); | ||
| 872 | object = XCDR (object); | ||
| 873 | if (CONSP (object)) | ||
| 874 | data = XCAR (object); | ||
| 875 | } | ||
| 876 | } | ||
| 845 | 877 | ||
| 846 | return ((STRINGP (object) | 878 | if (NATNUMP (width) && NATNUMP (height) && STRINGP (data)) |
| 847 | || (CONSP (object) | 879 | { |
| 848 | && CONSP (XCONS (object)->cdr) | 880 | int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1) |
| 849 | && CONSP (XCONS (XCONS (object)->cdr)->cdr) | 881 | / BITS_PER_CHAR); |
| 850 | && NILP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->cdr) | 882 | if (STRING_BYTES (XSTRING (data)) >= bytes_per_row * height) |
| 851 | && (width = XCONS (object)->car, INTEGERP (width)) | 883 | pixmap_p = 1; |
| 852 | && (height = XCONS (XCONS (object)->cdr)->car, | 884 | } |
| 853 | INTEGERP (height)) | 885 | } |
| 854 | && STRINGP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car) | 886 | |
| 855 | && XINT (width) > 0 | 887 | return pixmap_p ? Qt : Qnil; |
| 856 | && XINT (height) > 0 | ||
| 857 | /* The string must have enough bits for width * height. */ | ||
| 858 | && ((XSTRING (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car)->size | ||
| 859 | * (BITS_PER_INT / sizeof (int))) | ||
| 860 | >= XFASTINT (width) * XFASTINT (height)))) | ||
| 861 | ? Qt : Qnil); | ||
| 862 | } | 888 | } |
| 863 | 889 | ||
| 864 | 890 | ||
| @@ -2568,6 +2594,32 @@ check_lface (lface) | |||
| 2568 | #endif /* GLYPH_DEBUG == 0 */ | 2594 | #endif /* GLYPH_DEBUG == 0 */ |
| 2569 | 2595 | ||
| 2570 | 2596 | ||
| 2597 | /* Resolve face name FACE_NAME. If FACE_NAME Is a string, intern it | ||
| 2598 | to make it a symvol. If FACE_NAME is an alias for another face, | ||
| 2599 | return that face's name. */ | ||
| 2600 | |||
| 2601 | static Lisp_Object | ||
| 2602 | resolve_face_name (face_name) | ||
| 2603 | Lisp_Object face_name; | ||
| 2604 | { | ||
| 2605 | Lisp_Object aliased; | ||
| 2606 | |||
| 2607 | if (STRINGP (face_name)) | ||
| 2608 | face_name = intern (XSTRING (face_name)->data); | ||
| 2609 | |||
| 2610 | for (;;) | ||
| 2611 | { | ||
| 2612 | aliased = Fget (face_name, Qface_alias); | ||
| 2613 | if (NILP (aliased)) | ||
| 2614 | break; | ||
| 2615 | else | ||
| 2616 | face_name = aliased; | ||
| 2617 | } | ||
| 2618 | |||
| 2619 | return face_name; | ||
| 2620 | } | ||
| 2621 | |||
| 2622 | |||
| 2571 | /* Return the face definition of FACE_NAME on frame F. F null means | 2623 | /* Return the face definition of FACE_NAME on frame F. F null means |
| 2572 | return the global definition. FACE_NAME may be a string or a | 2624 | return the global definition. FACE_NAME may be a string or a |
| 2573 | symbol (apparently Emacs 20.2 allows strings as face names in face | 2625 | symbol (apparently Emacs 20.2 allows strings as face names in face |
| @@ -2583,16 +2635,9 @@ lface_from_face_name (f, face_name, signal_p) | |||
| 2583 | Lisp_Object face_name; | 2635 | Lisp_Object face_name; |
| 2584 | int signal_p; | 2636 | int signal_p; |
| 2585 | { | 2637 | { |
| 2586 | Lisp_Object lface, alias; | 2638 | Lisp_Object lface; |
| 2587 | |||
| 2588 | if (STRINGP (face_name)) | ||
| 2589 | face_name = intern (XSTRING (face_name)->data); | ||
| 2590 | 2639 | ||
| 2591 | /* If FACE_NAME is an alias for another face, return the definition | 2640 | face_name = resolve_face_name (face_name); |
| 2592 | of the aliased face. */ | ||
| 2593 | alias = Fget (face_name, Qface_alias); | ||
| 2594 | if (!NILP (alias)) | ||
| 2595 | face_name = alias; | ||
| 2596 | 2641 | ||
| 2597 | if (f) | 2642 | if (f) |
| 2598 | lface = assq_no_quit (face_name, f->face_alist); | 2643 | lface = assq_no_quit (face_name, f->face_alist); |
| @@ -3118,6 +3163,8 @@ frame.") | |||
| 3118 | CHECK_SYMBOL (face, 0); | 3163 | CHECK_SYMBOL (face, 0); |
| 3119 | CHECK_SYMBOL (attr, 1); | 3164 | CHECK_SYMBOL (attr, 1); |
| 3120 | 3165 | ||
| 3166 | face = resolve_face_name (face); | ||
| 3167 | |||
| 3121 | /* Set lface to the Lisp attribute vector of FACE. */ | 3168 | /* Set lface to the Lisp attribute vector of FACE. */ |
| 3122 | if (EQ (frame, Qt)) | 3169 | if (EQ (frame, Qt)) |
| 3123 | lface = lface_from_face_name (NULL, face, 1); | 3170 | lface = lface_from_face_name (NULL, face, 1); |
| @@ -3666,6 +3713,211 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource", | |||
| 3666 | } | 3713 | } |
| 3667 | 3714 | ||
| 3668 | 3715 | ||
| 3716 | |||
| 3717 | /*********************************************************************** | ||
| 3718 | Menu face | ||
| 3719 | ***********************************************************************/ | ||
| 3720 | |||
| 3721 | #ifdef USE_X_TOOLKIT | ||
| 3722 | |||
| 3723 | /* Structure used to pass X resources to functions called via | ||
| 3724 | XtApplyToWidgets. */ | ||
| 3725 | |||
| 3726 | struct x_resources | ||
| 3727 | { | ||
| 3728 | Arg *av; | ||
| 3729 | int ac; | ||
| 3730 | }; | ||
| 3731 | |||
| 3732 | |||
| 3733 | #ifdef USE_MOTIF | ||
| 3734 | |||
| 3735 | static void xm_apply_resources P_ ((Widget, XtPointer)); | ||
| 3736 | static void xm_set_menu_resources_from_menu_face P_ ((struct frame *, Widget)); | ||
| 3737 | |||
| 3738 | |||
| 3739 | /* Set widget W's X resources from P which points to an x_resources | ||
| 3740 | structure. If W is a cascade button, apply resources to W's | ||
| 3741 | submenu. */ | ||
| 3742 | |||
| 3743 | static void | ||
| 3744 | xm_apply_resources (w, p) | ||
| 3745 | Widget w; | ||
| 3746 | XtPointer p; | ||
| 3747 | { | ||
| 3748 | Widget submenu = 0; | ||
| 3749 | struct x_resources *res = (struct x_resources *) p; | ||
| 3750 | |||
| 3751 | XtSetValues (w, res->av, res->ac); | ||
| 3752 | XtVaGetValues (w, XmNsubMenuId, &submenu, NULL); | ||
| 3753 | if (submenu) | ||
| 3754 | { | ||
| 3755 | XtSetValues (submenu, res->av, res->ac); | ||
| 3756 | XtApplyToWidgets (submenu, xm_apply_resources, p); | ||
| 3757 | } | ||
| 3758 | } | ||
| 3759 | |||
| 3760 | |||
| 3761 | /* Set X resources of menu-widget WIDGET on frame F from face `menu'. | ||
| 3762 | This is the LessTif/Motif version. As of LessTif 0.88 it has the | ||
| 3763 | following problems: | ||
| 3764 | |||
| 3765 | 1. Setting the XmNfontList resource leads to an infinite loop | ||
| 3766 | somewhere in LessTif. */ | ||
| 3767 | |||
| 3768 | static void | ||
| 3769 | xm_set_menu_resources_from_menu_face (f, widget) | ||
| 3770 | struct frame *f; | ||
| 3771 | Widget widget; | ||
| 3772 | { | ||
| 3773 | struct face *face; | ||
| 3774 | Lisp_Object lface; | ||
| 3775 | Arg av[3]; | ||
| 3776 | int ac = 0; | ||
| 3777 | XmFontList fl = 0; | ||
| 3778 | |||
| 3779 | lface = lface_from_face_name (f, Qmenu, 1); | ||
| 3780 | face = FACE_FROM_ID (f, MENU_FACE_ID); | ||
| 3781 | |||
| 3782 | if (!UNSPECIFIEDP (LFACE_FOREGROUND (lface))) | ||
| 3783 | { | ||
| 3784 | XtSetArg (av[ac], XmNforeground, face->foreground); | ||
| 3785 | ++ac; | ||
| 3786 | } | ||
| 3787 | |||
| 3788 | if (!UNSPECIFIEDP (LFACE_BACKGROUND (lface))) | ||
| 3789 | { | ||
| 3790 | XtSetArg (av[ac], XmNbackground, face->background); | ||
| 3791 | ++ac; | ||
| 3792 | } | ||
| 3793 | |||
| 3794 | /* If any font-related attribute of `menu' is set, set the font. */ | ||
| 3795 | if (face->font | ||
| 3796 | && (!UNSPECIFIEDP (LFACE_FAMILY (lface)) | ||
| 3797 | || !UNSPECIFIEDP (LFACE_SWIDTH (lface)) | ||
| 3798 | || !UNSPECIFIEDP (LFACE_WEIGHT (lface)) | ||
| 3799 | || !UNSPECIFIEDP (LFACE_SLANT (lface)) | ||
| 3800 | || !UNSPECIFIEDP (LFACE_HEIGHT (lface)))) | ||
| 3801 | { | ||
| 3802 | #if 0 /* Setting the font leads to an infinite loop somewhere | ||
| 3803 | in LessTif during geometry computation. */ | ||
| 3804 | XmFontListEntry fe; | ||
| 3805 | fe = XmFontListEntryCreate ("menu_font", XmFONT_IS_FONT, face->font); | ||
| 3806 | fl = XmFontListAppendEntry (NULL, fe); | ||
| 3807 | XtSetArg (av[ac], XmNfontList, fl); | ||
| 3808 | ++ac; | ||
| 3809 | #endif | ||
| 3810 | } | ||
| 3811 | |||
| 3812 | xassert (ac <= sizeof av / sizeof *av); | ||
| 3813 | |||
| 3814 | if (ac) | ||
| 3815 | { | ||
| 3816 | struct x_resources res; | ||
| 3817 | |||
| 3818 | XtSetValues (widget, av, ac); | ||
| 3819 | res.av = av, res.ac = ac; | ||
| 3820 | XtApplyToWidgets (widget, xm_apply_resources, &res); | ||
| 3821 | if (fl) | ||
| 3822 | XmFontListFree (fl); | ||
| 3823 | } | ||
| 3824 | } | ||
| 3825 | |||
| 3826 | |||
| 3827 | #endif /* USE_MOTIF */ | ||
| 3828 | |||
| 3829 | #ifdef USE_LUCID | ||
| 3830 | |||
| 3831 | static void xl_apply_resources P_ ((Widget, XtPointer)); | ||
| 3832 | static void xl_set_menu_resources_from_menu_face P_ ((struct frame *, Widget)); | ||
| 3833 | |||
| 3834 | |||
| 3835 | /* Set widget W's resources from P which points to an x_resources | ||
| 3836 | structure. */ | ||
| 3837 | |||
| 3838 | static void | ||
| 3839 | xl_apply_resources (widget, p) | ||
| 3840 | Widget widget; | ||
| 3841 | XtPointer p; | ||
| 3842 | { | ||
| 3843 | struct x_resources *res = (struct x_resources *) p; | ||
| 3844 | XtSetValues (widget, res->av, res->ac); | ||
| 3845 | } | ||
| 3846 | |||
| 3847 | |||
| 3848 | /* On frame F, set X resources of menu-widget WIDGET from face `menu'. | ||
| 3849 | This is the Lucid version. */ | ||
| 3850 | |||
| 3851 | static void | ||
| 3852 | xl_set_menu_resources_from_menu_face (f, widget) | ||
| 3853 | struct frame *f; | ||
| 3854 | Widget widget; | ||
| 3855 | { | ||
| 3856 | struct face *face; | ||
| 3857 | Lisp_Object lface; | ||
| 3858 | Arg av[3]; | ||
| 3859 | int ac = 0; | ||
| 3860 | |||
| 3861 | lface = lface_from_face_name (f, Qmenu, 1); | ||
| 3862 | face = FACE_FROM_ID (f, MENU_FACE_ID); | ||
| 3863 | |||
| 3864 | if (!UNSPECIFIEDP (LFACE_FOREGROUND (lface))) | ||
| 3865 | { | ||
| 3866 | XtSetArg (av[ac], XtNforeground, face->foreground); | ||
| 3867 | ++ac; | ||
| 3868 | } | ||
| 3869 | |||
| 3870 | if (!UNSPECIFIEDP (LFACE_BACKGROUND (lface))) | ||
| 3871 | { | ||
| 3872 | XtSetArg (av[ac], XtNbackground, face->background); | ||
| 3873 | ++ac; | ||
| 3874 | } | ||
| 3875 | |||
| 3876 | if (face->font | ||
| 3877 | && (!UNSPECIFIEDP (LFACE_FAMILY (lface)) | ||
| 3878 | || !UNSPECIFIEDP (LFACE_SWIDTH (lface)) | ||
| 3879 | || !UNSPECIFIEDP (LFACE_WEIGHT (lface)) | ||
| 3880 | || !UNSPECIFIEDP (LFACE_SLANT (lface)) | ||
| 3881 | || !UNSPECIFIEDP (LFACE_HEIGHT (lface)))) | ||
| 3882 | { | ||
| 3883 | XtSetArg (av[ac], XtNfont, face->font); | ||
| 3884 | ++ac; | ||
| 3885 | } | ||
| 3886 | |||
| 3887 | if (ac) | ||
| 3888 | { | ||
| 3889 | struct x_resources res; | ||
| 3890 | |||
| 3891 | XtSetValues (widget, av, ac); | ||
| 3892 | |||
| 3893 | /* We must do children here in case we're handling a pop-up menu | ||
| 3894 | in which case WIDGET is a popup shell. XtApplyToWidgets | ||
| 3895 | is a function from lwlib. */ | ||
| 3896 | res.av = av, res.ac = ac; | ||
| 3897 | XtApplyToWidgets (widget, xl_apply_resources, &res); | ||
| 3898 | } | ||
| 3899 | } | ||
| 3900 | |||
| 3901 | #endif /* USE_LUCID */ | ||
| 3902 | |||
| 3903 | |||
| 3904 | /* On frame F, set X resources of menu-widget WIDGET from face `menu'. */ | ||
| 3905 | |||
| 3906 | void | ||
| 3907 | x_set_menu_resources_from_menu_face (f, widget) | ||
| 3908 | struct frame *f; | ||
| 3909 | Widget widget; | ||
| 3910 | { | ||
| 3911 | #ifdef USE_LUCID | ||
| 3912 | xl_set_menu_resources_from_menu_face (f, widget); | ||
| 3913 | #endif | ||
| 3914 | #ifdef USE_MOTIF | ||
| 3915 | xm_set_menu_resources_from_menu_face (f, widget); | ||
| 3916 | #endif | ||
| 3917 | } | ||
| 3918 | |||
| 3919 | #endif /* USE_X_TOOLKIT */ | ||
| 3920 | |||
| 3669 | #endif /* HAVE_X_WINDOWS */ | 3921 | #endif /* HAVE_X_WINDOWS */ |
| 3670 | 3922 | ||
| 3671 | 3923 | ||
| @@ -5217,6 +5469,7 @@ realize_basic_faces (f) | |||
| 5217 | realize_named_face (f, Qborder, BORDER_FACE_ID); | 5469 | realize_named_face (f, Qborder, BORDER_FACE_ID); |
| 5218 | realize_named_face (f, Qcursor, CURSOR_FACE_ID); | 5470 | realize_named_face (f, Qcursor, CURSOR_FACE_ID); |
| 5219 | realize_named_face (f, Qmouse, MOUSE_FACE_ID); | 5471 | realize_named_face (f, Qmouse, MOUSE_FACE_ID); |
| 5472 | realize_named_face (f, Qmenu, MENU_FACE_ID); | ||
| 5220 | success_p = 1; | 5473 | success_p = 1; |
| 5221 | } | 5474 | } |
| 5222 | 5475 | ||
| @@ -6340,6 +6593,8 @@ syms_of_xfaces () | |||
| 6340 | staticpro (&Qheader_line); | 6593 | staticpro (&Qheader_line); |
| 6341 | Qscroll_bar = intern ("scroll-bar"); | 6594 | Qscroll_bar = intern ("scroll-bar"); |
| 6342 | staticpro (&Qscroll_bar); | 6595 | staticpro (&Qscroll_bar); |
| 6596 | Qmenu = intern ("menu"); | ||
| 6597 | staticpro (&Qmenu); | ||
| 6343 | Qcursor = intern ("cursor"); | 6598 | Qcursor = intern ("cursor"); |
| 6344 | staticpro (&Qcursor); | 6599 | staticpro (&Qcursor); |
| 6345 | Qborder = intern ("border"); | 6600 | Qborder = intern ("border"); |