*** empty log message ***
[m17n/m17n-lib.git] / src / m17n-X.c
index 28a6c0e..5fdba28 100644 (file)
 #include "fontset.h"
 #include "face.h"
 
+typedef struct {
+  MFont core;
+  /* Nth bit tells the existence of a font of size (N+1).
+     core.property[MFONT_SIZE] holds the smallest size.  */
+  unsigned int sizes;
+  /* If sizes is not 0, smallest and largest sizes.  */
+  unsigned short smallest, largest;
+} MXFont;
+
+/* S must satisfy the condition (S > 0 && S <= 32).  */
+#define SET_SIZE(sizes, s) ((sizes) |= (1 << ((s) - 1)))
+#define HAVE_SIZE(sizes, s) ((sizes) & (1 << ((s) - 1)))
+
+typedef struct {
+  int size, inc, used;
+  MXFont *fonts;
+} MXFontList;
+
 typedef struct
 {
   /* Common header for the m17n object.  */
@@ -67,18 +85,19 @@ typedef struct
      be closed on freeing this structure.  */
   int auto_display;
 
-  /** List of available fonts on the display (except for iso8859-1 and
-      iso10646-1 fonts).  Keys are font registries, values are
-      (MFontList *).  */
-  MPlist *font_registry_list;
-
-  MPlist *iso8859_1_family_list;
+  /** List of available X-core fonts on the display.  Keys are
+      registries and values are plists whose keys are families and
+      values are pointers to MXFontList.  */
+  MPlist *font_list;
 
-  MPlist *iso10646_1_family_list;
+  /** List of available X-core fonts on the display.  Keys are
+      families and values are pointers to MFont.  For each MFont, only
+      these properties are important; FOUNDRY, FAMILY, REGISTRY.  */
+  MPlist *base_font_list;
 
-  /* List of information about each font.  Keys are font registries,
-     values are (MFontInfo *).  */
-  MPlist *realized_font_list;
+  /** Nonzero means that <font_list> already contains all available
+      fonts on the display.  */
+  int all_fonts_scaned;
 
  /** Modifier bit masks of the display.  */
   int meta_mask;
@@ -146,6 +165,10 @@ typedef struct
   /** List of pointers to realized faces on the frame.  */
   MPlist *realized_face_list;
 
+  /* List of information about each font.  Keys are font registries,
+     values are (MFontInfo *).  */
+  MPlist *realized_font_list;
+
   /** List of pointers to realized fontsets on the frame.  */
   MPlist *realized_fontset_list;
 
@@ -179,41 +202,18 @@ static void
 free_display_info (void *object)
 {
   MDisplayInfo *disp_info = (MDisplayInfo *) object;
-  MPlist *plist;
-
-  MPLIST_DO (plist, disp_info->font_registry_list)
-    {
-      MFontList *registry_list = MPLIST_VAL (plist);
-
-      if (registry_list->fonts)
-       free (registry_list->fonts);
-      free (registry_list);
-    }
-  M17N_OBJECT_UNREF (disp_info->font_registry_list);
-
-  MPLIST_DO (plist, disp_info->iso8859_1_family_list)
-    {
-      MFontList *family_list = MPLIST_VAL (plist);
+  MPlist *plist, *p;
 
-      if (family_list->fonts)
-       free (family_list->fonts);
-      free (family_list);
-    }
-  M17N_OBJECT_UNREF (disp_info->iso8859_1_family_list);
-
-  MPLIST_DO (plist, disp_info->iso10646_1_family_list)
+  MPLIST_DO (plist, disp_info->font_list)
     {
-      MFontList *family_list = MPLIST_VAL (plist);
-
-      if (family_list->fonts)
-       free (family_list->fonts);
-      free (family_list);
+      MPLIST_DO (p, MPLIST_VAL (plist))
+       free (MPLIST_VAL (p));
+      M17N_OBJECT_UNREF (MPLIST_VAL (plist));
     }
-  M17N_OBJECT_UNREF (disp_info->iso10646_1_family_list);
-
-  MPLIST_DO (plist, disp_info->realized_font_list)
-    mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist));
-  M17N_OBJECT_UNREF (disp_info->realized_font_list);
+  M17N_OBJECT_UNREF (disp_info->font_list);
+  MPLIST_DO (plist, disp_info->base_font_list)
+    free (MPLIST_VAL (plist));
+  M17N_OBJECT_UNREF (disp_info->base_font_list);
 
   if (disp_info->auto_display)
     XCloseDisplay (disp_info->display);
@@ -232,6 +232,10 @@ free_device (void *object)
     mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
   M17N_OBJECT_UNREF (device->realized_fontset_list);
 
+  MPLIST_DO (plist, device->realized_font_list)
+    mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist));
+  M17N_OBJECT_UNREF (device->realized_font_list);
+
   MPLIST_DO (plist, device->realized_face_list)
     {
       MRealizedFace *rface = MPLIST_VAL (plist);
@@ -428,138 +432,264 @@ static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
 static unsigned xfont_encode_char (MRealizedFont *, unsigned);
 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
                          MGlyph *, MGlyph *, int, MDrawRegion);
+static int xfont_list (MFrame *frame, MPlist *plist,
+                       MFont *font, MSymbol language, int maxnum);
+
 
 static MFontDriver xfont_driver =
   { xfont_select, xfont_open,
-    xfont_find_metric, xfont_encode_char, xfont_render };
+    xfont_find_metric, xfont_encode_char, xfont_render, xfont_list };
 
-typedef struct
+static int
+font_compare (const void *p1, const void *p2)
 {
-  M17NObject control;
-  Display *display;
-  XFontStruct *xfont;
-} MXFontInfo;
+  return strcmp (*(char **) p1, *(char **) p2);
+}
 
-static MFontList *
-build_font_list (MFrame *frame, MSymbol family, MSymbol registry,
-                MPlist *plist)
+static MPlist *
+xfont_registry_list (MFrame *frame, MSymbol registry)
 {
+  MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
+  MPlist *font_list = disp_info->font_list;
+  MPlist *base_font_list = disp_info->base_font_list;
+  MPlist *plist, *p;
   char pattern[1024];
-  MFontList *font_list;
-  char **fontnames;
+  char **font_names, **names;
   int nfonts;
   int i, j;
+  MXFont font;
+  MFont *bfont = NULL;
+
+  plist = mplist_get (font_list, registry);
+  if (plist)
+    return plist;
+  plist = mplist ();
+  mplist_add (font_list, registry, plist);
+  sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", msymbol_name (registry));
+  font_names = XListFonts (disp_info->display, pattern, 0x8000, &nfonts);
+  if (nfonts == 0)
+    return plist;
+  names = alloca (sizeof (char *) * nfonts);
+  memcpy (names, font_names, sizeof (char *) * nfonts);
+  qsort (names, nfonts, sizeof (char *), font_compare);
+  for (i = 0, p = NULL; i < nfonts; i++)
+    if (mfont__parse_name_into_font (names[i], Mx, (MFont *) &font) == 0
+       && (font.core.property[MFONT_SIZE] > 0
+           || font.core.property[MFONT_RESY] == 0))
+      {
+       MSymbol family = FONT_PROPERTY ((MFont *) &font, MFONT_FAMILY);
+       MXFontList *xfont_table;
+       int sizes[256];
+       int sizes_idx = 0;
+       int size, smallest, largest;
+       int have_scalable;
+       unsigned int size_bits = 0;
+       char *base_end;
+       int base_len;
+       int fields;
+       
+       if (p && MPLIST_KEY (p) != family)
+         p = mplist_find_by_key (plist, family);
+       if (p)
+         xfont_table = MPLIST_VAL (p);
+       else
+         {
+           p = plist;
+           MSTRUCT_MALLOC (xfont_table, MERROR_WIN);
+           MLIST_INIT1 (xfont_table, fonts, 4);
+           mplist_push (p, family, xfont_table);
+         }
 
-  MSTRUCT_CALLOC (font_list, MERROR_WIN);
+       /* Calculate how many bytes to compare to detect fonts of the
+          same base name.  */
+       for (base_end = names[i], fields = 0; *base_end; base_end++)
+         if (*base_end == '-'
+             && ++fields == 7  /* PIXEL_SIZE */)
+           break;
+       base_len = base_end - names[i] + 1;
+
+       size = font.core.property[MFONT_SIZE] / 10;
+       have_scalable = size == 0;
+       sizes[sizes_idx++] = size;
+       for (j = i + 1; j < nfonts && ! strncmp (names[i], names[j], base_len);
+            i = j++)
+         if (mfont__parse_name_into_font (names[j], Mx, (MFont *) &font) == 0
+             && (font.core.property[MFONT_SIZE] > 0
+                 || font.core.property[MFONT_RESY] == 0))
+           {
+             int k;
+
+             size = font.core.property[MFONT_SIZE] / 10;
+             if (! have_scalable)
+               have_scalable = size == 0;              
+             for (k = 0; k < sizes_idx && sizes[k] != size; k++);
+             if (k == sizes_idx && sizes_idx < 256)
+               sizes[sizes_idx++] = size;
+           }
 
-  if (family == Mnil)
-    {
-      sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s",
-              msymbol_name (registry));
-      font_list->tag = registry;
-    }
-  else
-    {
-      sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s",
-              msymbol_name (family), msymbol_name (registry));
-      font_list->tag = family;
-    }
+       for (j = 0, smallest = 0; j < sizes_idx; j++)
+         {
+           size = sizes[j];
+           if (size <= 32)
+             {
+               if (size != 0)
+                 {
+                   if (smallest == 0)
+                     smallest = largest = size;
+                   else if (size < smallest)
+                     smallest = size;
+                   else if (size > largest)
+                     largest = size;
+                   SET_SIZE (size_bits, size);
+                 }
+             }
+           else
+             {
+               font.core.property[MFONT_SIZE] = size * 10;
+               font.sizes = 0;
+               MLIST_APPEND1 (xfont_table, fonts, font, MERROR_WIN);
+             }
+         }
 
-  fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts);
-  if (nfonts > 0)
-    {
-      MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN);
-      for (i = j = 0; i < nfonts; i++)
-       if ((mfont__parse_name_into_font (fontnames[i], Mx,
-                                         font_list->fonts + j)
-            == 0)
-           && (font_list->fonts[j].property[MFONT_SIZE] != 0
-               || font_list->fonts[j].property[MFONT_RESY] == 0))
-         j++;
-      XFreeFontNames (fontnames);
-      font_list->nfonts = j;
-    }
-  mplist_add (plist, font_list->tag, font_list);
-  return (nfonts > 0 ? font_list : NULL);
+       if (size_bits || have_scalable == 1)
+         {
+           font.sizes = size_bits;
+           font.smallest = smallest;
+           font.largest = largest;
+           font.core.property[MFONT_SIZE] = have_scalable ? 0 : smallest * 10;
+           MLIST_APPEND1 (xfont_table, fonts, font, MERROR_WIN);
+         }
+       if (! bfont
+           || (font.core.property[MFONT_FOUNDRY]
+               != bfont->property[MFONT_FOUNDRY])
+           || (font.core.property[MFONT_FAMILY]
+               != bfont->property[MFONT_FAMILY]))
+         {
+           MSTRUCT_MALLOC (bfont, MERROR_WIN);
+           *bfont = font.core;
+           for (j = MFONT_WEIGHT; j <= MFONT_ADSTYLE; j++)
+             bfont->property[j] = 0;
+           bfont->property[MFONT_SIZE] = bfont->property[MFONT_RESY] = 0;
+           mplist_push (base_font_list, family, bfont);
+         }
+      }
+  XFreeFontNames (font_names);
+  return plist;
+}
+
+static void
+xfont_list_all (MFrame *frame)
+{
+  MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
+  MPlist *font_encoding_list, *p;
+
+  if (disp_info->all_fonts_scaned)
+    return;
+  disp_info->all_fonts_scaned = 1;
+  font_encoding_list = mfont__encoding_list ();
+  if (! font_encoding_list)
+    return;
+  MPLIST_DO (p, font_encoding_list)
+    xfont_registry_list (frame, MPLIST_KEY (p));
 }
 
+
+typedef struct
+{
+  M17NObject control;
+  Display *display;
+  XFontStruct *xfont;
+} MXFontInfo;
+
 /* The X font driver function SELECT.  */
 
 static MRealizedFont *
 xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size)
 {
+  MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY);
   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
+  int requested_size = request->property[MFONT_SIZE] / 10;
   MRealizedFont *rfont;
-  MFontList *font_list = NULL;
+  MPlist *plist;
   int i;
   MFont *best_font;
-  int best_score, score;
+  int best_size, best_score, score;
 
   if (registry == Mnil
       || ! strchr (MSYMBOL_NAME (registry), '-'))
     return NULL;
 
-  /* We handles iso8859-1 and iso10646-1 fonts specially because there
-     exists so many such fonts.  */
-  if (registry == M_iso8859_1 || registry == M_iso10646_1)
-    {
-      MPlist *family_list
-       = (registry == M_iso8859_1
-          ? FRAME_DEVICE (frame)->display_info->iso8859_1_family_list
-          : FRAME_DEVICE (frame)->display_info->iso10646_1_family_list);
-      MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY);
-
-      if (family != Mnil)
-       {
-         font_list = (MFontList *) mplist_get (family_list, family);
-         if (! font_list)
-           font_list = build_font_list (frame, family, registry, family_list);
-       }
-      if (! font_list)
-       {
-         family = FONT_PROPERTY (request, MFONT_FAMILY);
-         font_list = (MFontList *) mplist_get (family_list, family);
-         if (! font_list)
-           font_list = build_font_list (frame, family, registry, family_list);
-       }
-    }
-  if (! font_list)
-    {
-      MPlist *registry_list
-       = FRAME_DEVICE (frame)->display_info->font_registry_list;
-
-      font_list = (MFontList *) mplist_get (registry_list, registry);
-      if (! font_list)
-       font_list = build_font_list (frame, Mnil, registry, registry_list);
-    }
-  if (! font_list)
-    return NULL;
-
-  for (i = 0, best_score = -1, best_font = NULL; i < font_list->nfonts; i++)
-    if ((best_score = mfont__score (font_list->fonts + i, spec, request,
-                                   limited_size)) >= 0)
-      break;
-  if (best_score < 0)
+  plist = xfont_registry_list (frame, registry);
+  if (MPLIST_TAIL_P (plist))
     return NULL;
-  best_font = font_list->fonts + i;
-  for (; best_score > 0 && i < font_list->nfonts ; i++)
+  best_score = -1, best_font = NULL;
+  MPLIST_DO (plist, plist)
     {
-      score = mfont__score (font_list->fonts + i, spec, request,
-                           limited_size);
-      if (score >= 0 && score < best_score)
+      if (family == Mnil || family == MPLIST_KEY (plist))
        {
-         best_font = font_list->fonts + i;
-         best_score = score;
+         MXFontList *xfont_table = MPLIST_VAL (plist);
+
+         for (i = 0; i < xfont_table->used; i++)
+           {
+             MXFont *xfont = xfont_table->fonts + i;
+             MFont *font = (MFont *) xfont;
+             unsigned int sizes = xfont->sizes;
+             int orig_size = font->property[MFONT_SIZE];
+             int size;
+
+             if (sizes == 0)
+               size = orig_size / 10;
+             else if (requested_size < xfont->smallest)
+               size = orig_size == 0 ? 0 : xfont->smallest;
+             else if (requested_size > xfont->largest)
+               size = orig_size == 0 ? 0 : xfont->largest;
+             else if (HAVE_SIZE (sizes, requested_size))
+               size = requested_size;
+             else if (orig_size == 0)
+               size = 0;
+             else
+               {
+                 for (size = requested_size - 1;
+                      size > xfont->smallest && ! HAVE_SIZE (sizes, size);
+                      size--);
+                 if (! limited_size)
+                   {
+                     int s;
+                     for (s = requested_size;
+                          s < xfont->largest && ! HAVE_SIZE (sizes, s);
+                          s++);
+                     if (s - requested_size < requested_size - size)
+                       size = s;
+                   }
+               }
+             font->property[MFONT_SIZE] = size * 10;
+             score = mfont__score (font, spec, request, limited_size);
+             font->property[MFONT_SIZE] = orig_size;
+             if (score >= 0 && (best_score < 0 || score < best_score))
+               {
+                 best_size = size * 10;
+                 best_score = score;
+                 best_font = (MFont *) (xfont_table->fonts + i);
+                 if (best_score == 0)
+                   break;
+               }
+           }
+         if (best_score == 0)
+           break;
        }
     }
+  if (! best_font)
+    return NULL;
 
   MSTRUCT_CALLOC (rfont, MERROR_WIN);
   rfont->frame = frame;
   rfont->spec = *spec;
   rfont->request = *request;
   rfont->font = *best_font;
-  if (best_font->property[MFONT_SIZE] == 0)
+  if (best_size == 0)
     rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE];
+  else
+    rfont->font.property[MFONT_SIZE] = best_size;
   rfont->score = best_score;
   return rfont;
 }
@@ -607,6 +737,8 @@ xfont_open (MRealizedFont *rfont)
   rfont->status = 1;
   rfont->ascent = xfont_info->xfont->ascent;
   rfont->descent = xfont_info->xfont->descent;
+  rfont->type = Mx;
+  rfont->fontp = xfont_info->xfont;
   return 0;
 }
 
@@ -823,6 +955,78 @@ xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
     }
 }
 
+static int
+xfont_list (MFrame *frame, MPlist *plist, MFont *font, MSymbol language,
+           int maxnum)
+{
+  MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
+  MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil;
+  MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil;
+  MPlist *p, *pl;
+  int num = 0;
+
+  if (registry != Mnil)
+    xfont_registry_list (frame, registry);
+  else
+    xfont_list_all (frame);
+
+  /* As we have not yet implemented the language check, return all
+     base fonts.  */
+  if (! font)
+    MPLIST_DO (p, disp_info->base_font_list)
+      {
+       mplist_add (plist, MPLIST_KEY (p), MPLIST_VAL (p));
+       num++;
+       if (num == maxnum)
+         return num;
+      }
+  else
+    {
+      MXFontList *xfontlist;
+      MXFont *xfont;
+      int i;
+
+      pl = disp_info->font_list;
+      if (registry != Mnil)
+       {
+         pl = mplist_find_by_key (pl, registry);
+         if (! pl)
+           return 0;
+       }
+
+      MPLIST_DO (pl, pl)
+       {
+         p = MPLIST_VAL (pl);
+         if (family != Mnil)
+           {
+             p = mplist_find_by_key (p, family);
+             if (! p)
+               return 0;
+           }
+         MPLIST_DO (p, p)
+           {
+             xfontlist = MPLIST_VAL (p);
+             for (i = 0; i < xfontlist->used; i++)
+               {
+                 xfont = xfontlist->fonts + i;
+                 if (mfont__match_p (&xfont->core, font, MFONT_REGISTRY))
+                   {
+                     mplist_add (plist, MPLIST_KEY (p), &xfont->core);
+                     num++;
+                     if (num == maxnum)
+                       return num;
+                   }
+               }
+             if (family != Mnil)
+               break;
+           }
+         if (registry != Mnil)
+           break;
+       }
+    }
+  return num;
+}
+
 \f
 /* Xft Handler */
 
@@ -842,10 +1046,12 @@ static void xft_render (MDrawWindow, int, int, MGlyphString *,
                        MGlyph *, MGlyph *, int, MDrawRegion);
 
 MFontDriver xft_driver =
-  { NULL,                      /* Set to ft_select in mwin__init (). */
+  { NULL,                      /* Set to ft_select in device_init (). */
     xft_open, xft_find_metric,
-    NULL,                      /* Set to ft_encode_char in mwin__init (). */
-    xft_render };
+    NULL,                      /* Set to ft_encode_char in device_init (). */
+    xft_render,
+    NULL                       /* Set to ft_list in device_init (). */
+  };
 
 
 static void
@@ -902,7 +1108,11 @@ xft_open (MRealizedFont *rfont)
     {
       font_info->font_no_aa = xft_open_font (frame, ft_info, size, 0);
       if (font_info->font_no_aa)
-       return 0;
+       {
+         rfont->type = Mxft;
+         rfont->fontp = font_info->font_no_aa;
+         return 0;
+       }
       XftFontClose (FRAME_DISPLAY (rfont->frame), font_info->font_aa);
     }
   free (font_info);  
@@ -935,7 +1145,7 @@ xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
        {
          XGlyphInfo extents;
 
-         XftGlyphExtents (FRAME_DISPLAY (rfont->frame),
+         XftGlyphExtents (FRAME_DISPLAY (gstring->frame),
                           font_info->font_aa, &g->code, 1, &extents);
          g->lbearing = - extents.x;
          g->rbearing = extents.width - extents.x;
@@ -977,7 +1187,7 @@ xft_render (MDrawWindow win, int x, int y,
   glyphs = alloca (sizeof (FT_UInt) * (to - from));
   for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
     {
-      if (g->xoff == 0 && g->yoff == 0)
+      if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
        glyphs[nglyphs++] = g->code;
       else
        {
@@ -999,327 +1209,63 @@ xft_render (MDrawWindow win, int x, int y,
 \f
 /* Functions for the device driver.  */
 
-static int
-mwin__device_init ()
+static void
+mwin__close_device (MFrame *frame)
 {
-  M_iso8859_1 = msymbol ("iso8859-1");
-  M_iso10646_1 = msymbol ("iso10646-1");
-
-  display_info_list = mplist ();
-  device_list = mplist ();
-
-  Mxim = msymbol ("xim");
-  msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
+  MWDevice *device = FRAME_DEVICE (frame);
 
-  return 0;
+  M17N_OBJECT_UNREF (device);
 }
 
-static int
-mwin__device_fini ()
+static void *
+mwin__device_get_prop (MFrame *frame, MSymbol key)
 {
-  M17N_OBJECT_UNREF (display_info_list);
-  M17N_OBJECT_UNREF (device_list);
-  return 0;
-}
-
-/** Return an MWDevice object corresponding to a display specified in
-    PLIST.
+  MWDevice *device = FRAME_DEVICE (frame);
 
-    It searches device_list for a device matching the display.  If
-    found, return the found object.  Otherwise, return a newly created
-    object.  */
+  if (key == Mdisplay)
+    return (void *) device->display_info->display;
+  if (key == Mscreen)
+    return (void *) ScreenOfDisplay(device->display_info->display,
+                                   device->screen_num);
+  if (key == Mcolormap)
+    return (void *) device->cmap;
+  if (key == Mdepth)
+    return (void *) device->depth;
+  return NULL;
+}
 
-static int
-mwin__open_device (MFrame *frame, MPlist *param)
+static void
+mwin__realize_face (MRealizedFace *rface)
 {
-  Display *display = NULL;
-  Screen *screen = NULL;
-  int screen_num;
-  Drawable drawable = 0;
-  Widget widget = NULL;
-  Colormap cmap = 0;
-  int auto_display = 0;
-  MDisplayInfo *disp_info = NULL;
-  MWDevice *device = NULL;
-  MSymbol key;
-  XWindowAttributes attr;
-  unsigned depth = 0;
-  MPlist *plist;
-  AppData app_data;
-  MFace *face;
+  MFrame *frame;
+  MSymbol foreground, background, videomode;
+  MFaceHLineProp *hline;
+  MFaceBoxProp *box;
+  GCInfo *info;
 
-  for (plist = param; (key = mplist_key (plist)) != Mnil;
-       plist = mplist_next (plist))
+  if (rface != rface->ascii_rface)
     {
-      if (key == Mdisplay)
-       display = (Display *) mplist_value (plist);
-      else if (key == Mscreen)
-       screen = mplist_value (plist);
-      else if (key == Mdrawable)
-       drawable = (Drawable) mplist_value (plist);
-      else if (key == Mdepth)
-       depth = (unsigned) mplist_value (plist);
-      else if (key == Mwidget)
-       widget = (Widget) mplist_value (plist);
-      else if (key == Mcolormap)
-       cmap = (Colormap) mplist_value (plist);
+      rface->info = rface->ascii_rface->info;
+      return;
     }
 
-  if (widget)
-    {
-      display = XtDisplay (widget);
-      screen_num = XScreenNumberOfScreen (XtScreen (widget));
-      depth = DefaultDepth (display, screen_num);
-    }
-  else if (drawable)
-    {
-      Window root_window;
-      int x, y;
-      unsigned width, height, border_width;
+  frame = rface->frame;
+  MSTRUCT_CALLOC (info, MERROR_WIN);
 
-      if (! display)
-       MERROR (MERROR_WIN, -1);
-      XGetGeometry (display, drawable, &root_window,
-                   &x, &y, &width, &height, &border_width, &depth);
-      XGetWindowAttributes (display, root_window, &attr);
-      screen_num = XScreenNumberOfScreen (attr.screen);
+  foreground = rface->face.property[MFACE_FOREGROUND];
+  background = rface->face.property[MFACE_BACKGROUND];
+  videomode = rface->face.property[MFACE_VIDEOMODE];
+  if (! videomode)
+    videomode = frame->videomode;
+  if (videomode != Mreverse)
+    {
+      info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
+      info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
     }
   else
     {
-      if (screen)
-       display = DisplayOfScreen (screen);
-      else
-       {
-         if (! display)
-           {
-             display = XOpenDisplay (NULL);
-             if (! display)
-               MERROR (MERROR_WIN, -1);
-             auto_display = 1;
-           }
-         screen = DefaultScreenOfDisplay (display);
-       }
-      screen_num = XScreenNumberOfScreen (screen);
-      if (! depth)
-       depth = DefaultDepth (display, screen_num);
-    }
-
-  if (! cmap)
-    cmap = DefaultColormap (display, screen_num);
-
-  for (plist = display_info_list; mplist_key (plist) != Mnil;
-       plist = mplist_next (plist))
-    {
-      disp_info = (MDisplayInfo *) mplist_value (plist);
-      if (disp_info->display == display)
-       break;
-    }
-
-  if (mplist_key (plist) != Mnil)
-    M17N_OBJECT_REF (disp_info);
-  else
-    {
-      M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
-      disp_info->display = display;
-      disp_info->auto_display = auto_display;
-      disp_info->font_registry_list = mplist ();
-      disp_info->iso8859_1_family_list = mplist ();
-      disp_info->iso10646_1_family_list = mplist ();
-      disp_info->realized_font_list = mplist ();
-      find_modifier_bits (disp_info);
-      mplist_add (display_info_list, Mt, disp_info);
-    }  
-
-  for (plist = device_list; mplist_key (plist) != Mnil;
-       plist = mplist_next (plist))
-    {
-      device = (MWDevice *) mplist_value (plist);
-      if (device->display_info == disp_info
-         && device->depth == depth
-         && device->cmap == cmap)
-       break;
-    }
-
-  if (mplist_key (plist) != Mnil)
-    M17N_OBJECT_REF (device);
-  else
-    {
-      unsigned long valuemask = GCForeground;
-      XGCValues values;
-
-      M17N_OBJECT (device, free_device, MERROR_WIN);
-      device->display_info = disp_info;
-      device->screen_num = screen_num;
-      /* A drawable on which to create GCs.  */
-      device->drawable = XCreatePixmap (display,
-                                       RootWindow (display, screen_num),
-                                       1, 1, depth);
-      device->depth = depth;
-      device->cmap = cmap;
-      device->realized_face_list = mplist ();
-      device->realized_fontset_list = mplist ();
-      device->gc_list = mplist ();
-      values.foreground = BlackPixel (display, screen_num);
-      device->scratch_gc = XCreateGC (display, device->drawable,
-                                     valuemask, &values);
-#ifdef HAVE_XFT2
-      device->xft_draw = XftDrawCreate (display, device->drawable,
-                                       DefaultVisual (display, screen_num),
-                                       cmap);
-#endif
-    }
-
-  frame->device = device;
-  frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
-  frame->font_driver_list = mplist ();
-  mplist_add (frame->font_driver_list, Mx, &xfont_driver);
-#ifdef HAVE_XFT2
-  mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
-#elif HAVE_FREETYPE
-  mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
-#endif
-  frame->realized_font_list = disp_info->realized_font_list;
-  frame->realized_face_list = device->realized_face_list;
-  frame->realized_fontset_list = device->realized_fontset_list;
-
-  if (widget)
-    {
-      XtResource resources[] = {
-       { XtNfont, XtCFont, XtRString, sizeof (String),
-         XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
-       { XtNforeground, XtCForeground, XtRString, sizeof (String),
-         XtOffset (AppDataPtr, foreground), XtRString, "black" },
-       { XtNbackground, XtCBackground, XtRString, sizeof (String),
-         XtOffset (AppDataPtr, background), XtRString, "white" },
-       { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
-         XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
-      };
-
-      XtGetApplicationResources (widget, &app_data,
-                                resources, XtNumber (resources), NULL, 0);
-      frame->foreground = msymbol (app_data.foreground);
-      frame->background = msymbol (app_data.background);
-      frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
-    }
-  else
-    {
-      app_data.font = DEFAULT_FONT;
-      frame->foreground = msymbol ("black");
-      frame->background = msymbol ("white");
-      frame->videomode = Mnormal;
-    }
-
-  {
-    int nfonts;
-    char **names = XListFonts (display, app_data.font, 1, &nfonts);
-
-    if (nfonts > 0)
-      {
-       if (! (frame->font = mfont_parse_name (names[0], Mx)))
-         {
-           /* The font name does not conform to XLFD.  Try to open the
-              font and get XA_FONT property.  */
-           XFontStruct *xfont = XLoadQueryFont (display, names[0]);
-
-           nfonts = 0;
-           if (xfont)
-             {
-               unsigned long value;
-               char *name;
-
-               if (XGetFontProperty (xfont, XA_FONT, &value)
-                   && (name = ((char *)
-                               XGetAtomName (display, (Atom) value))))
-                 {
-                   if ((frame->font = mfont_parse_name (name, Mx)))
-                     nfonts = 1;
-                 }
-               XFreeFont (display, xfont);
-             }
-         }
-       XFreeFontNames (names);
-      }
-    if (! nfonts)
-      frame->font = mfont_parse_name (FALLBACK_FONT, Mx);
-  }
-
-  face = mface_from_font (frame->font);
-  face->property[MFACE_FONTSET] = mfontset (NULL);
-  face->property[MFACE_FOREGROUND] = frame->foreground;
-  face->property[MFACE_BACKGROUND] = frame->background;
-  mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
-  mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
-  face->property[MFACE_VIDEOMODE] = frame->videomode;
-  mface_put_prop (face, Mhook_func, 
-                 mface_get_prop (mface__default, Mhook_func));
-  face->property[MFACE_RATIO] = (void *) 100;
-  mplist_push (param, Mface, face);
-  M17N_OBJECT_UNREF (face);
-
-#ifdef X_SET_ERROR_HANDLER
-  XSetErrorHandler (x_error_handler);
-  XSetIOErrorHandler (x_io_error_handler);
-#endif
-
-  return 0;
-}
-
-
-static void
-mwin__close_device (MFrame *frame)
-{
-  M17N_OBJECT_UNREF (FRAME_DEVICE (frame));
-}
-
-static void *
-mwin__device_get_prop (MFrame *frame, MSymbol key)
-{
-  MWDevice *device = FRAME_DEVICE (frame);
-
-  if (key == Mdisplay)
-    return (void *) device->display_info->display;
-  if (key == Mscreen)
-    return (void *) ScreenOfDisplay(device->display_info->display,
-                                   device->screen_num);
-  if (key == Mcolormap)
-    return (void *) device->cmap;
-  if (key == Mdepth)
-    return (void *) device->depth;
-  return NULL;
-}
-
-static void
-mwin__realize_face (MRealizedFace *rface)
-{
-  MFrame *frame;
-  MSymbol foreground, background, videomode;
-  MFaceHLineProp *hline;
-  MFaceBoxProp *box;
-  GCInfo *info;
-
-  if (rface != rface->ascii_rface)
-    {
-      rface->info = rface->ascii_rface->info;
-      return;
-    }
-
-  frame = rface->frame;
-  MSTRUCT_CALLOC (info, MERROR_WIN);
-
-  foreground = rface->face.property[MFACE_FOREGROUND];
-  background = rface->face.property[MFACE_BACKGROUND];
-  videomode = rface->face.property[MFACE_VIDEOMODE];
-  if (! videomode)
-    videomode = frame->videomode;
-  if (videomode != Mreverse)
-    {
-      info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
-      info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
-    }
-  else
-    {
-      info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
-      info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
+      info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
+      info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
     }
 #ifdef HAVE_XFT2
   if (foreground == Mnil)
@@ -1853,7 +1799,7 @@ mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
   int len;
   char buf[512];
   KeySym keysym;
-  MSymbol key;
+  MSymbol key = Mnil;
 
   *modifiers = 0;
   if (event->xany.type != KeyPress
@@ -1882,7 +1828,7 @@ mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
     }
   else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
     return Mnil;
-  else
+  if (key == Mnil)
     {
       char *str = XKeysymToString (keysym);
 
@@ -1927,10 +1873,6 @@ mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
 
 static MDeviceDriver x_driver =
   {
-    0,
-    mwin__device_init,
-    mwin__device_fini,
-    mwin__open_device,
     mwin__close_device,
     mwin__device_get_prop,
     mwin__realize_face,
@@ -1956,6 +1898,312 @@ static MDeviceDriver x_driver =
     mwin__parse_event
   };
 
+/* Functions to be stored in MDeviceLibraryInterface by dlsym ().  */
+
+int
+device_init ()
+{
+  M_iso8859_1 = msymbol ("iso8859-1");
+  M_iso10646_1 = msymbol ("iso10646-1");
+
+  display_info_list = mplist ();
+  device_list = mplist ();
+
+#ifdef HAVE_XFT2
+  xft_driver.select = mfont__ft_driver.select;
+  xft_driver.encode_char = mfont__ft_driver.encode_char;
+  xft_driver.list = mfont__ft_driver.list;
+#endif
+
+  Mxim = msymbol ("xim");
+  msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
+
+  return 0;
+}
+
+int
+device_fini ()
+{
+  M17N_OBJECT_UNREF (display_info_list);
+  M17N_OBJECT_UNREF (device_list);
+  return 0;
+}
+
+/** Return an MWDevice object corresponding to a display specified in
+    PLIST.
+
+    It searches device_list for a device matching the display.  If
+    found, return the found object.  Otherwise, return a newly created
+    object.  */
+
+int
+device_open (MFrame *frame, MPlist *param)
+{
+  Display *display = NULL;
+  Screen *screen = NULL;
+  int screen_num;
+  Drawable drawable = 0;
+  Widget widget = NULL;
+  Colormap cmap = 0;
+  int auto_display = 0;
+  MDisplayInfo *disp_info = NULL;
+  MWDevice *device = NULL;
+  MSymbol key;
+  XWindowAttributes attr;
+  unsigned depth = 0;
+  MPlist *plist;
+  AppData app_data;
+  MFace *face;
+  int use_xfont = 0, use_freetype = 0, use_xft = 0;
+
+  for (plist = param; (key = mplist_key (plist)) != Mnil;
+       plist = mplist_next (plist))
+    {
+      if (key == Mdisplay)
+       display = (Display *) mplist_value (plist);
+      else if (key == Mscreen)
+       screen = mplist_value (plist);
+      else if (key == Mdrawable)
+       drawable = (Drawable) mplist_value (plist);
+      else if (key == Mdepth)
+       depth = (unsigned) mplist_value (plist);
+      else if (key == Mwidget)
+       widget = (Widget) mplist_value (plist);
+      else if (key == Mcolormap)
+       cmap = (Colormap) mplist_value (plist);
+      else if (key == Mfont)
+       {
+         MSymbol val = MPLIST_SYMBOL (plist);
+
+         if (val == Mx)
+           use_xfont = 1;
+#ifdef HAVE_FREETYPE
+         else if (val == Mfreetype)
+           use_freetype = 1;
+#ifdef HAVE_XFT2
+         else if (val == Mxft)
+           use_xft = 1;
+#endif
+#endif
+       }
+    }
+
+  /* If none of them is specified, use all of them.  */
+  if (! use_xfont && ! use_freetype && ! use_xft)
+    use_xfont = use_freetype = use_xft = 1;
+
+  if (widget)
+    {
+      display = XtDisplay (widget);
+      screen_num = XScreenNumberOfScreen (XtScreen (widget));
+      depth = DefaultDepth (display, screen_num);
+    }
+  else if (drawable)
+    {
+      Window root_window;
+      int x, y;
+      unsigned width, height, border_width;
+
+      if (! display)
+       MERROR (MERROR_WIN, -1);
+      XGetGeometry (display, drawable, &root_window,
+                   &x, &y, &width, &height, &border_width, &depth);
+      XGetWindowAttributes (display, root_window, &attr);
+      screen_num = XScreenNumberOfScreen (attr.screen);
+    }
+  else
+    {
+      if (screen)
+       display = DisplayOfScreen (screen);
+      else
+       {
+         if (! display)
+           {
+             display = XOpenDisplay (NULL);
+             if (! display)
+               MERROR (MERROR_WIN, -1);
+             auto_display = 1;
+           }
+         screen = DefaultScreenOfDisplay (display);
+       }
+      screen_num = XScreenNumberOfScreen (screen);
+      if (! depth)
+       depth = DefaultDepth (display, screen_num);
+    }
+
+  if (! cmap)
+    cmap = DefaultColormap (display, screen_num);
+
+  for (plist = display_info_list; mplist_key (plist) != Mnil;
+       plist = mplist_next (plist))
+    {
+      disp_info = (MDisplayInfo *) mplist_value (plist);
+      if (disp_info->display == display)
+       break;
+    }
+
+  if (mplist_key (plist) != Mnil)
+    M17N_OBJECT_REF (disp_info);
+  else
+    {
+      M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
+      disp_info->display = display;
+      disp_info->auto_display = auto_display;
+      disp_info->font_list = mplist ();
+      disp_info->base_font_list = mplist ();
+      find_modifier_bits (disp_info);
+      mplist_add (display_info_list, Mt, disp_info);
+    }  
+
+  for (plist = device_list; mplist_key (plist) != Mnil;
+       plist = mplist_next (plist))
+    {
+      device = (MWDevice *) mplist_value (plist);
+      if (device->display_info == disp_info
+         && device->depth == depth
+         && device->cmap == cmap)
+       break;
+    }
+
+  if (mplist_key (plist) != Mnil)
+    M17N_OBJECT_REF (device);
+  else
+    {
+      unsigned long valuemask = GCForeground;
+      XGCValues values;
+
+      M17N_OBJECT (device, free_device, MERROR_WIN);
+      device->display_info = disp_info;
+      device->screen_num = screen_num;
+      /* A drawable on which to create GCs.  */
+      device->drawable = XCreatePixmap (display,
+                                       RootWindow (display, screen_num),
+                                       1, 1, depth);
+      device->depth = depth;
+      device->cmap = cmap;
+      device->realized_face_list = mplist ();
+      device->realized_font_list = mplist ();
+      device->realized_fontset_list = mplist ();
+      device->gc_list = mplist ();
+      values.foreground = BlackPixel (display, screen_num);
+      device->scratch_gc = XCreateGC (display, device->drawable,
+                                     valuemask, &values);
+#ifdef HAVE_XFT2
+      device->xft_draw = XftDrawCreate (display, device->drawable,
+                                       DefaultVisual (display, screen_num),
+                                       cmap);
+#endif
+    }
+
+  frame->device = device;
+  frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
+  frame->driver = &x_driver;
+  frame->font_driver_list = mplist ();
+#ifdef HAVE_XFT2
+  if (use_xft)
+    {
+      mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
+      use_freetype = 0;
+    }
+#endif /* HAVE_XFT2 */
+#ifdef HAVE_FREETYPE
+  if (use_freetype)
+    mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
+#endif /* HAVE_FREETYPE */
+  if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
+    mplist_push (frame->font_driver_list, Mx, &xfont_driver);
+
+  frame->realized_font_list = device->realized_font_list;
+  frame->realized_face_list = device->realized_face_list;
+  frame->realized_fontset_list = device->realized_fontset_list;
+
+  if (widget)
+    {
+      XtResource resources[] = {
+       { XtNfont, XtCFont, XtRString, sizeof (String),
+         XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
+       { XtNforeground, XtCForeground, XtRString, sizeof (String),
+         XtOffset (AppDataPtr, foreground), XtRString, "black" },
+       { XtNbackground, XtCBackground, XtRString, sizeof (String),
+         XtOffset (AppDataPtr, background), XtRString, "white" },
+       { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
+         XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
+      };
+
+      XtGetApplicationResources (widget, &app_data,
+                                resources, XtNumber (resources), NULL, 0);
+      frame->foreground = msymbol (app_data.foreground);
+      frame->background = msymbol (app_data.background);
+      frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
+    }
+  else
+    {
+      app_data.font = DEFAULT_FONT;
+      frame->foreground = msymbol ("black");
+      frame->background = msymbol ("white");
+      frame->videomode = Mnormal;
+    }
+
+  {
+    int nfonts, i;
+    /* Try at least 32 fonts to obtain a non-autoscaled font.  */
+    char **names = XListFonts (display, app_data.font, 32, &nfonts);
+    MFont *font = NULL;
+
+    for (i = 0; ! font && i < nfonts; i++)
+      {
+       font = mfont_parse_name (names[i], Mx);
+       if (!font)
+         {
+           /* The font name does not conform to XLFD.  Try to open the
+              font and get XA_FONT property.  */
+           XFontStruct *xfont = XLoadQueryFont (display, names[i]);
+
+           if (xfont)
+             {
+               unsigned long value;
+               char *name;
+
+               if (XGetFontProperty (xfont, XA_FONT, &value)
+                   && (name = ((char *)
+                               XGetAtomName (display, (Atom) value))))
+                 font = mfont_parse_name (name, Mx);
+               XFreeFont (display, xfont);
+             }
+         }
+       if (font &&
+           font->property[MFONT_SIZE] == 0 && font->property[MFONT_RESY] > 0)
+         {
+           free (font);
+           font = NULL;
+         }
+      }
+    if (nfonts)
+      XFreeFontNames (names);
+    frame->font = font ? font : mfont_parse_name (FALLBACK_FONT, Mx);
+  }
+
+  face = mface_from_font (frame->font);
+  face->property[MFACE_FONTSET] = mfontset (NULL);
+  face->property[MFACE_FOREGROUND] = frame->foreground;
+  face->property[MFACE_BACKGROUND] = frame->background;
+  mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
+  mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
+  face->property[MFACE_VIDEOMODE] = frame->videomode;
+  mface_put_prop (face, Mhook_func, 
+                 mface_get_prop (mface__default, Mhook_func));
+  face->property[MFACE_RATIO] = (void *) 100;
+  mplist_push (param, Mface, face);
+  M17N_OBJECT_UNREF (face);
+
+#ifdef X_SET_ERROR_HANDLER
+  XSetErrorHandler (x_error_handler);
+  XSetIOErrorHandler (x_io_error_handler);
+#endif
+
+  return 0;
+}
+
 \f
 
 /* XIM (X Input Method) handler */
@@ -2164,26 +2412,13 @@ x_io_error_handler (Display *display)
 }
 #endif
 
+/*=*/
+
 /*** @} */
 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
 \f
 /* External API */
 
-int
-m17n_init_X ()
-{
-  x_driver.initialized = 0;
-  mplist_put (m17n__device_library_list, Mx, &x_driver);
-
-#ifdef HAVE_XFT2
-  xft_driver.select = mfont__ft_driver.select;
-  xft_driver.encode_char = mfont__ft_driver.encode_char;
-#endif
-
-  return 0;
-}
-
-/*=*/
 /*** @addtogroup m17nInputMethodWin */
 /*=*/
 /*** @{ */
@@ -2220,31 +2455,27 @@ m17n_init_X ()
 /***ja
     @brief XIMÍÑÆþÎϥɥ饤¥Ð.
 
-    ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã
-    ¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸
-    ¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
+    ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
+    XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
 
     ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
-    #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç¤¢¤ëÆþÎÏ
-    ¥á¥½¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
+    #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim 
+    ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
 
-    ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø
-    ¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+    ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_ 
+    ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
 
-    ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂΠ#MInputXIMArgIM ¤Ø¤Î¥Ý
-    ¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò
-    »²¾È¡£
+    ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂΠ#MInputXIMArgIM 
+    ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
 
-    ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂΠ#MInputXIMArgIC ¤Ø¤Î
-    ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ
-    ¤ò»²¾È¡£
+    ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂΠ#MInputXIMArgIC 
+    ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
 
-    ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂΠ@c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿
-    ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
+    ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂΠ@c XEvent 
+    ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
 
     ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter () 
-    ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì
-    ¤ë¡£  */
+    ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£  */
 
 MInputDriver minput_xim_driver =
   { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,