APPROVE COMMIT sjt-xft
For the lwlib parts of the patch, see my recent "stop tab geometry
thrashing" for 21.5.
With the current Xft patch, core X fonts and Xft fonts must coexist to
some extent (because not all widgets can handle Xft fonts yet).
G. Boffi reports a crash where an uninitialized XFontStruct causes X
to segfault. This patch should fix that (but it's untested for that).
A patch to do the same thing for Xft fonts is forthcoming, but this is
not critical because Xft fonts should almost never fail to be
initialized (fontconfig almost always returns _something_).
There are a couple of minor improvements in geometry calculations in
object-x.c, and some variable renamings (a couple of XFontStructs have
been renamed to "fs" for consistency with usage elsewhere).
Index: lwlib/ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lwlib/ChangeLog,v
retrieving revision 1.64.2.6
diff -u -r1.64.2.6 ChangeLog
--- lwlib/ChangeLog 7 Mar 2005 02:25:54 -0000 1.64.2.6
+++ lwlib/ChangeLog 9 Mar 2005 01:03:11 -0000
@@ -0,0 +1,6 @@
+2005-03-07 Stephen J. Turnbull <stephen(a)xemacs.org>
+
+ * lwlib-Xlw.c (build_tabs_in_widget): Correctly disable geometry
+ negotiation for tab children.
+ (xlw_create_tab_control): Don't set nonexistent resizable resource.
+
Index: lwlib/lwlib-Xlw.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lwlib/lwlib-Xlw.c,v
retrieving revision 1.13
diff -u -r1.13 lwlib-Xlw.c
--- lwlib/lwlib-Xlw.c 20 Sep 2004 19:19:16 -0000 1.13
+++ lwlib/lwlib-Xlw.c 9 Mar 2005 01:03:11 -0000
@@ -319,13 +319,21 @@
#ifdef LWLIB_TABS_LUCID
/* tab control
- lwlib is such an incredible hairy crock. I just cannot believe
+ [[ lwlib is such an incredible hairy crock. I just cannot believe
it! There are random dependencies between functions, there is a
total lack of genericity, even though it initially appears to be
generic. It should all be junked and begun again. Building tabs are
an example - in theory we should be able to reuse a lot of the
general stuff because we want to put labels of whatever toolkit we
- are using in the tab. Instead we have to hack it by hand. */
+ are using in the tab. Instead we have to hack it by hand. ]]
+ While lwlib is a hairy crock, whoever wrote that seems to misunderstand
+ Falk's tab control widget. The tab control widget has *two* kinds of
+ children: *widgets*, which all occupy a *single* pane below the row of
+ tabs---this is where the labels created in build_tabs_in_widget go, and
+ *gadgets*, the tabs themselves, which do *not* draw themselves, but
+ rather are drawn by the control. In fact, in XEmacs the true widget
+ children are *never* visible! So this case is not a problem in the
+ design of lwlib, but rather of Falk's widget. -- sjt */
static void
xlw_tab_control_callback (Widget w, XtPointer client_data, XtPointer call_data)
{
@@ -375,9 +383,8 @@
widget_value* val = instance->info->val;
XtSetArg (al [ac], XtNsensitive, val->enabled); ac++;
- XtSetArg (al [ac], XtNmappedWhenManaged, FALSE); ac++;
+ XtSetArg (al [ac], XtNmappedWhenManaged, False); ac++;
XtSetArg (al [ac], XtNorientation, XtorientHorizontal); ac++;
- XtSetArg (al [ac], XtNresizable, False); ac++;
/* add any args the user supplied for creation time */
lw_add_value_args_to_args (val, al, &ac);
@@ -396,15 +403,22 @@
Widget widget, widget_value* val)
{
widget_value* cur = val;
+ Arg al[1];
+
+ /* Children are always invisible, don't permit resizing. */
+ XtSetArg (al[0], XtNresizable, False);
+
for (cur = val; cur; cur = cur->next)
{
if (cur->value)
{
+ Widget w;
#ifdef LWLIB_WIDGETS_MOTIF
- xm_create_label (widget, cur);
+ w = xm_create_label (widget, cur);
#else
- xaw_create_label (widget, cur);
+ w = xaw_create_label (widget, cur);
#endif
+ XtSetValues (w, al, 1);
}
cur->change = NO_CHANGE;
}
@@ -465,8 +479,8 @@
Widget clip = 0;
widget_value* val = instance->info->val;
- XtSetArg (al [ac], XtNmappedWhenManaged, FALSE); ac++;
- XtSetArg (al [ac], XtNsensitive, TRUE); ac++;
+ XtSetArg (al [ac], XtNmappedWhenManaged, False); ac++;
+ XtSetArg (al [ac], XtNsensitive, True); ac++;
/* add any args the user supplied for creation time */
lw_add_value_args_to_args (val, al, &ac);
Index: lwlib/xlwtabs.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lwlib/xlwtabs.c,v
retrieving revision 1.4.2.8
diff -u -r1.4.2.8 xlwtabs.c
--- lwlib/xlwtabs.c 7 Mar 2005 02:25:54 -0000 1.4.2.8
+++ lwlib/xlwtabs.c 9 Mar 2005 01:03:12 -0000
@@ -909,10 +909,12 @@
static int debug_mask = 1;
/* Position request cannot be satisfied, so if tabs are not resizable,
- no request can be satisfied: return XGeometryNo. */
+ no nontrivial request can be satisfied: return XGeometryNo. */
if (!constraint->tabs.resizable)
return XtGeometryNo;
+ fprintf (stderr, "Urk! label is resizable!\n");
+
/* Assume we will refuse these; toggle iff we accept them.
Reply won't specify any fields not in the request. */
reply->request_mode = request->request_mode;
@@ -943,7 +945,10 @@
reply->width == tab->core.width &&
reply->height == tab->core.height &&
reply->border_width == tab->core.border_width)
- return best_offer;
+ {
+ reply->request_mode &= ~(CWWidth | CWHeight | CWBorderWidth);
+ return best_offer;
+ }
#ifndef DONT_DEBUG_REQUESTS
#define DBG_REQUEST_PRINT(name,field,size) \
@@ -1131,9 +1136,14 @@
/* Cannot grant child's request. Describe what we *can* do
* and return counter-offer.
*/
+ control->tabs.needs_layout = False;
reply->width = aw - 2 * request->border_width ;
reply->height = ah - 2 * request->border_width ;
- control->tabs.needs_layout = False;
+ reply->request_mode &=
+ ~((reply->border_width == tab->core.border_width
+ ? CWBorderWidth : 0)
+ |(reply->width == tab->core.width ? CWWidth : 0)
+ |(reply->height == tab->core.height ? CWHeight : 0))
return XtGeometryAlmost ;
}
Index: src/ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/ChangeLog,v
retrieving revision 1.758.2.16
diff -u -r1.758.2.16 ChangeLog
--- src/ChangeLog 5 Mar 2005 18:09:25 -0000 1.758.2.16
+++ src/ChangeLog 9 Mar 2005 01:03:27 -0000
@@ -1,3 +1,16 @@
+2005-03-07 Stephen J. Turnbull <stephen(a)xemacs.org>
+
+ * objects-x-impl.h: Include lwlib-fonts.h
+
+ * objects-x.c (x_font_instance_truename):
+ * glyphs-x.c (update_widget_face):
+ * frame-x.c (x_update_frame_external_traits):
+ Use the correct variant of FONT_INSTANCE_{X,XFT}_FONT.
+ Protect against access of uninitialized objects.
+
+ * redisplay-x.c (x_get_gc): Fix typo.
+ * (x_output_string): Add comments, clarify logic slightly.
+
2005-03-05 Stephen J. Turnbull <stephen(a)xemacs.org>
Refactor language/charset checking in Xft.
Index: src/frame-x.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/frame-x.c,v
retrieving revision 1.68.2.3
diff -u -r1.68.2.3 frame-x.c
--- src/frame-x.c 5 Mar 2005 18:09:28 -0000 1.68.2.3
+++ src/frame-x.c 9 Mar 2005 01:03:28 -0000
@@ -2674,17 +2674,30 @@
}
else if (EQ (name, Qfont))
{
- /* #### what to do about Xft? It looks like the font is used to
- compute cell size for computing frame pixel dimensions (see call
- to EmacsFrameRecomputeCellSize() below); maybe we should make
- those directly members of the frame, not the font itself. -- sjt */
Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii);
+ /* #### what to do about Xft? I don't think the font is actually used
+ to compute cell size for computing frame pixel dimensions (see call
+ to EmacsFrameRecomputeCellSize() below); where is it used? -- sjt
+ What does XtSetValues() do if that resource isn't present? */
if (!EQ (font, Vthe_null_font_instance))
{
- XtSetArg (al[ac], XtNfont,
- (void *) FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)));
- ac++;
+ if (0)
+ ;
+#ifdef USE_XFT
+ else if (FONT_INSTANCE_X_XFTFONT (XFONT_INSTANCE (font)))
+ {
+ XtSetArg (al[ac], XtNxftFont,
+ (void *) FONT_INSTANCE_X_XFTFONT (XFONT_INSTANCE (font)));
+ ac++;
+ }
+#endif
+ else if (FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)))
+ {
+ XtSetArg (al[ac], XtNfont,
+ (void *) FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)));
+ ac++;
+ }
}
}
else
Index: src/glyphs-x.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/glyphs-x.c,v
retrieving revision 1.80.2.4
diff -u -r1.80.2.4 glyphs-x.c
--- src/glyphs-x.c 1 Feb 2005 15:46:55 -0000 1.80.2.4
+++ src/glyphs-x.c 9 Mar 2005 01:03:29 -0000
@@ -2326,21 +2326,33 @@
lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel);
{
- /* #### What to do about Xft? */
Lisp_Object face = IMAGE_INSTANCE_WIDGET_FACE (ii);
- XFontStruct *fs =
- FONT_INSTANCE_X_FONT (XFONT_INSTANCE (query_string_font
- (IMAGE_INSTANCE_WIDGET_TEXT (ii),
- face,
- domain)));
-#ifdef LWLIB_WIDGETS_MOTIF
- fontList = XmFontListCreate (fs, XmSTRING_DEFAULT_CHARSET);
- lw_add_widget_value_arg (wv, XmNfontList, (XtArgVal)fontList);
+ Lisp_Font_Instance *fi =
+ XFONT_INSTANCE (query_string_font (IMAGE_INSTANCE_WIDGET_TEXT (ii),
+ face,
+ domain));
+ XFontStruct *fs = FONT_INSTANCE_X_FONT (fi);
+#ifdef USE_XFT
+ XftFont *rf = FONT_INSTANCE_X_XFTFONT (fi);
+
+ if (rf)
+ {
+ /* #### What to do about Motif? */
+ lw_add_widget_value_arg (wv, XtNxftFont, (XtArgVal) rf);
+ }
#endif
- /* #### This is an unacceptable hack. */
+
if (fs)
- lw_add_widget_value_arg (wv, XtNfont, (XtArgVal) fs);
- else
+ {
+#ifdef LWLIB_WIDGETS_MOTIF
+ fontList = XmFontListCreate (fs, XmSTRING_DEFAULT_CHARSET);
+ lw_add_widget_value_arg (wv, XmNfontList, (XtArgVal) fontList);
+#endif
+ lw_add_widget_value_arg (wv, XtNfont, (XtArgVal) fs);
+ }
+
+ /* #### sanity check, should wrap in appropriate ERROR_CHECK macro */
+ if (!rf && !fs)
warn_when_safe_lispobj
(intern ("xft"), Qdebug,
Fcons (build_string ("missing font in update_widget_face"),
Index: src/objects-x-impl.h
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/objects-x-impl.h,v
retrieving revision 1.1.6.1
diff -u -r1.1.6.1 objects-x-impl.h
--- src/objects-x-impl.h 25 Nov 2004 12:44:15 -0000 1.1.6.1
+++ src/objects-x-impl.h 9 Mar 2005 01:03:29 -0000
@@ -29,6 +29,10 @@
#include "objects-impl.h"
#include "objects-x.h"
+#ifdef USE_XFT
+/* for resource name definitions, etc */
+#include "../lwlib/lwlib-fonts.h"
+#endif
#ifdef HAVE_X_WINDOWS
Index: src/objects-x.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/objects-x.c,v
retrieving revision 1.26.2.10
diff -u -r1.26.2.10 objects-x.c
--- src/objects-x.c 5 Mar 2005 18:09:29 -0000 1.26.2.10
+++ src/objects-x.c 9 Mar 2005 01:03:29 -0000
@@ -237,12 +237,11 @@
{
/* yes, this has been known to happen. */
XFreeFont (dpy, fs);
+ fs = NULL;
maybe_signal_error (Qgui_error, "X font is too small", f->name,
Qfont,
errb);
if (!rf)
return 0;
- else
- fs = NULL;
}
/* Now that we're sure that we will succeed, we can allocate data without
@@ -274,17 +273,17 @@
XftTextExtents8 (dpy, rf, test_string8, len, &glyphinfo);
/* #### maybe should be glyphinfo.xOff - glyphinfo.x? */
- f->width = glyphinfo.width/len + 1;
+ f->width = (2*glyphinfo.width + len)/(2*len);
}
f->height = rf->height;
- /* #### Is this right? See comment on proportional_p below. */
- f->proportional_p = 1; /* we can't recognize monospaced fonts! */
+ f->proportional_p = 1; /* we can't recognize monospaced fonts! */
if (debug_xft > 0)
stderr_out ("initialized metrics ascent %d descent %d width %d height %d\n",
f->ascent, f->descent, f->width, f->height);
if (debug_xft > 2) /* we also output on initialization of any font below */
stderr_out ("initialized Xft font %s\n", extname);
+ fs = NULL; /* we don' need no steenkin' X font */
}
else
{
@@ -294,7 +293,7 @@
#endif
FONT_INSTANCE_X_FONT (f) = fs;
- if (fs && !rf) /* fs && rf is unlikely, but play it safe */
+ if (fs)
/* Have to use a core font, initialize font info from it. */
{
f->ascent = fs->ascent;
@@ -769,7 +768,8 @@
#endif
/* OK, fall back to core font. */
- if (NILP (FONT_INSTANCE_TRUENAME (f)))
+ if (NILP (FONT_INSTANCE_TRUENAME (f))
+ && FONT_INSTANCE_X_FONT (f))
{
nameext = &xlfd[0];
LISP_STRING_TO_EXTERNAL (f->name, nameext, Qx_font_name_encoding);
Index: src/redisplay-x.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/redisplay-x.c,v
retrieving revision 1.39.2.3
diff -u -r1.39.2.3 redisplay-x.c
--- src/redisplay-x.c 1 Feb 2005 15:46:57 -0000 1.39.2.3
+++ src/redisplay-x.c 9 Mar 2005 01:03:30 -0000
@@ -800,7 +800,7 @@
/* evil kludge! */
if (!NILP (fg) && !COLOR_INSTANCEP (fg) && !INTP (fg))
{
- /* #### I fixed once case where this was getting it. It was a
+ /* #### I fixed one case where this was getting hit. It was a
bad macro expansion (compiler bug). */
stderr_out ("Help! x_get_gc got a bogus fg value! fg = ");
debug_print (fg);
@@ -931,7 +931,8 @@
int i;
struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex);
- int use_x_font = 1;
+ int use_x_font = 1; /* #### bogus!!
+ The logic of this function needs review! */
#ifdef USE_XFT
Colormap cmap = DEVICE_X_COLORMAP (d);
Visual *visual = DEVICE_X_VISUAL (d);
@@ -1214,19 +1215,18 @@
{
int upos, uthick;
unsigned long upos_ext, uthick_ext;
- XFontStruct *xfont = FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font));
+ XFontStruct *fs =
+ use_x_font ? FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)) : 0;
/* #### the logic of the next two may be suboptimal: we may want
to use the POSITION and/or THICKNESS information with Xft */
- if (!use_x_font
- || !XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &upos_ext))
- upos = dl->descent / 2;
- else
+ if (fs && XGetFontProperty (fs, XA_UNDERLINE_POSITION, &upos_ext))
upos = (int) upos_ext;
- if (!use_x_font
- || !XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &uthick_ext))
- uthick = 1;
else
+ upos = dl->descent / 2;
+ if (fs && XGetFontProperty (fs, XA_UNDERLINE_THICKNESS, &uthick_ext))
uthick = (int) uthick_ext;
+ else
+ uthick = 1;
if (dl->ypos + upos < dl->ypos + dl->descent - dl->clip)
{
if (dl->ypos + upos + uthick > dl->ypos + dl->descent - dl->clip)
@@ -1249,7 +1249,7 @@
{
int ascent, descent, upos, uthick;
unsigned long ascent_ext, descent_ext, uthick_ext;
- XFontStruct *xf = FONT_INSTANCE_X_FONT (fi);
+ XFontStruct *fs = FONT_INSTANCE_X_FONT (fi);
if (!use_x_font)
{
@@ -1259,15 +1259,15 @@
}
else
{
- if (!XGetFontProperty (xf, XA_STRIKEOUT_ASCENT, &ascent_ext))
- ascent = xf->ascent;
+ if (!XGetFontProperty (fs, XA_STRIKEOUT_ASCENT, &ascent_ext))
+ ascent = fs->ascent;
else
ascent = (int) ascent_ext;
- if (!XGetFontProperty (xf, XA_STRIKEOUT_DESCENT, &descent_ext))
- descent = xf->descent;
+ if (!XGetFontProperty (fs, XA_STRIKEOUT_DESCENT, &descent_ext))
+ descent = fs->descent;
else
descent = (int