diff src/objects-x.c @ 3659:98af8a976fc3

[xemacs-hg @ 2006-11-05 22:31:31 by aidan] Support specifying fonts for particular character sets in Mule; support translation to ISO 10646-1 for Mule character sets without an otherwise matching font; move to a vector of X11-charset-X11-registry instead of a regex for the charset-registry property.
author aidan
date Sun, 05 Nov 2006 22:31:46 +0000
parents f986ebd9c080
children a23ac8f90a49
line wrap: on
line diff
--- a/src/objects-x.c	Sat Nov 04 22:51:03 2006 +0000
+++ b/src/objects-x.c	Sun Nov 05 22:31:46 2006 +0000
@@ -37,6 +37,7 @@
 
 #include "console-x-impl.h"
 #include "objects-x-impl.h"
+#include "elhash.h"
 
 #ifdef USE_XFT
 #include "font-mgr.h"
@@ -44,6 +45,10 @@
 
 int x_handle_non_fully_specified_fonts;
 
+#ifdef DEBUG_XEMACS 
+Fixnum debug_x_objects;
+#endif /* DEBUG_XEMACS */
+
 
 /************************************************************************/
 /*                          color instances                             */
@@ -205,74 +210,6 @@
 /*                           font instances                             */
 /************************************************************************/
 
-#ifdef USE_XFT
-/* #### all these #defines should probably move to font-mgr.h */
-
-/*
-  The format of a fontname (as returned by fontconfig) is not well-documented,
-  But the character repertoire is represented in an ASCII-compatible way.  See
-  fccharset.c (FcCharSetUnparse).  So we can use UTF-8 for long names.
-
-  Currently we have a hack where different versions of the unparsed name are
-  used in different contexts fairly arbitrarily.  I don't think this is close
-  to coherency; even without the charset and lang properties fontconfig names
-  are too unwieldy to use.  We need to rethink the approach here.  I think
-  probably Lisp_Font_Instance.name should contain the font name as specified
-  to Lisp (almost surely much shorter than shortname, even, and most likely
-  wildcarded), while Lisp_Font_Instance.truename should contain the longname.
-  For now, I'm going to #ifdef the return values defaulting to short. -- sjt
-*/
-
-/*                DEBUGGING STUFF                */
-
-/* print message to stderr: one internal-format string argument */
-#define DEBUG_XFT0(level,s)		\
-  if (debug_xft > level) stderr_out (s)
-
-/* print message to stderr: one formatted argument */
-#define DEBUG_XFT1(level,format,x1)		\
-  if (debug_xft > level) stderr_out (format, x1)
-
-/* print message to stderr: two formatted arguments */
-#define DEBUG_XFT2(level,format,x1,x2)			\
-  if (debug_xft > level) stderr_out (format, x1, x2)
-
-/* print message to stderr: three formatted arguments */
-#define DEBUG_XFT3(level,format,x1,x2,x3)			\
-  if (debug_xft > level) stderr_out (format, x1, x2, x3)
-
-/* print message to stderr: four formatted arguments */
-#define DEBUG_XFT4(level,format,x1,x2,x3,x4)			\
-  if (debug_xft > level) stderr_out (format, x1, x2, x3, x4)
-
-/* print an Xft pattern to stderr
-   LEVEL is the debug level (to compare to debug_xft)
-   FORMAT is a newline-terminated printf format with one %s for the pattern
-     and must be internal format (eg, pure ASCII)
-   PATTERN is an FcPattern *. */
-#define PRINT_XFT_PATTERN(level,format,pattern)			\
-  do {								\
-    DECLARE_EISTRING (eistrpxft_name);				\
-    Extbyte *name = (Extbyte *) FcNameUnparse (pattern);	\
-								\
-    eicpy_ext(eistrpxft_name, name, Qfc_font_name_encoding);	\
-    DEBUG_XFT1 (level, format, eidata(eistrpxft_name));		\
-    free (name);						\
-  } while (0)
-
-/* print a progress message
-   LEVEL is the debug level (to compare to debug_xft)
-   FONT is the Xft font name in UTF-8 (the native encoding of Xft)
-   LANG is the language being checked for support (must be ASCII). */
-#define CHECKING_LANG(level,font,lang)					\
-  do {									\
-    DECLARE_EISTRING (eistrcl_name);					\
-    eicpy_ext(eistrcl_name, (Extbyte *) font, Qfc_font_name_encoding);	\
-    DEBUG_XFT2 (level, "checking if %s handles %s\n",			\
-			eidata(eistrcl_name), lang);			\
-  } while (0)
-
-#endif /* USE_XFT */
 
 static int
 x_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object UNUSED (name),
@@ -299,6 +236,12 @@
   rf = xft_open_font_by_name (dpy, extname);
 #endif
   LISP_STRING_TO_EXTERNAL (f->name, extname, Qx_font_name_encoding);
+  /* With XFree86 4.0's fonts, XListFonts returns an entry for
+     -isas-fangsong ti-medium-r-normal--16-160-72-72-c-160-gb2312.1980-0 but
+     an XLoadQueryFont on the corresponding XLFD returns NULL.
+
+     XListFonts is not trustworthy (of course, this is news to exactly
+     no-one used to reading XEmacs source.) */
   fs = XLoadQueryFont (dpy, extname);
       
   if (!fs && !rf)
@@ -461,9 +404,13 @@
 		       Lisp_Object printcharfun,
 		       int UNUSED (escapeflag))
 {
+  /* We should print information here about initial vs. final stages; we
+     can't rely on the device charset stage cache for that,
+     unfortunately. */
   if (FONT_INSTANCE_X_FONT (f))
-    write_fmt_string (printcharfun, " font id: 0x%lx",
-		      (unsigned long) FONT_INSTANCE_X_FONT (f)->fid);
+      write_fmt_string (printcharfun, " font id: 0x%lx,",
+			(unsigned long) FONT_INSTANCE_X_FONT (f)->fid);
+
 #ifdef USE_XFT
   /* #### What should we do here?  For now, print the address. */
   if (FONT_INSTANCE_X_XFTFONT (f))
@@ -944,534 +891,9 @@
   return result;
 }
 
-#ifdef MULE
-
-static int
-x_font_spec_matches_charset (struct device * USED_IF_XFT (d),
-			     Lisp_Object charset,
-			     const Ibyte *nonreloc, Lisp_Object reloc,
-			     Bytecount offset, Bytecount length,
-			     int stage)
-{
-  if (stage)
-#ifdef USE_XFT
-    {
-      Display *dpy = DEVICE_X_DISPLAY (d);
-      Extbyte *extname;
-      XftFont *rf;
-      const Ibyte *the_nonreloc;
-
-      if (!NILP(reloc))
-	{
-	  the_nonreloc = XSTRING_DATA (reloc);
-	  LISP_STRING_TO_EXTERNAL (reloc, extname, Qx_font_name_encoding);
-	  rf = xft_open_font_by_name (dpy, extname);
-	  return 0;	 /* #### maybe this will compile and run ;) */
-	}
-    }
-#else
-    return 0;
-#endif
-
-  if (UNBOUNDP (charset))
-    return 1;
-  /* Hack! Short font names don't have the registry in them,
-     so we just assume the user knows what they're doing in the
-     case of ASCII.  For other charsets, you gotta give the
-     long form; sorry buster.
-     #### FMH: this screws fontconfig/Xft?
-     STRATEGY: use fontconfig's ability to hack languages and character
-     sets (lang and charset properties).
-     #### Maybe we can use the fontconfig model to eliminate the difference
-     between faces and fonts?  No - it looks like that would be an abuse
-     (fontconfig doesn't know about colors, although Xft does).
-     */
-  if (EQ (charset, Vcharset_ascii))
-    {
-      const Ibyte *the_nonreloc = nonreloc;
-      int i;
-      Bytecount the_length = length;
-
-      if (!the_nonreloc)
-	the_nonreloc = XSTRING_DATA (reloc);
-      fixup_internal_substring (nonreloc, reloc, offset, &the_length);
-      the_nonreloc += offset;
-      if (!memchr (the_nonreloc, '*', the_length))
-	{
-	  for (i = 0;; i++)
-	    {
-	      const Ibyte *new_nonreloc = (const Ibyte *)
-		memchr (the_nonreloc, '-', the_length);
-	      if (!new_nonreloc)
-		break;
-	      new_nonreloc++;
-	      the_length -= new_nonreloc - the_nonreloc;
-	      the_nonreloc = new_nonreloc;
-	    }
-
-	  /* If it has less than 5 dashes, it's a short font.
-	     Of course, long fonts always have 14 dashes or so, but short
-	     fonts never have more than 1 or 2 dashes, so this is some
-	     sort of reasonable heuristic. */
-	  if (i < 5)
-	    return 1;
-	}
-    }
-
-  return (fast_string_match (XCHARSET_REGISTRY (charset),
-			     nonreloc, reloc, offset, length, 1,
-			     ERROR_ME, 0) >= 0);
-}
-
-#ifdef USE_XFT
-/* #### debug functions: find a better place for us */
-const char *FcResultToString (FcResult r);
-const char *
-FcResultToString (FcResult r)
-{
-  static char buffer[256];
-  switch (r)
-    {
-    case FcResultMatch:
-      return "FcResultMatch";
-    case FcResultNoMatch:
-      return "FcResultNoMatch";
-    case FcResultTypeMismatch:
-      return "FcResultTypeMismatch";
-    case FcResultNoId:
-      return "FcResultNoId";
-    default:
-      snprintf (buffer, 255, "FcResultUndocumentedValue (%d)", r);
-      return buffer;
-    }
-}
-
-const char *FcTypeOfValueToString (FcValue v);
-const char *
-FcTypeOfValueToString (FcValue v)
-{
-  static char buffer[256];
-  switch (v.type)
-    {
-    case FcTypeMatrix:
-      return "FcTypeMatrix";
-    case FcTypeString:
-      return "FcTypeString";
-    case FcTypeVoid:
-      return "FcTypeVoid";
-    case FcTypeDouble:
-      return "FcTypeDouble";
-    case FcTypeInteger:
-      return "FcTypeInteger";
-    case FcTypeBool:
-      return "FcTypeBool";
-    case FcTypeCharSet:
-      return "FcTypeCharSet";
-    case FcTypeLangSet:
-      return "FcTypeLangSet";
-    /* #### There is no union member of this type, but there are void* and
-       FcPattern* members, as of fontconfig.h FC_VERSION 10002 */
-    case FcTypeFTFace:
-      return "FcTypeFTFace";
-    default:
-      snprintf (buffer, 255, "FcTypeUndocumentedType (%d)", v.type);
-      return buffer;
-    }
-}
-
-static FcCharSet *
-mule_to_fc_charset (Lisp_Object cs)
-{
-  int ucode, i, j;
-  FcCharSet *fccs;
-
-  CHECK_CHARSET (cs);
-  fccs = FcCharSetCreate ();
-  /* #### do we also need to deal with 94 vs. 96 charsets?
-     ie, how are SP and DEL treated in ASCII?  non-graphic should return -1 */
-  if (1 == XCHARSET_DIMENSION (cs))
-    /* Unicode tables are indexed by offsets from ASCII SP, not by ASCII */
-    for (i = 0; i < 96; i++)
-      {
-	ucode = ((int *) XCHARSET_TO_UNICODE_TABLE (cs))[i];
-	if (ucode >= 0)
-	  /* #### should check for allocation failure */
-	  FcCharSetAddChar (fccs, (FcChar32) ucode);
-      }
-  else if (2 == XCHARSET_DIMENSION (cs))
-    /* Unicode tables are indexed by offsets from ASCII SP, not by ASCII */
-    for (i = 0; i < 96; i++)
-      for (j = 0; j < 96; j++)
-      {
-	ucode = ((int **) XCHARSET_TO_UNICODE_TABLE (cs))[i][j];
-	if (ucode >= 0)
-	  /* #### should check for allocation failure */
-	  FcCharSetAddChar (fccs, (FcChar32) ucode);
-      }
-  else
-    {
-      FcCharSetDestroy (fccs);
-      fccs = NULL;
-    }
-  return fccs;
-}
-
-struct charset_reporter {
-  Lisp_Object *charset;
-  /* This is a debug facility, require ASCII. */
-  Extbyte *language;		/* ASCII, please */
-  /* Technically this is FcChar8, but fsckin' GCC 4 bitches. */
-  Extbyte *rfc3066;		/* ASCII, please */
-};
-
-static struct charset_reporter charset_table[] =
-  {
-    /* #### It's my branch, my favorite charsets get checked first!
-       That's a joke, Son.
-       Ie, I don't know what I'm doing, so my charsets first is as good as
-       any other arbitrary order.  If you have a better idea, speak up! */
-    { &Vcharset_ascii, "English", "en" },
-    { &Vcharset_japanese_jisx0208, "Japanese", "ja" },
-    { &Vcharset_japanese_jisx0212, "Japanese", "ja" },
-    { &Vcharset_katakana_jisx0201, "Japanese", "ja" },
-    { &Vcharset_latin_jisx0201, "Japanese", "ja" },
-    { &Vcharset_japanese_jisx0208_1978, "Japanese", "ja" },
-    { &Vcharset_greek_iso8859_7, "Greek", "el" },
-    /* #### all the Chinese need checking
-       Damn the blood-sucking ISO anyway. */
-    { &Vcharset_chinese_gb2312, "simplified Chinese", "zh-CN" },
-    { &Vcharset_korean_ksc5601, "Korean", "ko" },
-    { &Vcharset_chinese_cns11643_1, "traditional Chinese", "zh-TW" },
-    { &Vcharset_chinese_cns11643_2, "traditional Chinese", "zh-TW" },
-    { &Vcharset_latin_iso8859_1, NULL, NULL },
-    { &Vcharset_latin_iso8859_2, NULL, NULL },
-    { &Vcharset_latin_iso8859_3, NULL, NULL },
-    { &Vcharset_latin_iso8859_4, NULL, NULL },
-    { &Vcharset_latin_iso8859_9, NULL, NULL },
-    { &Vcharset_latin_iso8859_15, NULL, NULL },
-    { &Vcharset_thai_tis620, NULL, NULL },
-    { &Vcharset_arabic_iso8859_6, NULL, NULL },
-    { &Vcharset_hebrew_iso8859_8, "Hebrew", "he" },
-    { &Vcharset_cyrillic_iso8859_5, NULL, NULL },
-    /* #### these probably are not quite right */
-    { &Vcharset_chinese_big5_1, "traditional Chinese", "zh-TW" },
-    { &Vcharset_chinese_big5_2, "traditional Chinese", "zh-TW" },
-    { NULL, NULL, NULL }
-  };
-
-/* Choose appropriate font name for debug messages.
-   Use only in the top half of next function (enforced with #undef). */
-#define DECLARE_DEBUG_FONTNAME(__xemacs_name)          \
-  Eistring *__xemacs_name;                             \
-  do                                                   \
-    {	       					       \
-      __xemacs_name = debug_xft > 2 ? eistr_fullname   \
-                      : debug_xft > 1 ? eistr_longname \
-                      : eistr_shortname;               \
-    } while (0)
-
-#endif /* USE_XFT */
-
-/* find a font spec that matches font spec FONT and also matches
-   (the registry of) CHARSET. */
-static Lisp_Object
-x_find_charset_font (Lisp_Object device, Lisp_Object font, Lisp_Object charset,
-		     int stage)
-{
-  Extbyte **names;
-  int count = 0;
-  const Extbyte *patternext;
-  Lisp_Object result = Qnil;
-  int i;
-
-  /* #### with Xft need to handle second stage here -- sjt
-     Hm.  Or maybe not.  That would be cool. :-) */
-  if (stage)
-    return Qnil;
-
-#ifdef USE_XFT
-  /* Fontconfig converts all FreeType names to UTF-8 before passing them
-     back to callers---see fcfreetype.c (FcFreeTypeQuery).
-     I don't believe this is documented.  */
-
-  DEBUG_XFT1 (1, "confirming charset for font instance %s\n", 
-	      XSTRING_DATA(font));
-
-  /* #### this looks like a fair amount of work, but the basic design
-     has never been rethought, and it should be
-
-     what really should happen here is that we use FcFontSort (FcFontList?)
-     to get a list of matching fonts, then pick the first (best) one that
-     gives language or repertoire coverage.
-  */
-
-  FcInit ();			/* No-op if already initialized.
-				   In fontconfig 2.3.2, this cannot return
-				   failure, but that looks like a bug.  We
-				   check for it with FcGetCurrentConfig(),
-				   which *can* fail. */
-  if (!FcConfigGetCurrent())	/* #### We should expose FcInit* interfaces
-				   to LISP and decide when to reinitialize
-				   intelligently. */
-    stderr_out ("Failed fontconfig initialization\n");
-  else
-    {
-      FcPattern *fontxft;	/* long-lived, freed at end of this block */
-      FcResult fcresult;
-      FcConfig *fcc;
-      FcChar8 *lang = (FcChar8 *) "en";	/* #### fix this bogus hack! */
-      FcCharSet *fccs = NULL;
-      DECLARE_EISTRING (eistr_shortname); /* user-friendly nickname */
-      DECLARE_EISTRING (eistr_longname);  /* omit FC_LANG and FC_CHARSET */
-      DECLARE_EISTRING (eistr_fullname);  /* everything */
-
-      LISP_STRING_TO_EXTERNAL (font, patternext, Qfc_font_name_encoding);
-      fcc = FcConfigGetCurrent ();
-
-      /* parse the name, do the substitutions, and match the font */
-
-      {
-	FcPattern *p = FcNameParse ((FcChar8 *) patternext);
-	PRINT_XFT_PATTERN (3, "FcNameParse'ed name is %s\n", p);
-	/* #### Next two return FcBool, but what does the return mean? */
-	/* The order is correct according the fontconfig docs. */
-	FcConfigSubstitute (fcc, p, FcMatchPattern);
-	PRINT_XFT_PATTERN (2, "FcConfigSubstitute'ed name is %s\n", p);
-	FcDefaultSubstitute (p);
-	PRINT_XFT_PATTERN (3, "FcDefaultSubstitute'ed name is %s\n", p);
-	/* #### check fcresult of following match? */
-	fontxft = FcFontMatch (fcc, p, &fcresult);
-	/* this prints the long fontconfig name */
-	PRINT_XFT_PATTERN (1, "FcFontMatch'ed name is %s\n", fontxft);
-	FcPatternDestroy (p);
-      }
-
-      /* heuristic to give reasonable-length names for debug reports
-
-         I considered #ifdef SUPPORT_FULL_FONTCONFIG_NAME etc but that's
-	 pointless.  We're just going to remove this code once the font/
-	 face refactoring is done, but until then it could be very useful.
-      */
-      {
-	FcPattern *p = FcFontRenderPrepare (fcc, fontxft, fontxft);
-	FcChar8 *name;
-
-	/* full name, including language coverage and repertoire */
-	name = FcNameUnparse (p);
-	eicpy_ext (eistr_fullname, (Extbyte *) name, Qfc_font_name_encoding);
-	free (name);
-
-	/* long name, omitting coverage and repertoire, plus a number
-	   of rarely useful properties */
-	FcPatternDel (p, FC_CHARSET);
-	FcPatternDel (p, FC_LANG);
-	FcPatternDel (p, FC_WIDTH);
-	FcPatternDel (p, FC_SPACING);
-	FcPatternDel (p, FC_HINTING);
-	FcPatternDel (p, FC_VERTICAL_LAYOUT);
-	FcPatternDel (p, FC_AUTOHINT);
-	FcPatternDel (p, FC_GLOBAL_ADVANCE);
-	FcPatternDel (p, FC_INDEX);
-	FcPatternDel (p, FC_SCALE);
-	FcPatternDel (p, FC_FONTVERSION);
-	name = FcNameUnparse (p);
-	eicpy_ext (eistr_longname, (Extbyte *) name, Qfc_font_name_encoding);
-	free (name);
-
-	/* nickname, just family and size, but
-	   "family" names usually have style, slant, and weight */
-	FcPatternDel (p, FC_FOUNDRY);
-	FcPatternDel (p, FC_STYLE);
-	FcPatternDel (p, FC_SLANT);
-	FcPatternDel (p, FC_WEIGHT);
-	FcPatternDel (p, FC_PIXEL_SIZE);
-	FcPatternDel (p, FC_OUTLINE);
-	FcPatternDel (p, FC_SCALABLE);
-	FcPatternDel (p, FC_DPI);
-	name = FcNameUnparse (p);
-	eicpy_ext (eistr_shortname, (Extbyte *) name, Qfc_font_name_encoding);
-	free (name);
-
-	FcPatternDestroy (p);
-      }
-
-      /* The language approach may better in the long run, but we can't use
-	 it based on Mule charsets; fontconfig doesn't provide a way to test
-	 for unions of languages, etc.  That will require support from the
-	 text module.
-
-	 Optimization:  cache the generated FcCharSet in the Mule charset.
-         Don't forget to destroy it if the Mule charset gets deallocated. */
-
-      {
-	/* This block possibly should be a function, but it generates
-	   multiple values.  I find the "pass an address to return the
-	   value in" idiom opaque, so prefer a block. */
-	struct charset_reporter *cr;
-	for (cr = charset_table;
-	     cr->charset && !EQ (*(cr->charset), charset);
-	     cr++)
-	  ;
-
-	if (cr->rfc3066)
-	  {
-	    DECLARE_DEBUG_FONTNAME (name);
-	    CHECKING_LANG (0, eidata(name), cr->language);
-	    lang = (FcChar8 *) cr->rfc3066;
-	  }
-	else if (cr->charset)
-	  {
-	    /* what the hey, build 'em on the fly */
-	    /* #### in the case of error this could return NULL! */
-	    fccs = mule_to_fc_charset (charset);
-	    lang = (FcChar8 *) XSTRING_DATA (XSYMBOL
-					     (XCHARSET_NAME (charset))-> name);
-	  }
-	else
-	  {
-	    /* OK, we fell off the end of the table */
-	    warn_when_safe_lispobj (intern ("xft"), intern ("alert"),
-				    list2 (build_string ("unchecked charset"),
-					   charset));
-	    /* default to "en"
-	       #### THIS IS WRONG, WRONG, WRONG!!
-	       It is why we never fall through to XLFD-checking. */
-	  }
-
-	ASSERT_ASCTEXT_ASCII((Extbyte *) lang);
-      }
-
-      if (fccs)
-	{
-	  /* check for character set coverage */
-	  int i = 0;
-	  FcCharSet *v;
-	  FcResult r = FcPatternGetCharSet (fontxft, FC_CHARSET, i, &v);
-
-	  if (r == FcResultTypeMismatch)
-	    {
-	      DEBUG_XFT0 (0, "Unexpected type return in charset value\n");
-	      result = Qnil;
-	    }
-	  else if (r == FcResultMatch && FcCharSetIsSubset (fccs, v))
-	    {
-	      /* The full pattern with the bitmap coverage is massively
-		 unwieldy, but the shorter names are's just *wrong*.  We
-		 should have the full thing internally as truename, and
-		 filter stuff the client doesn't want to see on output.
-		 Should we just store it into the truename right here? */
-	      DECLARE_DEBUG_FONTNAME (name);
-	      DEBUG_XFT2 (0, "Xft font %s supports %s\n",
-			  eidata(name), lang);
-#ifdef RETURN_LONG_FONTCONFIG_NAMES
-	      result = eimake_string(eistr_fullname);
-#else
-	      result = eimake_string(eistr_longname);
-#endif
-	    }
-	  else
-	    {
-	      DECLARE_DEBUG_FONTNAME (name);
-	      DEBUG_XFT2 (0, "Xft font %s doesn't support %s\n",
-			  eidata(name), lang);
-	      result = Qnil;
-	    }
-
-	  /* clean up */
-	  FcCharSetDestroy (fccs);
-	}
-      else
-	{
-	  /* check for language coverage */
-	  int i = 0;
-	  FcValue v;
-	  /* the main event */
-	  FcResult r = FcPatternGet (fontxft, FC_LANG, i, &v);
-
-	  if (r == FcResultMatch)
-	    {
-	      if (v.type != FcTypeLangSet) /* excessive paranoia */
-		{
-		  ASSERT_ASCTEXT_ASCII(FcTypeOfValueToString(v));
-		  /* Urk!  Fall back and punt to core font. */
-		  DEBUG_XFT1 (0, "Unexpected type of lang value (%s)\n",
-			       FcTypeOfValueToString (v));
-		  result = Qnil;
-		}
-	      else if (FcLangSetHasLang (v.u.l, lang) != FcLangDifferentLang)
-		{
-		  DECLARE_DEBUG_FONTNAME (name);
-		  DEBUG_XFT2 (0, "Xft font %s supports %s\n",
-			      eidata(name), lang);
-#ifdef RETURN_LONG_FONTCONFIG_NAMES
-		  result = eimake_string(eistr_fullname);
-#else
-		  result = eimake_string(eistr_longname);
-#endif
-		}
-	      else
-		{
-		  DECLARE_DEBUG_FONTNAME (name);
-		  DEBUG_XFT2 (0, "Xft font %s doesn't support %s\n",
-			      eidata(name), lang);
-		  result = Qnil;
-		}
-	    }
-	  else
-	    {
-	      ASSERT_ASCTEXT_ASCII(FcResultToString(r));
-	      DEBUG_XFT1 (0, "Getting lang: unexpected result=%s\n",
-			  FcResultToString (r));
-	      result = Qnil;
-	    }
-	}
-
-      /* clean up and maybe return */
-      FcPatternDestroy (fontxft);
-      if (!UNBOUNDP (result))
-	return result;
-    }
-
-  DEBUG_XFT1 (0, "shit happens, try X11 charset match for %s\n", 
-	      XSTRING_DATA(font));
-#undef DECLARE_DEBUG_FONTNAME
-#endif /* USE_XFT */
-
-  LISP_STRING_TO_EXTERNAL (font, patternext, Qx_font_name_encoding);
-  names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)),
-		      patternext, MAX_FONT_COUNT, &count);
-  /* #### This code seems awfully bogus -- mrb */
-  /* #### fontconfig does it better -- sjt */
-  for (i = 0; i < count; i ++)
-    {
-      const Ibyte *intname;
-      Bytecount intlen;
-
-      TO_INTERNAL_FORMAT (C_STRING, names[i],
-			  ALLOCA, (intname, intlen),
-			  Qx_font_name_encoding);
-      if (x_font_spec_matches_charset (XDEVICE (device), charset,
-				       intname, Qnil, 0, -1, 0))
-	{
-	  result = build_ext_string ((const Extbyte *) intname, 
-				     Qx_font_name_encoding); 
-	  break;
-	}
-    }
-
-  if (names)
-    XFreeFontNames (names);
-
-  /* Check for a short font name. */
-  if (NILP (result)
-      && x_font_spec_matches_charset (XDEVICE (device), charset, 0,
-				      font, 0, -1, 0))
-    return font;
-
-  return result;
-}
-
-#endif /* MULE */
+/* Include the charset support, shared, for the moment, with GTK.  */
+#define THIS_IS_X
+#include "objects-xlike-inc.c"
 
 
 /************************************************************************/
@@ -1512,6 +934,13 @@
 void
 vars_of_objects_x (void)
 {
+#ifdef DEBUG_XEMACS
+  DEFVAR_INT ("debug-x-objects", &debug_x_objects /*
+If non-zero, display debug information about X objects
+*/ );
+  debug_x_objects = 0;
+#endif
+
   DEFVAR_BOOL ("x-handle-non-fully-specified-fonts",
 	       &x_handle_non_fully_specified_fonts /*
 If this is true then fonts which do not have all characters specified