Mercurial > emacs
changeset 25883:2955c353186a
(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.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Wed, 06 Oct 1999 23:09:44 +0000 |
parents | 42efd343a3f8 |
children | 1bdd14c5ed64 |
files | src/xfaces.c |
diffstat | 1 files changed, 288 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/src/xfaces.c Wed Oct 06 23:05:32 1999 +0000 +++ b/src/xfaces.c Wed Oct 06 23:09:44 1999 +0000 @@ -187,6 +187,10 @@ #ifdef HAVE_X_WINDOWS #include "xterm.h" #include "fontset.h" +#ifdef USE_MOTIF +#include <Xm/Xm.h> +#include <Xm/XmStrDefs.h> +#endif /* USE_MOTIF */ #endif #ifdef MSDOS @@ -286,7 +290,7 @@ /* Names of basic faces. */ Lisp_Object Qdefault, Qmode_line, Qtool_bar, Qregion, Qfringe; -Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse;; +Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu; /* The symbol `face-alias'. A symbols having that property is an alias for another face. Value of the property is the name of @@ -397,6 +401,7 @@ struct font_name; struct table_entry; +static Lisp_Object resolve_face_name P_ ((Lisp_Object)); static int may_use_scalable_font_p P_ ((struct font_name *, char *)); static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object)); static int better_font_p P_ ((int *, struct font_name *, struct font_name *, @@ -834,31 +839,52 @@ #ifdef HAVE_X_WINDOWS DEFUN ("pixmap-spec-p", Fpixmap_spec_p, Spixmap_spec_p, 1, 1, 0, - "Non-nil if OBJECT is a valid pixmap specification.\n\ -A pixmap specification is either a string, or a list (WIDTH HEIGHT DATA)\n\ -where WIDTH is the pixel width of the pixmap, HEIGHT is its height,\n\ -and DATA contains the bits of the pixmap.") + "Value is non-nil if OBJECT is a valid pixmap specification.\n\ +A pixmap specification is either a string, a file name, or a list\n\ +(WIDTH HEIGHT DATA) where WIDTH is the pixel width of the pixmap,\n\ +HEIGHT is its height, and DATA is a string containing the bits of\n\ +the pixmap. Bits are stored row by row, each row occupies\n\ +(WIDTH + 7)/8 bytes.") (object) Lisp_Object object; { - Lisp_Object height, width; - - return ((STRINGP (object) - || (CONSP (object) - && CONSP (XCONS (object)->cdr) - && CONSP (XCONS (XCONS (object)->cdr)->cdr) - && NILP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->cdr) - && (width = XCONS (object)->car, INTEGERP (width)) - && (height = XCONS (XCONS (object)->cdr)->car, - INTEGERP (height)) - && STRINGP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car) - && XINT (width) > 0 - && XINT (height) > 0 - /* The string must have enough bits for width * height. */ - && ((XSTRING (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car)->size - * (BITS_PER_INT / sizeof (int))) - >= XFASTINT (width) * XFASTINT (height)))) - ? Qt : Qnil); + int pixmap_p = 0; + + if (STRINGP (object)) + /* If OBJECT is a string, it's a file name. */ + pixmap_p = 1; + else if (CONSP (object)) + { + /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and + HEIGHT must be integers > 0, and DATA must be string large + enough to hold a bitmap of the specified size. */ + Lisp_Object width, height, data; + + height = width = data = Qnil; + + if (CONSP (object)) + { + width = XCAR (object); + object = XCDR (object); + if (CONSP (object)) + { + height = XCAR (object); + object = XCDR (object); + if (CONSP (object)) + data = XCAR (object); + } + } + + if (NATNUMP (width) && NATNUMP (height) && STRINGP (data)) + { + int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1) + / BITS_PER_CHAR); + if (STRING_BYTES (XSTRING (data)) >= bytes_per_row * height) + pixmap_p = 1; + } + } + + return pixmap_p ? Qt : Qnil; } @@ -2568,6 +2594,32 @@ #endif /* GLYPH_DEBUG == 0 */ +/* Resolve face name FACE_NAME. If FACE_NAME Is a string, intern it + to make it a symvol. If FACE_NAME is an alias for another face, + return that face's name. */ + +static Lisp_Object +resolve_face_name (face_name) + Lisp_Object face_name; +{ + Lisp_Object aliased; + + if (STRINGP (face_name)) + face_name = intern (XSTRING (face_name)->data); + + for (;;) + { + aliased = Fget (face_name, Qface_alias); + if (NILP (aliased)) + break; + else + face_name = aliased; + } + + return face_name; +} + + /* Return the face definition of FACE_NAME on frame F. F null means return the global definition. FACE_NAME may be a string or a symbol (apparently Emacs 20.2 allows strings as face names in face @@ -2583,16 +2635,9 @@ Lisp_Object face_name; int signal_p; { - Lisp_Object lface, alias; - - if (STRINGP (face_name)) - face_name = intern (XSTRING (face_name)->data); - - /* If FACE_NAME is an alias for another face, return the definition - of the aliased face. */ - alias = Fget (face_name, Qface_alias); - if (!NILP (alias)) - face_name = alias; + Lisp_Object lface; + + face_name = resolve_face_name (face_name); if (f) lface = assq_no_quit (face_name, f->face_alist); @@ -3118,6 +3163,8 @@ CHECK_SYMBOL (face, 0); CHECK_SYMBOL (attr, 1); + face = resolve_face_name (face); + /* Set lface to the Lisp attribute vector of FACE. */ if (EQ (frame, Qt)) lface = lface_from_face_name (NULL, face, 1); @@ -3666,6 +3713,211 @@ } + +/*********************************************************************** + Menu face + ***********************************************************************/ + +#ifdef USE_X_TOOLKIT + +/* Structure used to pass X resources to functions called via + XtApplyToWidgets. */ + +struct x_resources +{ + Arg *av; + int ac; +}; + + +#ifdef USE_MOTIF + +static void xm_apply_resources P_ ((Widget, XtPointer)); +static void xm_set_menu_resources_from_menu_face P_ ((struct frame *, Widget)); + + +/* Set widget W's X resources from P which points to an x_resources + structure. If W is a cascade button, apply resources to W's + submenu. */ + +static void +xm_apply_resources (w, p) + Widget w; + XtPointer p; +{ + Widget submenu = 0; + struct x_resources *res = (struct x_resources *) p; + + XtSetValues (w, res->av, res->ac); + XtVaGetValues (w, XmNsubMenuId, &submenu, NULL); + if (submenu) + { + XtSetValues (submenu, res->av, res->ac); + XtApplyToWidgets (submenu, xm_apply_resources, p); + } +} + + +/* Set X resources of menu-widget WIDGET on frame F from face `menu'. + This is the LessTif/Motif version. As of LessTif 0.88 it has the + following problems: + + 1. Setting the XmNfontList resource leads to an infinite loop + somewhere in LessTif. */ + +static void +xm_set_menu_resources_from_menu_face (f, widget) + struct frame *f; + Widget widget; +{ + struct face *face; + Lisp_Object lface; + Arg av[3]; + int ac = 0; + XmFontList fl = 0; + + lface = lface_from_face_name (f, Qmenu, 1); + face = FACE_FROM_ID (f, MENU_FACE_ID); + + if (!UNSPECIFIEDP (LFACE_FOREGROUND (lface))) + { + XtSetArg (av[ac], XmNforeground, face->foreground); + ++ac; + } + + if (!UNSPECIFIEDP (LFACE_BACKGROUND (lface))) + { + XtSetArg (av[ac], XmNbackground, face->background); + ++ac; + } + + /* If any font-related attribute of `menu' is set, set the font. */ + if (face->font + && (!UNSPECIFIEDP (LFACE_FAMILY (lface)) + || !UNSPECIFIEDP (LFACE_SWIDTH (lface)) + || !UNSPECIFIEDP (LFACE_WEIGHT (lface)) + || !UNSPECIFIEDP (LFACE_SLANT (lface)) + || !UNSPECIFIEDP (LFACE_HEIGHT (lface)))) + { +#if 0 /* Setting the font leads to an infinite loop somewhere + in LessTif during geometry computation. */ + XmFontListEntry fe; + fe = XmFontListEntryCreate ("menu_font", XmFONT_IS_FONT, face->font); + fl = XmFontListAppendEntry (NULL, fe); + XtSetArg (av[ac], XmNfontList, fl); + ++ac; +#endif + } + + xassert (ac <= sizeof av / sizeof *av); + + if (ac) + { + struct x_resources res; + + XtSetValues (widget, av, ac); + res.av = av, res.ac = ac; + XtApplyToWidgets (widget, xm_apply_resources, &res); + if (fl) + XmFontListFree (fl); + } +} + + +#endif /* USE_MOTIF */ + +#ifdef USE_LUCID + +static void xl_apply_resources P_ ((Widget, XtPointer)); +static void xl_set_menu_resources_from_menu_face P_ ((struct frame *, Widget)); + + +/* Set widget W's resources from P which points to an x_resources + structure. */ + +static void +xl_apply_resources (widget, p) + Widget widget; + XtPointer p; +{ + struct x_resources *res = (struct x_resources *) p; + XtSetValues (widget, res->av, res->ac); +} + + +/* On frame F, set X resources of menu-widget WIDGET from face `menu'. + This is the Lucid version. */ + +static void +xl_set_menu_resources_from_menu_face (f, widget) + struct frame *f; + Widget widget; +{ + struct face *face; + Lisp_Object lface; + Arg av[3]; + int ac = 0; + + lface = lface_from_face_name (f, Qmenu, 1); + face = FACE_FROM_ID (f, MENU_FACE_ID); + + if (!UNSPECIFIEDP (LFACE_FOREGROUND (lface))) + { + XtSetArg (av[ac], XtNforeground, face->foreground); + ++ac; + } + + if (!UNSPECIFIEDP (LFACE_BACKGROUND (lface))) + { + XtSetArg (av[ac], XtNbackground, face->background); + ++ac; + } + + if (face->font + && (!UNSPECIFIEDP (LFACE_FAMILY (lface)) + || !UNSPECIFIEDP (LFACE_SWIDTH (lface)) + || !UNSPECIFIEDP (LFACE_WEIGHT (lface)) + || !UNSPECIFIEDP (LFACE_SLANT (lface)) + || !UNSPECIFIEDP (LFACE_HEIGHT (lface)))) + { + XtSetArg (av[ac], XtNfont, face->font); + ++ac; + } + + if (ac) + { + struct x_resources res; + + XtSetValues (widget, av, ac); + + /* We must do children here in case we're handling a pop-up menu + in which case WIDGET is a popup shell. XtApplyToWidgets + is a function from lwlib. */ + res.av = av, res.ac = ac; + XtApplyToWidgets (widget, xl_apply_resources, &res); + } +} + +#endif /* USE_LUCID */ + + +/* On frame F, set X resources of menu-widget WIDGET from face `menu'. */ + +void +x_set_menu_resources_from_menu_face (f, widget) + struct frame *f; + Widget widget; +{ +#ifdef USE_LUCID + xl_set_menu_resources_from_menu_face (f, widget); +#endif +#ifdef USE_MOTIF + xm_set_menu_resources_from_menu_face (f, widget); +#endif +} + +#endif /* USE_X_TOOLKIT */ + #endif /* HAVE_X_WINDOWS */ @@ -5217,6 +5469,7 @@ realize_named_face (f, Qborder, BORDER_FACE_ID); realize_named_face (f, Qcursor, CURSOR_FACE_ID); realize_named_face (f, Qmouse, MOUSE_FACE_ID); + realize_named_face (f, Qmenu, MENU_FACE_ID); success_p = 1; } @@ -6340,6 +6593,8 @@ staticpro (&Qheader_line); Qscroll_bar = intern ("scroll-bar"); staticpro (&Qscroll_bar); + Qmenu = intern ("menu"); + staticpro (&Qmenu); Qcursor = intern ("cursor"); staticpro (&Qcursor); Qborder = intern ("border");