You should have received a copy of the GNU Lesser General Public
License along with the m17n library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
02111-1307, USA. */
+#include "config.h"
+
+#ifdef HAVE_X11
+
#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
/*** @addtogroup m17nInternal
@{ */
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
+#ifdef HAVE_XFT2
+#include <X11/Xft/Xft.h>
+#include <fontconfig/fcfreetype.h>
+#endif /* HAVE_XFT2 */
+
#include "m17n-gui.h"
#include "m17n-X.h"
#include "m17n-misc.h"
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 MFont. */
+ MPlist *font_list;
- MPlist *iso10646_1_family_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;
int alt_mask;
int super_mask;
int hyper_mask;
+
+ Atom MULE_BASELINE_OFFSET;
+ Atom AVERAGE_WIDTH;
} MDisplayInfo;
/* Anchor of the chain of MDisplayInfo objects. */
static MPlist *display_info_list;
-struct MWDevice
+
+/* Color value and the corresponding GC. */
+typedef struct
+{
+ unsigned int rgb; /* (red << 16) | (green << 8) | blue */
+ GC gc;
+} RGB_GC;
+
+enum gc_index
+ {
+ GC_INVERSE,
+ GC_NORMAL = GC_INVERSE + 7,
+ GC_HLINE,
+ GC_BOX_TOP,
+ GC_BOX_BOTTOM,
+ GC_BOX_LEFT,
+ GC_BOX_RIGHT,
+ GC_MAX
+ };
+
+typedef struct
+{
+ int rgb_fore;
+ int rgb_back;
+ /* The first 8 elements are indexed by an intensity for
+ anti-aliasing. The 2nd to 7th are created on demand. */
+ GC gc[GC_MAX];
+#ifdef HAVE_XFT2
+ XftColor xft_color_fore, xft_color_back;
+#endif
+} GCInfo;
+
+typedef struct
{
/* Common header for the m17n object. */
M17NObject control;
Colormap cmap;
- unsigned long foreground, background;
+ GC scratch_gc;
+
+ int resy;
+
+#ifdef HAVE_XFT2
+ XftDraw *xft_draw;
+#endif
/** List of pointers to realized faces on the frame. */
MPlist *realized_face_list;
+ /* List of single element whose value is a root of chain of realized
+ fonts. */
+ MPlist *realized_font_list;
+
/** List of pointers to realized fontsets on the frame. */
MPlist *realized_fontset_list;
-};
+ /** List of XColors vs GCs on the frame. */
+ MPlist *gc_list;
+} MWDevice;
static MPlist *device_list;
static MSymbol M_iso8859_1, M_iso10646_1;
-#define FRAME_DISPLAY(frame) (frame->device->display_info->display)
-#define FRAME_SCREEN(frame) (frame->device->screen_num)
+#define FRAME_DEVICE(frame) ((MWDevice *) (frame)->device)
+#define FRAME_DISPLAY(frame) (FRAME_DEVICE (frame)->display_info->display)
+#define FRAME_SCREEN(frame) (FRAME_DEVICE (frame)->screen_num)
+#define FRAME_CMAP(frame) (FRAME_DEVICE (frame)->cmap)
+#define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
+ FRAME_SCREEN (frame))
+
+#define DEFAULT_FONT "-*-*-medium-r-normal--13-*-*-*-c-*-iso8859-1"
+
+typedef struct
+{
+ String font;
+ String foreground;
+ String background;
+ Boolean reverse_video;
+} AppData, *AppDataPtr;
static void
free_display_info (void *object)
{
MDisplayInfo *disp_info = (MDisplayInfo *) object;
- MPlist *plist;
-
- for (plist = disp_info->font_registry_list;
- mplist_key (plist) != Mnil; plist = mplist_next (plist))
- {
- MFontList *registry_list = mplist_value (plist);
-
- if (registry_list->fonts)
- free (registry_list->fonts);
- free (registry_list);
- }
- M17N_OBJECT_UNREF (disp_info->font_registry_list);
+ MPlist *plist, *pl;
- for (plist = disp_info->iso8859_1_family_list;
- mplist_key (plist) != Mnil; plist = mplist_next (plist))
- {
- MFontList *family_list = mplist_value (plist);
-
- if (family_list->fonts)
- free (family_list->fonts);
- free (family_list);
- }
- M17N_OBJECT_UNREF (disp_info->iso8859_1_family_list);
-
- for (plist = disp_info->iso10646_1_family_list;
- mplist_key (plist) != Mnil; plist = mplist_next (plist))
+ MPLIST_DO (plist, disp_info->font_list)
{
- MFontList *family_list = mplist_value (plist);
-
- if (family_list->fonts)
- free (family_list->fonts);
- free (family_list);
+ MPLIST_DO (pl, MPLIST_VAL (plist))
+ free (MPLIST_VAL (pl));
+ M17N_OBJECT_UNREF (MPLIST_VAL (plist));
}
- M17N_OBJECT_UNREF (disp_info->iso10646_1_family_list);
-
- for (plist = disp_info->realized_font_list;
- mplist_key (plist) != Mnil; plist = mplist_next (plist))
- mfont__free_realized ((MRealizedFont *) mplist_value (plist));
- M17N_OBJECT_UNREF (disp_info->realized_font_list);
+ M17N_OBJECT_UNREF (disp_info->font_list);
if (disp_info->auto_display)
XCloseDisplay (disp_info->display);
static void
free_device (void *object)
{
- MWDevice *device = (MWDevice *) object;
+ MWDevice *device = object;
MPlist *plist;
for (plist = device->realized_fontset_list;
mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
M17N_OBJECT_UNREF (device->realized_fontset_list);
- for (plist = device->realized_face_list;
- mplist_key (plist) != Mnil; plist = mplist_next (plist))
- mface__free_realized ((MRealizedFace *) mplist_value (plist));
+ if (MPLIST_VAL (device->realized_font_list))
+ mfont__free_realized (MPLIST_VAL (device->realized_font_list));
+ M17N_OBJECT_UNREF (device->realized_font_list);
+
+ MPLIST_DO (plist, device->realized_face_list)
+ {
+ MRealizedFace *rface = MPLIST_VAL (plist);
+
+ free (rface->info);
+ mface__free_realized (rface);
+ }
M17N_OBJECT_UNREF (device->realized_face_list);
+ MPLIST_DO (plist, device->gc_list)
+ {
+ XFreeGC (device->display_info->display,
+ ((RGB_GC *) MPLIST_VAL (plist))->gc);
+ free (MPLIST_VAL (plist));
+ }
+ M17N_OBJECT_UNREF (device->gc_list);
+ XFreeGC (device->display_info->display, device->scratch_gc);
+
+#ifdef HAVE_XFT2
+ XftDrawDestroy (device->xft_draw);
+#endif
+
XFreePixmap (device->display_info->display, device->drawable);
M17N_OBJECT_UNREF (device->display_info);
free (object);
XFreeModifiermap (mods);
}
-unsigned long
-get_color (Display *display, Colormap cmap,
- MSymbol color_name, MSymbol default_name,
- unsigned long default_pixel)
+static RGB_GC *
+get_rgb_gc (MWDevice *device, XColor *xcolor)
{
- XColor exact_def;
+ int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
+ | (xcolor->blue >> 8));
+ MPlist *plist;
+ RGB_GC *rgb_gc;
+ unsigned long valuemask = GCForeground;
+ XGCValues values;
+
+ MPLIST_DO (plist, device->gc_list)
+ {
+ rgb_gc = MPLIST_VAL (plist);
- if (XParseColor (display, cmap, msymbol_name (color_name), &exact_def)
- && XAllocColor (display, cmap, &exact_def))
- return exact_def.pixel;
+ if (rgb_gc->rgb == rgb)
+ return rgb_gc;
+ if (rgb_gc->rgb > rgb)
+ break;
+ }
- if (XParseColor (display, cmap, msymbol_name (default_name), &exact_def)
- && XAllocColor (display, cmap, &exact_def))
- return exact_def.pixel;
+ if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
+ return NULL;
- return default_pixel;
+ rgb_gc = malloc (sizeof (RGB_GC));
+ rgb_gc->rgb = rgb;
+ values.foreground = xcolor->pixel;
+ rgb_gc->gc = XCreateGC (device->display_info->display,
+ device->drawable, valuemask, &values);
+ mplist_push (plist, Mt, rgb_gc);
+ return rgb_gc;
}
-\f
-/** X font handler */
-
-/** Indices to each field of split font name. */
+static GC
+get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
+{
+ MWDevice *device = FRAME_DEVICE (frame);
+ XColor xcolor;
+ RGB_GC *rgb_gc;
-enum xlfd_field_idx
+ if (color == Mnil)
+ {
+ if (frame->rface)
+ goto no_color;
+ color = for_foreground ? frame->foreground : frame->background;
+ }
+ if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
+ msymbol_name (color), &xcolor))
+ goto no_color;
+ rgb_gc = get_rgb_gc (device, &xcolor);
+ if (! rgb_gc)
+ goto no_color;
+ if (rgb_ret)
+ *rgb_ret = rgb_gc->rgb;
+ return rgb_gc->gc;
+
+ no_color:
{
- XLFD_FOUNDRY,
- XLFD_FAMILY,
- XLFD_WEIGHT,
- XLFD_SLANT,
- XLFD_SWIDTH,
- XLFD_ADSTYLE,
- XLFD_PIXEL,
- XLFD_POINT,
- XLFD_RESX,
- XLFD_RESY,
- XLFD_SPACING,
- XLFD_AVGWIDTH,
- XLFD_REGISTRY,
- XLFD_ENCODING,
- /* anchor */
- XLFD_FIELD_MAX
- };
+ GCInfo *info = frame->rface->info;
+ GC gc;
+ int rgb;
+
+ if (for_foreground)
+ rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
+ else
+ rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
+ if (rgb_ret)
+ *rgb_ret = rgb;
+ return gc;
+ }
+}
-/** Split the fontname NAME into each XLFD field destructively. Set
- each element of the table pointed by PROPERTY_IDX to a pointer to
- the corresponding font property name. Store the point size and
- the resolution-Y of the font to the place pointed by POINT and
- RESY respectively.
+static GC
+get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
+{
+ int rgb_fore, rgb_back;
+ XColor xcolor;
+ RGB_GC *rgb_gc;
+ GC gc;
- If NAME does not contain all XLFD fields, the unspecified fields is
- treated as wild cards. */
+ if (info->gc[intensity])
+ return info->gc[intensity];
+
+ rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
+ xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
+ + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
+ xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
+ + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
+ xcolor.blue = (((rgb_fore & 0xFF) * intensity
+ + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
+ rgb_gc = get_rgb_gc (device, &xcolor);
+ if (rgb_gc)
+ gc = rgb_gc->gc;
+ else
+ gc =get_gc_for_anti_alias (device, info,
+ intensity < 4 ? intensity - 1 : intensity + 1);
+ return (info->gc[intensity] = gc);
+}
-static int
-split_font_name (char *name, char **field,
- unsigned short *size, unsigned short *resy)
+static GC
+set_region (MFrame *frame, GC gc, MDrawRegion region)
{
- int i;
- char *p;
+ unsigned long valuemask = GCForeground;
- for (i = 0, p = name; *p; p++)
- {
- *p = tolower (*p);
- if (*p == '-' && i < XLFD_FIELD_MAX)
- {
- field[i] = p + 1;
- if (i != XLFD_ENCODING)
- *p = '\0';
- i++;
- }
- }
- if (i < XLFD_REGISTRY)
- return -1;
- for (; i < XLFD_FIELD_MAX; i++)
- field[i] = "*";
+ XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
+ FRAME_DEVICE (frame)->scratch_gc);
+ XSetRegion (FRAME_DISPLAY (frame), FRAME_DEVICE (frame)->scratch_gc, region);
+ return FRAME_DEVICE (frame)->scratch_gc;
+}
- if (*(field[XLFD_RESY]) == '*')
- *resy = 0;
- else
- *resy = atoi (field[XLFD_RESY]);
- if (*(field[XLFD_PIXEL]) == '*')
- {
- if (*(field[XLFD_POINT]) != '*')
- *size = atoi (field[XLFD_POINT]) * *resy / 72;
- else
- *size = 0;
- }
- else if (*(field[XLFD_PIXEL]) == '[')
- {
- /* The pixel size field specifies a transformation matrix of the
- form "[A B C D]". The XLFD spec says that the scalar value N
- for the pixel size is equivalent to D. */
- char *p0 = field[XLFD_PIXEL] + 1, *p1;
- double d;
-
- for (i = 0; i < 4; i++, p0 = p1)
- d = strtod (p0, &p1);
- *size = d * 10;
- }
- else
- *size = atoi (field[XLFD_PIXEL]) * 10;
- if (*size == 0 && *(field[XLFD_POINT]) != '*')
- {
- *size = atoi (field[XLFD_POINT]);
- if (*resy)
- *size = *size * *resy / 72;
- else
- *size = *size * 100 / 72;
- }
+\f
+/** X font handler */
- return 0;
-}
+static MFont *xfont_select (MFrame *, MFont *, int);
+static MRealizedFont *xfont_open (MFrame *, MFont *, MFont *, MRealizedFont *);
+static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
+static int xfont_has_char (MFrame *, MFont *, MFont *, int, unsigned);
+static unsigned xfont_encode_char (MFrame *, MFont *, MFont *, unsigned);
+static void xfont_render (MDrawWindow, int, int, MGlyphString *,
+ MGlyph *, MGlyph *, int, MDrawRegion);
+static int xfont_list (MFrame *, MPlist *, MFont *, int);
+static void xfont_list_family_names (MFrame *, MPlist *);
+static int xfont_check_capability (MRealizedFont *rfont, MSymbol capability);
-static int
-build_font_name (MFont *font, char *name, int limit)
-{
- MSymbol prop[7];
- char *str[7];
- int len, i;
- unsigned short size, resy;
-
- prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
- prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
- prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
- prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
- prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
- prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
- prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
- for (len = 0, i = 0; i < 7; i++)
- {
- if (prop[i] != Mnil)
- {
- str[i] = msymbol_name (prop[i]);
- len += strlen (str[i]);
- }
- else
- {
- str[i] = "*";
- len++;
- }
- }
- if ((len
- + 12 /* 12 dashes */
- + 3 /* 3 asterisks */
- + 30 /* 3 integers (each 10 digits) */
- + 1) /* '\0' terminal */
- > limit)
- return -1;
-
- size = (int) mfont_get_prop (font, Msize);
- if ((size % 10) < 5)
- size /= 10;
- else
- size = size / 10 + 1;
- resy = (int) mfont_get_prop (font, Mresolution);
+static MFontDriver xfont_driver =
+ { xfont_select, xfont_open,
+ xfont_find_metric, xfont_has_char, xfont_encode_char,
+ xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability };
- sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
- str[0], str[1], str[2], str[3], str[4], str[5],
- size, resy, resy, str[6]);
- return 0;
+static int
+font_compare (const void *p1, const void *p2)
+{
+ 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 *plist, *p;
char pattern[1024];
- MFontList *font_list;
- char **fontnames;
+ char **font_names, **names;
int nfonts;
int i, j;
+ MFont font;
+ int for_full_width;
+
+ plist = mplist_get (font_list, registry);
+ if (plist)
+ return plist;
+ p = 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;
+ {
+ char *reg_name = msymbol_name (registry);
+
+ for_full_width = (strncmp (reg_name, "jis", 3) == 0
+ || strncmp (reg_name, "gb", 2) == 0
+ || strncmp (reg_name, "big5", 4) == 0
+ || strncmp (reg_name, "ksc", 3) == 0);
+ }
+ names = alloca (sizeof (char *) * nfonts);
+ memcpy (names, font_names, sizeof (char *) * nfonts);
+ qsort (names, nfonts, sizeof (char *), font_compare);
+ MFONT_INIT (&font);
+ for (i = 0; i < nfonts; i++)
+ if (mfont__parse_name_into_font (names[i], Mx, &font) == 0
+ && (font.size > 0 || font.property[MFONT_RESY] == 0))
+ {
+ MSymbol family = FONT_PROPERTY (&font, MFONT_FAMILY);
+ MFont *fontx;
+ unsigned sizes[256];
+ int nsizes = 0;
+ int limit;
+ int size, normal_size;
+ char *base_end;
+ int base_len;
+ int fields;
+
+ /* 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.size / 10;
+ sizes[nsizes++] = size;
+ normal_size = (size >= 6 && size <= 29);
+ limit = (i + 256 < nfonts ? i + 256 : nfonts);
+ for (j = i + 1; j < limit && ! memcmp (names[i], names[j], base_len);
+ i = j++)
+ if (mfont__parse_name_into_font (names[j], Mx, &font) == 0
+ && (font.size > 0 || font.property[MFONT_RESY] == 0))
+ {
+ size = font.size / 10;
+ sizes[nsizes++] = size;
+ normal_size |= (size >= 6 && size <= 29);
+ }
- MSTRUCT_CALLOC (font_list, MERROR_WIN);
-
- 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;
- }
-
- 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 (mwin__parse_font_name (fontnames[i], font_list->fonts + j) >= 0
- && (font_list->fonts[j].property[MFONT_SIZE] != 0
- || font_list->fonts[j].property[MFONT_RESY] == 0))
+ font.for_full_width = for_full_width;
+ font.type = MFONT_TYPE_OBJECT;
+ font.source = MFONT_SOURCE_X;
+ if (normal_size)
{
- font_list->fonts[j].property[MFONT_TYPE] = MFONT_TYPE_WIN + 1;
- j++;
+ MSTRUCT_CALLOC (fontx, MERROR_WIN);
+ *fontx = font;
+ fontx->multiple_sizes = 1;
+ fontx->size = 0;
+ for (j = 0; j < nsizes; j++)
+ if (sizes[j] >= 6 && sizes[j] <= 29)
+ fontx->size |= 1 << (sizes[j] - 6);
+ p = mplist_add (p, family, fontx);
}
- XFreeFontNames (fontnames);
- font_list->nfonts = j;
- }
- mplist_add (plist, font_list->tag, font_list);
- return (nfonts > 0 ? font_list : NULL);
+ for (j = 0; j < nsizes; j++)
+ if (sizes[j] < 6 || sizes[j] > 29)
+ {
+ MSTRUCT_CALLOC (fontx, MERROR_WIN);
+ *fontx = font;
+ fontx->multiple_sizes = 0;
+ fontx->size = sizes[j] * 10;
+ if (sizes[j] == 0)
+ fontx->property[MFONT_RESY] = 0;
+ p = mplist_add (p, family, fontx);
+ }
+ }
+ 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;
-static MRealizedFont *xfont_select (MFrame *, MFont *, MFont *, int);
-static int xfont_open (MRealizedFont *);
-static void xfont_close (MRealizedFont *);
-static void xfont_find_metric (MRealizedFont *, MGlyph *);
-static unsigned xfont_encode_char (MRealizedFont *, int, unsigned);
-static void xfont_render (MDrawWindow, int, int, MGlyphString *,
- MGlyph *, MGlyph *, int, MDrawRegion);
+ 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));
+}
-MFontDriver xfont_driver =
- { xfont_select, xfont_open, xfont_close,
- xfont_find_metric, xfont_encode_char, xfont_render };
+typedef struct
+{
+ M17NObject control;
+ Display *display;
+ XFontStruct *xfont;
+} MRealizedFontX;
/* The X font driver function SELECT. */
-static MRealizedFont *
-xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size)
+static MFont *
+xfont_select (MFrame *frame, MFont *font, int limited_size)
{
- MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
- MRealizedFont *rfont;
- MFontList *font_list = NULL;
- int i;
- MFont *best_font;
- int 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->display_info->iso8859_1_family_list
- : frame->device->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->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;
+ MPlist *plist = mplist (), *pl;
+ int num = xfont_list (frame, plist, font, 0);
+ MFont *found = 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)
- return NULL;
- best_font = font_list->fonts + i;
- for (; best_score > 0 && i < font_list->nfonts ; i++)
- {
- score = mfont__score (font_list->fonts + i, spec, request,
- limited_size);
- if (score >= 0 && score < best_score)
- {
- best_font = font_list->fonts + i;
- best_score = score;
- }
- }
-
- 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)
- rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE];
- rfont->score = best_score;
- rfont->driver = &xfont_driver;
- return rfont;
+ if (num > 0)
+ MPLIST_DO (pl, plist)
+ {
+ font = MPLIST_VAL (pl);
+ if (limited_size == 0
+ || font->size == 0
+ || font->size <= limited_size)
+ {
+ found = font;
+ break;
+ }
+ }
+ M17N_OBJECT_UNREF (plist);
+ return found;
}
-typedef struct
-{
- M17NObject control;
- MFrame *frame;
- XFontStruct *f;
-} MXFontInfo;
+/* The X font driver function CLOSE. */
static void
close_xfont (void *object)
{
- MXFontInfo *xfont = (MXFontInfo *) object;
+ MRealizedFontX *x_rfont = object;
- if (xfont->f)
- XFreeFont (FRAME_DISPLAY (xfont->frame), xfont->f);
- free (object);
+ XFreeFont (x_rfont->display, x_rfont->xfont);
+ free (x_rfont);
}
-
/* The X font driver function OPEN. */
-static int
-xfont_open (MRealizedFont *rfont)
+static MRealizedFont *
+xfont_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
{
- char name[1024];
- MXFontInfo *xfont;
- MFrame *frame = rfont->frame;
+ int size;
+ MRealizedFontX *x_rfont;
+ char *name;
+ Display *display = FRAME_DISPLAY (frame);
+ XFontStruct *xfont;
int mdebug_mask = MDEBUG_FONT;
+ MFont this;
- /* This never fail to generate a valid fontname because open_spec
- should correspond to a font available on the system. */
- build_font_name (&rfont->font, name, 1024);
- M17N_OBJECT (xfont, close_xfont, MERROR_WIN);
- rfont->info = xfont;
- xfont->frame = frame;
- xfont->f = XLoadQueryFont (FRAME_DISPLAY (frame), name);
- if (! xfont->f)
+ size = spec->size;
+ if (size)
{
- rfont->status = -1;
- MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
- return -1;
+ int ratio = mfont_resize_ratio (font);
+
+ if (ratio != 100)
+ size = size * ratio / 100;
}
- MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
- rfont->status = 1;
- rfont->ascent = xfont->f->ascent;
- rfont->descent = xfont->f->descent;
- return 0;
-}
+ else
+ size = 120;
+ if (font->size)
+ {
+ /* non-scalable font */
+ if (font->multiple_sizes)
+ {
+ int i;
+
+ if (size < 60)
+ size = 60;
+ else if (size > 290)
+ size = 290;
+ for (i = size / 10 - 6; i >= 0; i--)
+ if (font->size & (1 << i))
+ break;
+ if (i == 0)
+ for (i = size / 10 - 5; i < 24; i++)
+ if (font->size & (1 << i))
+ break;
+ size = (i + 6) * 10;
+ }
+ else
+ size = font->size;
+ }
-/* The X font driver function CLOSE. */
+ if (rfont)
+ {
+ for (; rfont; rfont = rfont->next)
+ if (rfont->font == font && rfont->spec.size == size)
+ return rfont;
+ }
-static void
-xfont_close (MRealizedFont *rfont)
-{
- M17N_OBJECT_UNREF (rfont->info);
+ this = *font;
+ this.multiple_sizes = 0;
+ this.size = size;
+ /* This never fail to generate a valid fontname. */
+ name = mfont_unparse_name (&this, Mx);
+ xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
+ if (! xfont)
+ {
+ MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
+ free (name);
+ font->type = MFONT_TYPE_FAILURE;
+ return NULL;
+ }
+ MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
+ free (name);
+ M17N_OBJECT (x_rfont, close_xfont, MERROR_FONT_X);
+ x_rfont->display = display;
+ x_rfont->xfont = xfont;
+ MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
+ rfont->spec = this;
+ rfont->spec.type = MFONT_TYPE_REALIZED;
+ rfont->spec.source = MFONT_SOURCE_X;
+ rfont->frame = frame;
+ rfont->font = font;
+ rfont->driver = &xfont_driver;
+ rfont->info = x_rfont;
+ {
+ MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
+ unsigned long value;
+
+ rfont->baseline_offset
+ = (XGetFontProperty (xfont, disp_info->MULE_BASELINE_OFFSET, &value)
+ ? (int) value : 0);
+ rfont->average_width
+ = (XGetFontProperty (xfont, disp_info->AVERAGE_WIDTH, &value)
+ ? (int) value / 10 : 0);
+ }
+ rfont->ascent = xfont->ascent + rfont->baseline_offset;
+ rfont->descent = xfont->descent - rfont->baseline_offset;
+ rfont->max_advance = xfont->max_bounds.width;
+ rfont->fontp = xfont;
+ rfont->next = MPLIST_VAL (frame->realized_font_list);
+ MPLIST_VAL (frame->realized_font_list) = rfont;
+ return rfont;
}
+
/* The X font driver function FIND_METRIC. */
static void
-xfont_find_metric (MRealizedFont *rfont, MGlyph *g)
+xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
+ int from, int to)
{
- XCharStruct *pcm = NULL;
- MXFontInfo *xfont = (MXFontInfo *) rfont->info;
- XFontStruct *f = xfont->f;
- int byte1, byte2;
-
- if (g->code == MCHAR_INVALID_CODE)
- {
- g->lbearing = f->max_bounds.lbearing;
- g->rbearing = f->max_bounds.rbearing;
- g->width = f->max_bounds.width;
- g->ascent = f->ascent;
- g->descent = f->descent;
- return;
- }
-
- byte1 = g->code >> 8;
- byte2 = g->code & 0xFF;
+ XFontStruct *xfont = rfont->fontp;
+ MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
- if (f->per_char != NULL)
+ for (; g != gend; g++)
{
- if (f->min_byte1 == 0 && f->max_byte1 == 0)
+ if (g->code == MCHAR_INVALID_CODE)
{
- if (byte1 == 0
- && byte2 >= f->min_char_or_byte2
- && byte2 <= f->max_char_or_byte2)
- pcm = f->per_char + byte2 - f->min_char_or_byte2;
+ g->lbearing = xfont->max_bounds.lbearing;
+ g->rbearing = xfont->max_bounds.rbearing;
+ g->width = xfont->max_bounds.width;
+ g->ascent = xfont->ascent;
+ g->descent = xfont->descent;
}
else
{
- if (byte1 >= f->min_byte1
- && byte1 <= f->max_byte1
- && byte2 >= f->min_char_or_byte2
- && byte2 <= f->max_char_or_byte2)
+ int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
+ XCharStruct *pcm = NULL;
+
+ if (xfont->per_char != NULL)
{
- pcm = (f->per_char
- + ((f->max_char_or_byte2-f->min_char_or_byte2 + 1)
- * (byte1 - f->min_byte1))
- + (byte2 - f->min_char_or_byte2));
+ if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
+ {
+ if (byte1 == 0
+ && byte2 >= xfont->min_char_or_byte2
+ && byte2 <= xfont->max_char_or_byte2)
+ pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
+ }
+ else
+ {
+ if (byte1 >= xfont->min_byte1
+ && byte1 <= xfont->max_byte1
+ && byte2 >= xfont->min_char_or_byte2
+ && byte2 <= xfont->max_char_or_byte2)
+ {
+ pcm = (xfont->per_char
+ + ((xfont->max_char_or_byte2
+ - xfont->min_char_or_byte2 + 1)
+ * (byte1 - xfont->min_byte1))
+ + (byte2 - xfont->min_char_or_byte2));
+ }
+ }
}
- }
- }
- if (pcm)
- {
- g->lbearing = pcm->lbearing;
- g->rbearing = pcm->rbearing;
- g->width = pcm->width;
- g->ascent = pcm->ascent;
- g->descent = pcm->descent;
- }
- else
- {
- /* If the per_char pointer is null, all glyphs between the first
- and last character indexes inclusive have the same
- information, as given by both min_bounds and max_bounds. */
- g->lbearing = 0;
- g->rbearing = f->max_bounds.width;
- g->width = f->max_bounds.width;
- g->ascent = f->ascent;
- g->descent = f->descent;
+ if (pcm)
+ {
+ g->lbearing = pcm->lbearing;
+ g->rbearing = pcm->rbearing;
+ g->width = pcm->width;
+ g->ascent = pcm->ascent;
+ g->descent = pcm->descent;
+ }
+ else
+ {
+ /* If the per_char pointer is null, all glyphs between
+ the first and last character indexes inclusive have
+ the same information, as given by both min_bounds and
+ max_bounds. */
+ g->lbearing = 0;
+ g->rbearing = xfont->max_bounds.width;
+ g->width = xfont->max_bounds.width;
+ g->ascent = xfont->ascent;
+ g->descent = xfont->descent;
+ }
+ }
+ g->ascent += rfont->baseline_offset;
+ g->descent -= rfont->baseline_offset;
}
}
-/* The X font driver function ENCODE_CHAR. */
+static int
+xfont_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
+{
+ return (xfont_encode_char (frame, font, spec, code) != MCHAR_INVALID_CODE);
+}
+
+/* The X font driver function GET_GLYPH_ID. */
static unsigned
-xfont_encode_char (MRealizedFont *rfont, int c, unsigned code)
+xfont_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
{
- MXFontInfo *xfont;
- XFontStruct *f;
+ MRealizedFont *rfont;
+ XFontStruct *xfont;
unsigned min_byte1, max_byte1, min_byte2, max_byte2;
int all_chars_exist;
- if (rfont->status < 0)
- return -1;
- if (rfont->status == 0)
+ if (font->type == MFONT_TYPE_REALIZED)
+ rfont = (MRealizedFont *) font;
+ else if (font->type == MFONT_TYPE_OBJECT)
{
- if (xfont_open (rfont) < 0)
- return -1;
+ for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
+ rfont = rfont->next)
+ if (rfont->font == font)
+ break;
+ if (! rfont)
+ {
+ rfont = xfont_open (frame, font, spec, NULL);
+ if (! rfont)
+ return MCHAR_INVALID_CODE;
+ }
}
- xfont = (MXFontInfo *) rfont->info;
- f = xfont->f;
- all_chars_exist = (! f->per_char || f->all_chars_exist == True);
- min_byte1 = f->min_byte1;
- max_byte1 = f->max_byte1;
- min_byte2 = f->min_char_or_byte2;
- max_byte2 = f->max_char_or_byte2;
+ else
+ MFATAL (MERROR_FONT_X);
+ xfont = rfont->fontp;
+ all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True);
+ min_byte1 = xfont->min_byte1;
+ max_byte1 = xfont->max_byte1;
+ min_byte2 = xfont->min_char_or_byte2;
+ max_byte2 = xfont->max_char_or_byte2;
if (min_byte1 == 0 && max_byte1 == 0)
{
XCharStruct *pcm;
+ if (code < min_byte2 || code > max_byte2)
+ return MCHAR_INVALID_CODE;
if (all_chars_exist)
- return ((code >= min_byte2 && code <= max_byte2)
- ? code : MCHAR_INVALID_CODE);
- pcm = f->per_char + (code - min_byte2);
+ return code;
+ pcm = xfont->per_char + (code - min_byte2);
return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
? code : MCHAR_INVALID_CODE);
}
unsigned byte1 = code >> 8, byte2 = code & 0xFF;
XCharStruct *pcm;
+ if (byte1 < min_byte1 || byte1 > max_byte1
+ || byte2 < min_byte2 || byte2 > max_byte2)
+ return MCHAR_INVALID_CODE;
+
if (all_chars_exist)
- return ((byte1 >= min_byte1 && byte1 <= max_byte1
- && byte2 >= min_byte2 && byte2 <= max_byte2)
- ? code : MCHAR_INVALID_CODE);
- pcm = f->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
+ return code;
+ pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
+ (byte2 - min_byte2));
return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
? code : MCHAR_INVALID_CODE);
}
}
-static GC
-set_region (Display *display, MRealizedFace *rface, GC gc, MDrawRegion region)
-{
- GC gc1;
- XRectangle xrect;
-
- XClipBox (region, &xrect);
- gc1 = ((GC *) rface->info)[MFACE_GC_SCRATCH];
- XCopyGC (display, gc, GCFont | GCForeground | GCBackground, gc1);
- XSetRegion (display, gc1, region);
- return gc1;
-}
-
/* The X font driver function RENDER. */
static void
MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
{
MRealizedFace *rface = from->rface;
- Display *display;
+ Display *display = FRAME_DISPLAY (rface->frame);
XChar2b *code;
- GC *gcs = rface->info;
- GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
+ GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
MGlyph *g;
int i;
+ int baseline_offset;
if (from == to)
return;
- /* It is assured that the all glyphs in the current range use the
- same realized face. */
- display = FRAME_DISPLAY (rface->frame);
-
+ baseline_offset = rface->rfont->baseline_offset;
if (region)
- gc = set_region (display, rface, gc, region);
-
- if (from->code == MCHAR_INVALID_CODE)
+ gc = set_region (rface->frame, gc, region);
+ XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
+ code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
+ for (i = 0, g = from; g < to; i++, g++)
{
- int x0 = x;
-
- for (; from < to; from++)
- {
- XDrawRectangle (display, (Window) win, gc,
- x0, y - gstring->ascent + 1, from->width - 1,
- gstring->ascent + gstring->descent - 2);
- x0 += from->width;
- }
- return;
- }
-
- code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
- for (i = 0, g = from; g < to; i++, g++)
- {
- code[i].byte1 = g->code >> 8;
- code[i].byte2 = g->code & 0xFF;
- }
+ code[i].byte1 = g->code >> 8;
+ code[i].byte2 = g->code & 0xFF;
+ }
g = from;
while (g < to)
else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
{
XDrawString16 (display, (Window) win, gc,
- x + g->xoff, y + g->yoff, code + (g - from), 1);
+ x + g->xoff, y + g->yoff - baseline_offset,
+ code + (g - from), 1);
x += g->width;
g++;
}
g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
i++, g++)
x += g->width;
- XDrawString16 (display, (Window) win, gc, orig_x, y,
- code + code_idx, i);
+ XDrawString16 (display, (Window) win, gc,
+ orig_x, y - baseline_offset, code + code_idx, i);
}
}
}
-\f
-
-/* XIM (X Input Method) handler */
-
-typedef struct MInputXIMMethodInfo
-{
- Display *display;
- XIM xim;
- MSymbol language;
- MSymbol coding;
-} MInputXIMMethodInfo;
-
-typedef struct MInputXIMContextInfo
-{
- XIC xic;
- Window win;
- MConverter *converter;
-} MInputXIMContextInfo;
-
static int
-xim_open_im (MInputMethod *im)
+xfont_list (MFrame *frame, MPlist *plist, MFont *font, int maxnum)
{
- MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
- MLocale *saved, *this;
- char *save_modifier_list;
- XIM xim;
- MInputXIMMethodInfo *im_info;
+ 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;
+ int size = font ? font->size : 0;
+ MPlist *pl, *p;
+ int num = 0;
+ int mdebug_mask = MDEBUG_FONT;
- saved = mlocale_set (LC_CTYPE, NULL);
- this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
- if (! this)
- /* The specified locale is not supported. */
- MERROR (MERROR_LOCALE, -1);
- if (mlocale_get_prop (this, Mcoding) == Mnil)
- {
- /* Unable to decode the output of XIM. */
- mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
- MERROR (MERROR_LOCALE, -1);
- }
+ MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
+ family ? msymbol_name (family) : "*",
+ registry ? msymbol_name (registry) : "*");
- if (arg->modifier_list)
- save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
+ if (registry == Mnil)
+ xfont_list_all (frame);
else
- save_modifier_list = XSetLocaleModifiers ("");
- if (! save_modifier_list)
- {
- /* The specified locale is not supported by X. */
- mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
- MERROR (MERROR_LOCALE, -1);
- }
-
- xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
- if (! xim)
- {
- /* No input method is available in the current locale. */
- XSetLocaleModifiers (save_modifier_list);
- mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
- MERROR (MERROR_WIN, -1);
- }
+ xfont_registry_list (frame, registry);
- MSTRUCT_MALLOC (im_info, MERROR_WIN);
- im_info->display = arg->display;
- im_info->xim = xim;
- im_info->language = mlocale_get_prop (this, Mlanguage);
- im_info->coding = mlocale_get_prop (this, Mcoding);
- im->info = im_info;
+ MPLIST_DO (pl, disp_info->font_list)
+ if (registry == Mnil || registry == MPLIST_KEY (pl))
+ {
+ MPLIST_DO (p, MPLIST_VAL (pl))
+ if (family == Mnil || family == MPLIST_KEY (p))
+ {
+ MFont *fontx = MPLIST_VAL (p);
- XSetLocaleModifiers (save_modifier_list);
- mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
+ if (! font || (mfont__match_p (fontx, font, MFONT_REGISTRY)))
+ {
+ if (fontx->size != 0 && size)
+ {
+ if (fontx->multiple_sizes)
+ {
+ if (size < 60 || size > 290
+ || ! (fontx->size & (1 << (size / 10 - 6))))
+ continue;
+ }
+ else if (fontx->size != size)
+ continue;
+ }
+ mplist_push (plist, MPLIST_KEY (p), fontx);
+ num++;
+ if (maxnum > 0 && maxnum == num)
+ goto done;
+ }
+ }
+ }
- return 0;
+ done:
+ MDEBUG_PRINT1 (" %d found\n", num);
+ return num;
}
static void
-xim_close_im (MInputMethod *im)
+xfont_list_family_names (MFrame *frame, MPlist *plist)
{
- MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
+ MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
+ char **font_names;
+ int i, nfonts;
+ MSymbol last_family = Mnil;
+
+ font_names = XListFonts (disp_info->display,
+ "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", 0x8000, &nfonts);
+ for (i = 0; i < nfonts; i++)
+ {
+ MSymbol family;
+ char foundry[256], fam[256];
+ MPlist *p;
+
+ if (sscanf (font_names[i], "-%s-%s-", foundry, fam) < 2)
+ continue;
+ family = msymbol (fam);
+ if (family == last_family)
+ continue;
+ last_family = family;
+
+ MPLIST_DO (p, plist)
+ {
+ MSymbol sym = MPLIST_SYMBOL (p);
- XCloseIM (im_info->xim);
- free (im_info);
+ if (sym == family)
+ break;
+ if (strcmp (MSYMBOL_NAME (sym), fam) > 0)
+ {
+ mplist_push (p, Msymbol, family);
+ break;
+ }
+ }
+ if (MPLIST_TAIL_P (p))
+ mplist_push (p, Msymbol, family);
+ }
+ if (font_names)
+ XFreeFontNames (font_names);
}
-int
-xim_create_ic (MInputContext *ic)
+static int
+xfont_check_capability (MRealizedFont *rfont, MSymbol capability)
{
- MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
- MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
- MInputXIMContextInfo *ic_info;
- XIC xic;
-
- if (! arg->input_style)
- {
- /* By default, use Root style. */
- arg->input_style = XIMPreeditNothing | XIMStatusNothing;
- arg->preedit_attrs = NULL;
- arg->status_attrs = NULL;
- }
+ /* Currently X font driver doesn't support any capability. */
+ return -1;
+}
- if (! arg->preedit_attrs && ! arg->status_attrs)
- xic = XCreateIC (im_info->xim,
- XNInputStyle, arg->input_style,
- XNClientWindow, arg->client_win,
- XNFocusWindow, arg->focus_win,
- NULL);
- else if (arg->preedit_attrs && ! arg->status_attrs)
- xic = XCreateIC (im_info->xim,
- XNInputStyle, arg->input_style,
- XNClientWindow, arg->client_win,
- XNFocusWindow, arg->focus_win,
- XNPreeditAttributes, arg->preedit_attrs,
- NULL);
- else if (! arg->preedit_attrs && arg->status_attrs)
- xic = XCreateIC (im_info->xim,
- XNInputStyle, arg->input_style,
- XNClientWindow, arg->client_win,
- XNFocusWindow, arg->focus_win,
- XNStatusAttributes, arg->status_attrs,
- NULL);
- else
- xic = XCreateIC (im_info->xim,
- XNInputStyle, arg->input_style,
- XNClientWindow, arg->client_win,
- XNFocusWindow, arg->focus_win,
- XNPreeditAttributes, arg->preedit_attrs,
- XNStatusAttributes, arg->status_attrs,
- NULL);
- if (! xic)
- MERROR (MERROR_WIN, -1);
+\f
+/* Xft Handler */
- MSTRUCT_MALLOC (ic_info, MERROR_WIN);
- ic_info->xic = xic;
- ic_info->win = arg->focus_win;
- ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
- ic->info = ic_info;
- return 0;
-}
+#ifdef HAVE_XFT2
-void
-xim_destroy_ic (MInputContext *ic)
+typedef struct
{
- MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
+ M17NObject control;
+ FT_Face ft_face; /* This must be the 2nd member. */
+ Display *display;
+ XftFont *font_aa;
+ XftFont *font_no_aa;
+ /* Pointer to MRealizedFontFT */
+ void *info;
+} MRealizedFontXft;
+
+static MRealizedFont *xft_open (MFrame *frame, MFont *font, MFont *spec,
+ MRealizedFont *);
+static int xft_has_char (MFrame *frame, MFont *font, MFont *spec,
+ int c, unsigned code);
+static unsigned xft_encode_char (MFrame *frame, MFont *font, MFont *spec,
+ unsigned code);
+static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
+static void xft_render (MDrawWindow, int, int, MGlyphString *,
+ MGlyph *, MGlyph *, int, MDrawRegion);
+static int xft_check_capability (MRealizedFont *rfont, MSymbol capability);
+
+static MFontDriver xft_driver =
+ { NULL, xft_open,
+ xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL, NULL,
+ xft_check_capability
+ };
- XDestroyIC (ic_info->xic);
- mconv_free_converter (ic_info->converter);
- free (ic_info);
- ic->info = NULL;
+static void
+close_xft (void *object)
+{
+ MRealizedFontXft *rfont_xft = object;
+
+ if (rfont_xft->font_aa)
+ XftFontClose (rfont_xft->display, rfont_xft->font_aa);
+ if (rfont_xft->font_no_aa)
+ XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
+ M17N_OBJECT_UNREF (rfont_xft->info);
+ free (rfont_xft);
}
-static int
-xim_filter (MInputContext *ic, MSymbol key, void *event)
-{
- MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
- return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
+static XftFont *
+xft_open_font (Display *display, MSymbol file, double size,
+ FcBool anti_alias)
+{
+ FcPattern *pattern;
+ XftFont *font;
+
+ pattern = FcPatternCreate ();
+ FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
+ FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
+ FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
+ font = XftFontOpenPattern (display, pattern);
+ return font;
}
-static int
-xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
+static MRealizedFont *
+xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
{
- MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
- MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
- XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
- KeySym keysym;
- Status status;
- char *buf;
- int len;
-
- buf = (char *) alloca (512);
- len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
- if (status == XBufferOverflow)
+ Display *display = FRAME_DISPLAY (frame);
+ int reg = spec->property[MFONT_REGISTRY];
+ FT_Face ft_face;
+ MRealizedFontXft *rfont_xft;
+ FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
+ int size;
+ XftFont *xft_font;
+ int ascent, descent, max_advance, average_width, baseline_offset;
+
+ if (font->size)
+ /* non-scalable font */
+ size = font->size;
+ else if (spec->size)
{
- buf = (char *) alloca (len);
- len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
+ int ratio = mfont_resize_ratio (font);
+
+ size = ratio == 100 ? spec->size : spec->size * ratio / 100;
}
+ else
+ size = 120;
- mtext_reset (ic->produced);
- if (len == 0)
- return 1;
+ if (rfont)
+ {
+ MRealizedFont *save = NULL;
- mconv_reset_converter (ic_info->converter);
- mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
- mconv_decode (ic_info->converter, ic->produced);
- mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
- Mlanguage, (void *) im_info->language);
- mtext_cpy (mt, ic->produced);
- mtext_reset (ic->produced);
- return 0;
+ for (; rfont; rfont = rfont->next)
+ if (rfont->font == font
+ && (rfont->font->size ? rfont->font->size == size
+ : rfont->spec.size == size)
+ && rfont->spec.property[MFONT_REGISTRY] == reg)
+ {
+ if (! save)
+ save = rfont;
+ if (rfont->driver == &xft_driver)
+ return rfont;
+ }
+ rfont = save;
+ }
+ rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
+ if (! rfont)
+ return NULL;
+ ascent = rfont->ascent;
+ descent = rfont->descent;
+ max_advance = rfont->max_advance;
+ average_width = rfont->average_width;
+ baseline_offset = rfont->baseline_offset;
+ spec = &rfont->spec;
+ ft_face = rfont->fontp;
+ xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
+ if (! xft_font)
+ return NULL;
+ M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
+ rfont_xft->display = display;
+ if (anti_alias == FcTrue)
+ rfont_xft->font_aa = xft_font;
+ else
+ rfont_xft->font_no_aa = xft_font;
+ rfont_xft->ft_face = ft_face;
+ rfont_xft->info = rfont->info;
+ M17N_OBJECT_REF (rfont->info);
+ MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
+ rfont->spec = *spec;
+ rfont->spec.size = size;
+ rfont->frame = frame;
+ rfont->font = font;
+ rfont->driver = &xft_driver;
+ rfont->info = rfont_xft;
+ rfont->ascent = ascent;
+ rfont->descent = descent;
+ rfont->max_advance = max_advance;
+ rfont->average_width = average_width;
+ rfont->baseline_offset = baseline_offset;
+ rfont->fontp = xft_font;
+ rfont->next = MPLIST_VAL (frame->realized_font_list);
+ MPLIST_VAL (frame->realized_font_list) = rfont;
+ return rfont;
}
-\f
-
-#if 1
-int
-x_error_handler (Display *display, XErrorEvent *error)
+static void
+xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
+ int from, int to)
{
- mdebug_hook ();
- return 0;
-}
+ Display *display = FRAME_DISPLAY (rfont->frame);
+ XftFont *xft_font = rfont->fontp;
+ MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
-int
-x_io_error_handler (Display *display)
-{
- mdebug_hook ();
- return 0;
+ for (; g != gend; g++)
+ {
+ if (g->code == MCHAR_INVALID_CODE)
+ {
+ g->lbearing = 0;
+ g->rbearing = xft_font->max_advance_width;
+ g->width = g->rbearing;
+ g->ascent = xft_font->ascent;
+ g->descent = xft_font->descent;
+ }
+ else
+ {
+ XGlyphInfo extents;
+
+ XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
+ g->lbearing = - extents.x;
+ g->rbearing = extents.width - extents.x;
+ g->width = extents.xOff;
+ g->ascent = extents.y;
+ g->descent = extents.height - extents.y;
+ }
+ }
}
-#endif
-\f
-
-int
-mwin__init ()
+static int
+xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
{
- Mdisplay = msymbol ("display");
- Mscreen = msymbol ("screen");
- Mdrawable = msymbol ("drawable");
- Mdepth = msymbol ("depth");
- Mwidget = msymbol ("widget");
- M_iso8859_1 = msymbol ("iso8859-1");
- M_iso10646_1 = msymbol ("iso10646-1");
-
- display_info_list = mplist ();
- device_list = mplist ();
-
- mfont__driver_list[MFONT_TYPE_WIN] = &xfont_driver;
-
- Mxim = msymbol ("xim");
- msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
+ int result;
- return 0;
+ if (font->type == MFONT_TYPE_REALIZED)
+ {
+ MRealizedFont *rfont = (MRealizedFont *) font;
+ MRealizedFontXft *rfont_xft = rfont->info;
+
+ rfont->info = rfont_xft->info;
+ result = mfont__ft_driver.has_char (frame, font, spec, c, code);
+ rfont->info = rfont_xft;
+ }
+ else
+ result = mfont__ft_driver.has_char (frame, font, spec, c, code);
+ return result;
}
-void
-mwin__fini ()
+static unsigned
+xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
{
- M17N_OBJECT_UNREF (display_info_list);
- M17N_OBJECT_UNREF (device_list);
+ if (font->type == MFONT_TYPE_REALIZED)
+ {
+ MRealizedFont *rfont = (MRealizedFont *) font;
+ MRealizedFontXft *rfont_xft = rfont->info;
+
+ rfont->info = rfont_xft->info;
+ code = mfont__ft_driver.encode_char (frame, font, spec, code);
+ rfont->info = rfont_xft;
+ }
+ else
+ code = mfont__ft_driver.encode_char (frame, font, spec, code);
+ return code;
}
-typedef struct
+static void
+xft_render (MDrawWindow win, int x, int y,
+ MGlyphString *gstring, MGlyph *from, MGlyph *to,
+ int reverse, MDrawRegion region)
{
- String font;
- String foreground;
- String background;
- Boolean reverse_video;
-} AppData, *AppDataPtr;
-
-
-int
-mwin__parse_font_name (char *name, MFont *font)
-{
- char *field[XLFD_FIELD_MAX];
- unsigned short size, resy;
- MSymbol attrs[MFONT_PROPERTY_MAX];
- char *copy = (char *) alloca (512);
- int i, len;
- char *p, *last = NULL;
-
- len = strlen (name) + 1;
- for (i = 0, p = name; *p; p++)
- {
- if (*p == '-')
- i++;
- else if (p > name && *p == '*' && p[-1] == '-')
- last = p + 1;
- }
- if (i == 14)
- memcpy (copy, name, len);
- else if (last)
- {
- memcpy (copy, name, last - name);
- for (; i < 14; i++)
- strcat (copy, "-*");
- strcat (copy, last);
- }
-
- if (split_font_name (copy, field, &size, &resy) < 0)
- return -1;
- attrs[MFONT_FOUNDRY]
- = *(field[XLFD_FOUNDRY]) != '*' ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
- attrs[MFONT_FAMILY]
- = *(field[XLFD_FAMILY]) != '*' ? msymbol (field[XLFD_FAMILY]) : Mnil;
- attrs[MFONT_WEIGHT]
- = *(field[XLFD_WEIGHT]) != '*' ? msymbol (field[XLFD_WEIGHT]) : Mnil;
- attrs[MFONT_STYLE]
- = *(field[XLFD_SLANT]) != '*' ? msymbol (field[XLFD_SLANT]) : Mnil;
- attrs[MFONT_STRETCH]
- = *(field[XLFD_SWIDTH]) != '*' ? msymbol (field[XLFD_SWIDTH]) : Mnil;
- attrs[MFONT_ADSTYLE]
- = *(field[XLFD_ADSTYLE]) != '*' ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
- attrs[MFONT_REGISTRY]
- = *(field[XLFD_REGISTRY]) != '*' ? msymbol (field[XLFD_REGISTRY]) : Mnil;
- mfont__set_spec (font, attrs, size, resy);
- return 0;
-}
-
-
-char *
-mwin__build_font_name (MFont *font)
-{
- char name[1024];
-
- if (build_font_name (font, name, 1024) < 0)
- return NULL;
- return strdup (name);
-}
-
-/** 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. */
-
-MWDevice *
-mwin__open_device (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;
-
- if (param)
- 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);
- }
+ MRealizedFace *rface = from->rface;
+ MFrame *frame = rface->frame;
+ Display *display = FRAME_DISPLAY (frame);
+ MRealizedFont *rfont = rface->rfont;
+ MRealizedFontXft *rfont_xft = rfont->info;
+ XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
+ XftColor *xft_color = (! reverse
+ ? &((GCInfo *) rface->info)->xft_color_fore
+ : &((GCInfo *) rface->info)->xft_color_back);
+ int anti_alias = (gstring->control.anti_alias
+ && FRAME_DEVICE (frame)->depth > 1);
+ XftFont *xft_font;
+ MGlyph *g;
+ FT_UInt *glyphs;
+ int last_x;
+ int nglyphs;
- 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 (from == to)
+ return;
- if (! display)
- MERROR (MERROR_WIN, NULL);
- XGetGeometry (display, drawable, &root_window,
- &x, &y, &width, &height, &border_width, &depth);
- XGetWindowAttributes (display, root_window, &attr);
- screen_num = XScreenNumberOfScreen (attr.screen);
- }
- else
+ if (anti_alias)
{
- if (screen)
- display = DisplayOfScreen (screen);
+ if (rfont_xft->font_aa)
+ xft_font = rfont_xft->font_aa;
else
{
- if (! display)
- {
- display = XOpenDisplay (NULL);
- if (! display)
- MERROR (MERROR_WIN, NULL);
- 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);
- }
+ double size = rfont->spec.size;
- 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;
+ xft_font = xft_open_font (display, rfont->spec.file, size / 10,
+ FcTrue);
+ if (xft_font)
+ rfont_xft->font_aa = xft_font;
+ else
+ xft_font = rfont->fontp;
+ }
}
-
- if (mplist_key (plist) != Mnil)
- M17N_OBJECT_REF (device);
else
{
- 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->foreground = BlackPixel (display, screen_num);
- device->background = WhitePixel (display, screen_num);
- }
-
- 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)
- {
- AppData app_data;
- XtResource resources[] = {
- { XtNfont, XtCFont, XtRString, sizeof (String),
- XtOffset (AppDataPtr, font), XtRString,
- "-misc-fixed-medium-r-normal--*-120-*-*-*-*-iso8859-1" },
- { 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 }
- };
- MFace *face = NULL;
- MFont font;
- char **names;
- int nfonts;
-
- XtGetApplicationResources (widget, &app_data,
- resources, XtNumber (resources), NULL, 0);
- names = XListFonts (display, app_data.font, 1, &nfonts);
- if (nfonts == 1)
+ if (rfont_xft->font_no_aa)
+ xft_font = rfont_xft->font_no_aa;
+ else
{
- if (mwin__parse_font_name (names[0], &font) >= 0)
- face = mface_from_font (&font);
- else
- {
- /* The font name does not conform to XLFD. Try to open the
- font and get XA_FONT property. */
- XFontStruct *xfont = XLoadQueryFont (display, names[0]);
-
- if (xfont)
- {
- unsigned long value;
- char *name;
+ double size = rfont->spec.size;
- if (XGetFontProperty (xfont, XA_FONT, &value)
- && (name = ((char *)
- XGetAtomName (display, (Atom) value))))
- {
- if (mwin__parse_font_name (name, &font) >= 0)
- face = mface_from_font (&font);
- }
- XFreeFont (display, xfont);
- }
- }
- XFreeFontNames (names);
+ xft_font = xft_open_font (display, rfont->spec.file, size / 10,
+ FcTrue);
+ if (xft_font)
+ rfont_xft->font_no_aa = xft_font;
+ else
+ xft_font = rfont->fontp;
}
+ }
- if (app_data.reverse_video == True)
- {
- if (! face)
- face = mface ();
- mface_put_prop (face, Mvideomode, Mreverse);
- }
- if (face)
+ XftDrawChange (xft_draw, (Drawable) win);
+ XftDrawSetClip (xft_draw, (Region) region);
+
+ y -= rfont->baseline_offset;
+ 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 && !g->left_padding && !g->right_padding)
+ glyphs[nglyphs++] = g->code;
+ else
{
- mplist_push (param, Mface, face);
- M17N_OBJECT_UNREF (face);
+ if (nglyphs > 0)
+ XftDrawGlyphs (xft_draw, xft_color, xft_font,
+ last_x, y, glyphs, nglyphs);
+ nglyphs = 0;
+ XftDrawGlyphs (xft_draw, xft_color, xft_font,
+ x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
+ last_x = x + g->width;
}
- device->foreground
- = get_color (display, cmap, msymbol (app_data.foreground), Mnil,
- device->foreground);
- device->background
- = get_color (display, cmap, msymbol (app_data.background), Mnil,
- device->background);
}
- XSetErrorHandler (x_error_handler);
- /* XSetIOErrorHandler (x_io_error_handler); */
+ if (nglyphs > 0)
+ XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
+}
- return device;
+static int
+xft_check_capability (MRealizedFont *rfont, MSymbol capability)
+{
+ MRealizedFontXft *rfont_xft = rfont->info;
+ int result;
+
+ rfont->info = rfont_xft->info;
+ result = mfont__ft_driver.check_capability (rfont, capability);
+ rfont->info = rfont_xft;
+ return result;
}
-void
+#endif /* HAVE_XFT2 */
+
+\f
+/* Functions for the device driver. */
+
+static void
mwin__close_device (MFrame *frame)
{
- M17N_OBJECT_UNREF (frame->device);
+ MWDevice *device = FRAME_DEVICE (frame);
+
+ M17N_OBJECT_UNREF (device);
}
-void *
-mwin__device_get_prop (MWDevice *device, MSymbol key)
+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 NULL;
}
-struct {
- int size, inc, used;
- GC *gc_table;
-} gc_list;
-
-#define REGISTER_GC(gc) \
- do { \
- if (! gc_list.size) \
- MLIST_INIT1 (&gc_list, gc_table, 100); \
- MLIST_APPEND1 (&gc_list, gc_table, gc, MERROR_WIN); \
- } while (0)
-
-
-#define UNREGISTER_GC(gc) \
- do { \
- int j; \
- for (j = 0; j < gc_list.used; j++) \
- if (gc_list.gc_table[j] == gc) \
- gc_list.gc_table[j] = (GC) NULL; \
- } while (0)
-
-
-void
+static void
mwin__realize_face (MRealizedFace *rface)
{
- MFrame *frame = rface->frame;
- MWDevice *device = frame->device;
- Display *display = FRAME_DISPLAY (frame);
- XGCValues values;
- int mask = GCForeground | GCBackground;
- MSymbol foreground = rface->face.property[MFACE_FOREGROUND];
- MSymbol background = rface->face.property[MFACE_BACKGROUND];
- MFaceHLineProp *hline = rface->hline;
- MFaceBoxProp *box = rface->box;
- MFaceHookFunc func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
- MSymbol default_foreground
- = (MSymbol) mface_get_prop (frame->face, Mforeground);
- MSymbol default_background
- = (MSymbol) mface_get_prop (frame->face, Mbackground);
- GC *gcs;
- unsigned long pixel;
-
- MTABLE_CALLOC (gcs, MFACE_GCS, MERROR_WIN);
-
- values.foreground = get_color (display, device->cmap, foreground,
- default_foreground, device->foreground);
- values.background = get_color (display, device->cmap, background,
- default_background, device->background);
- if (rface->face.property[MFACE_VIDEOMODE] == Mreverse)
- pixel = values.foreground,
- values.foreground = values.background,
- values.background = pixel;
-
- if (rface->rfont
- && rface->rfont->font.property[MFONT_TYPE] - 1 == MFONT_TYPE_WIN)
+ MFrame *frame;
+ MSymbol foreground, background, videomode;
+ MFaceHLineProp *hline;
+ MFaceBoxProp *box;
+ GCInfo *info;
+
+ if (rface != rface->ascii_rface)
{
- values.font = ((MXFontInfo *) (rface->rfont->info))->f->fid;
- mask |= GCFont;
+ rface->info = rface->ascii_rface->info;
+ return;
}
- gcs[MFACE_GC_NORMAL] = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_NORMAL]);
-
- gcs[MFACE_GC_SCRATCH] = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_SCRATCH]);
+ frame = rface->frame;
+ MSTRUCT_CALLOC (info, MERROR_WIN);
- pixel = values.foreground;
- values.foreground = values.background;
- values.background = pixel;
- gcs[MFACE_GC_INVERSE] = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_INVERSE]);
- values.background = values.foreground;
- values.foreground = pixel;
-
- mask &= ~GCFont;
-
- if (rface == rface->ascii_rface)
+ 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)
{
- /* This realized face is for ASCII. Setup GCs for hline and
- box. */
- if (hline && hline->color != foreground)
- {
- values.foreground
- = get_color (display, device->cmap, hline->color,
- default_foreground, device->foreground);
- gcs[MFACE_GC_HLINE]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_HLINE]);
- values.foreground = pixel;
- }
-
- if (box)
- {
- if (box->color_top)
- {
- values.foreground
- = get_color (display, device->cmap, box->color_top,
- default_foreground, device->foreground);
- gcs[MFACE_GC_BOX_TOP]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_BOX_TOP]);
- }
-
- if (box->color_left
- && box->color_left != box->color_top)
- {
- values.foreground
- = get_color (display, device->cmap, box->color_left,
- default_foreground, device->foreground);
- gcs[MFACE_GC_BOX_LEFT]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_BOX_LEFT]);
- }
-
- if (box->color_right
- && box->color_right != box->color_top)
- {
- values.foreground
- = get_color (display, device->cmap, box->color_right,
- default_foreground, device->foreground);
- gcs[MFACE_GC_BOX_RIGHT]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_BOX_RIGHT]);
- }
-
- if (box->color_bottom
- && box->color_bottom != box->color_top)
- {
- values.foreground
- = get_color (display, device->cmap, box->color_bottom,
- default_foreground, device->foreground);
- gcs[MFACE_GC_BOX_BOTTOM]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_BOX_BOTTOM]);
- }
- }
+ 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
{
- /* This realized face is not for ASCII. GCs for hline and box
- are shared with that of the corresponding ASCII face. */
- GC *ascii_gcs = rface->ascii_rface->info;
- int i;
+ 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)
+ foreground = frame->foreground;
+ if (background == Mnil)
+ background = frame->background;
+ if (videomode == Mreverse)
+ {
+ MSymbol temp = foreground;
+ foreground = background;
+ background = temp;
+ }
+ if (! XftColorAllocName (FRAME_DISPLAY (frame),
+ FRAME_VISUAL (frame),
+ FRAME_CMAP (frame),
+ MSYMBOL_NAME (foreground),
+ &info->xft_color_fore))
+ mdebug_hook ();
+ if (! XftColorAllocName (FRAME_DISPLAY (frame),
+ FRAME_VISUAL (frame),
+ FRAME_CMAP (frame),
+ MSYMBOL_NAME (background),
+ &info->xft_color_back))
+ mdebug_hook ();
+#endif /* HAVE_XFT2 */
+
+ hline = rface->hline;
+ if (hline)
+ {
+ if (hline->color)
+ info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
+ else
+ info->gc[GC_HLINE] = info->gc[GC_NORMAL];
+ }
+
+ box = rface->box;
+ if (box)
+ {
+ if (box->color_top)
+ info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
+ else
+ info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
- for (i = MFACE_GC_HLINE; i < MFACE_GCS; i++)
- gcs[i] = ascii_gcs[i];
+ if (box->color_left && box->color_left != box->color_top)
+ info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
+ else
+ info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
+
+ if (box->color_bottom && box->color_bottom != box->color_top)
+ info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
+ else
+ info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
+
+ if (box->color_right && box->color_right != box->color_bottom)
+ info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
+ else
+ info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
}
- rface->info = gcs;
- if (func)
- (func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]);
+ rface->info = info;
}
-void
+static void
mwin__free_realized_face (MRealizedFace *rface)
{
- GC *gcs = rface->info;
- enum face_gc limit
- = rface == rface->ascii_rface ? MFACE_GCS : MFACE_GC_HLINE;
- int i;
-
- for (i = 0; i < limit; i++)
- if (gcs[i])
- {
- UNREGISTER_GC (gcs[i]);
- XFreeGC (FRAME_DISPLAY (rface->frame), gcs[i]);
- }
- free (gcs);
+ if (rface == rface->ascii_rface)
+ free (rface->info);
}
-void
+static void
mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
int reverse,
int x, int y, int width, int height, MDrawRegion region)
{
- GC *gcs = rface->info;
- GC gc = gcs[reverse ? MFACE_GC_NORMAL : MFACE_GC_INVERSE];
+ GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
if (region)
- gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
+ gc = set_region (frame, gc, region);
XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
x, y, width, height);
}
-void
+static void
+mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
+ MGlyphString *gstring, MGlyph *from, MGlyph *to,
+ int reverse, MDrawRegion region)
+{
+ MRealizedFace *rface = from->rface;
+ Display *display = FRAME_DISPLAY (rface->frame);
+ GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
+
+ if (from == to)
+ return;
+
+ if (region)
+ gc = set_region (rface->frame, gc, region);
+ for (; from < to; from++)
+ {
+ XDrawRectangle (display, (Window) win, gc,
+ x, y - gstring->ascent + 1, from->width - 1,
+ gstring->ascent + gstring->descent - 2);
+ x += from->width;
+ }
+}
+
+
+static void
mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
MRealizedFace *rface, int reverse,
int x, int y, int width, MDrawRegion region)
{
enum MFaceHLineType type = rface->hline->type;
- GC *gcs = rface->info;
- GC gc;
+ GCInfo *info = rface->info;
+ GC gc = gc = info->gc[GC_HLINE];
int i;
y = (type == MFACE_HLINE_BOTTOM
: type == MFACE_HLINE_STRIKE_THROUGH
? y - ((gstring->ascent + gstring->descent) / 2)
: y - gstring->text_ascent);
- if (reverse)
- gc = gcs[MFACE_GC_INVERSE];
- else if (gcs[MFACE_GC_HLINE])
- gc = gcs[MFACE_GC_HLINE];
- else
- gc = gcs[MFACE_GC_NORMAL];
-
if (region)
- gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
+ gc = set_region (frame, gc, region);
for (i = 0; i < rface->hline->width; i++)
XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
}
-void
+static void
mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
MGlyph *g, int x, int y, int width, MDrawRegion region)
{
Display *display = FRAME_DISPLAY (frame);
MRealizedFace *rface = g->rface;
MFaceBoxProp *box = rface->box;
- GC *gcs = rface->info;
+ GCInfo *info = rface->info;
GC gc_top, gc_left, gc_right, gc_btm;
int y0, y1;
int i;
y1 = y + (gstring->text_descent
+ rface->box->inner_vmargin + rface->box->width - 1);
- gc_top = gcs[MFACE_GC_BOX_TOP];
- if (! gc_top)
- gc_top = gcs[MFACE_GC_NORMAL];
+ gc_top = info->gc[GC_BOX_TOP];
if (region)
- gc_top = set_region (FRAME_DISPLAY (frame), rface, gc_top, region);
- gc_btm = gcs[MFACE_GC_BOX_BOTTOM];
- if (! gc_btm)
+ gc_top = set_region (frame, gc_top, region);
+ if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
gc_btm = gc_top;
+ else
+ gc_btm = info->gc[GC_BOX_BOTTOM];
if (g->type == GLYPH_BOX)
{
XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
/* Draw the bottom side. */
- if (region)
- gc_btm = set_region (display, rface, gc_btm, region);
+ if (region && gc_btm != gc_top)
+ gc_btm = set_region (frame, gc_btm, region);
for (i = 0; i < box->width; i++)
XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
if (g->left_padding > 0)
{
/* Draw the left side. */
- gc_left = gcs[MFACE_GC_BOX_LEFT];
- if (! gc_left)
+ if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
gc_left = gc_top;
- else if (region)
- gc_left = set_region (display, rface, gc_left, region);
+ else
+ {
+ gc_left = info->gc[GC_BOX_LEFT];
+ if (region)
+ gc_left = set_region (frame, gc_left, region);
+ }
for (i = 0; i < rface->box->width; i++)
XDrawLine (display, (Window) win, gc_left,
x0 + i, y0 + i, x0 + i, y1 - i);
else
{
/* Draw the right side. */
- gc_right = gcs[MFACE_GC_BOX_RIGHT];
- if (! gc_right)
+ if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
gc_right = gc_top;
- else if (region)
- gc_right = set_region (display, rface, gc_right, region);
+ else
+ {
+ gc_right = info->gc[GC_BOX_RIGHT];
+ if (region)
+ gc_right = set_region (frame, gc_right, region);
+ }
for (i = 0; i < rface->box->width; i++)
XDrawLine (display, (Window) win, gc_right,
x1 - i, y0 + i, x1 - i, y1 - i);
x, y0 + i, x + width - 1, y0 + i);
/* Draw the bottom side. */
- if (region)
- gc_btm = set_region (display, rface, gc_btm, region);
+ if (region && gc_btm != gc_top)
+ gc_btm = set_region (frame, gc_btm, region);
for (i = 0; i < box->width; i++)
XDrawLine (display, (Window) win, gc_btm,
x, y1 - i, x + width - 1, y1 - i);
}
-void
+#if 0
+static void
mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
int reverse, int x, int y,
int width, int height, int row_bytes, unsigned char *bmp,
{
Display *display = FRAME_DISPLAY (frame);
int i, j;
- GC *gcs = rface->info;
- GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
+ GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
if (region)
- gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
+ gc = set_region (frame, gc, region);
for (i = 0; i < height; i++, bmp += row_bytes)
for (j = 0; j < width; j++)
if (bmp[j / 8] & (1 << (7 - (j % 8))))
XDrawPoint (display, (Window) win, gc, x + j, y + i);
}
+#endif
+static void
+mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
+ int intensity, MDrawPoint *points, int num,
+ MDrawRegion region)
+{
+ GCInfo *info = rface->info;
+ GC gc;
-MDrawRegion
+ if (! (gc = info->gc[intensity]))
+ gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
+ info, intensity);
+ if (region)
+ gc = set_region (frame, gc, region);
+
+ XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
+ (XPoint *) points, num, CoordModeOrigin);
+}
+
+
+static MDrawRegion
mwin__region_from_rect (MDrawMetric *rect)
{
MDrawRegion region1 = XCreateRegion ();
return region2;
}
-void
+static void
mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
{
MDrawRegion region1 = XCreateRegion ();
XDestroyRegion (region1);
}
-void
+static void
mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
{
MDrawRegion region = XCreateRegion ();
XDestroyRegion (region);
}
-void
+static void
mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
{
MDrawRegion region1 = XCreateRegion ();
XDestroyRegion (region1);
}
-void
+static void
mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
{
XRectangle xrect;
rect->height = xrect.height;
}
-void
+static void
mwin__free_region (MDrawRegion region)
{
XDestroyRegion (region);
}
-void
+static void
mwin__dump_region (MDrawRegion region)
{
XRectangle rect;
fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
}
-void
-mwin__verify_region (MFrame *frame, MDrawRegion region)
-{
- set_region (FRAME_DISPLAY (frame), frame->rface,
- ((GC *) frame->rface->info)[MFACE_GC_NORMAL], region);
-}
-MDrawWindow
+static MDrawWindow
mwin__create_window (MFrame *frame, MDrawWindow parent)
{
- MWDevice *device = frame->device;
Display *display = FRAME_DISPLAY (frame);
- int screen = FRAME_SCREEN (frame);
Window win;
XWMHints wm_hints = { InputHint, False };
XClassHint class_hints = { "M17N-IM", "m17n-im" };
- XSetWindowAttributes attrs;
+ XSetWindowAttributes set_attrs;
unsigned long mask;
- MSymbol background = mface_get_prop (frame->face, Mbackground);
-
- attrs.background_pixel = get_color (display, device->cmap,
- background, background,
- WhitePixel (display, screen));
- attrs.backing_store = Always;
- attrs.override_redirect = True;
- attrs.save_under = True;
- mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
+ XGCValues values;
+ GCInfo *info = frame->rface->info;
+
if (! parent)
- parent = (MDrawWindow) RootWindow (display, screen);
+ parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
+ mask = GCForeground;
+ XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
+ set_attrs.background_pixel = values.foreground;
+ set_attrs.backing_store = Always;
+ set_attrs.override_redirect = True;
+ set_attrs.save_under = True;
+ mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
CopyFromParent, InputOutput, CopyFromParent,
- mask, &attrs);
+ mask, &set_attrs);
XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
NULL, &wm_hints, &class_hints);
XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
return (MDrawWindow) win;
}
-void
+static void
mwin__destroy_window (MFrame *frame, MDrawWindow win)
{
+#ifdef HAVE_XFT2
+ XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
+
+ if (XftDrawDrawable (xft_draw) == (Drawable) win)
+ XftDrawChange (xft_draw, FRAME_DEVICE (frame)->drawable);
+#endif /* HAVE_XFT2 */
XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
}
#if 0
-MDrawWindow
+static MDrawWindow
mwin__event_window (void *event)
{
return ((MDrawWindow) ((XEvent *) event)->xany.window);
}
-void
+static void
mwin__print_event (void *arg, char *win_name)
{
char *event_name;
}
#endif
-void
+static void
mwin__map_window (MFrame *frame, MDrawWindow win)
{
XMapRaised (FRAME_DISPLAY (frame), (Window) win);
}
-void
+static void
mwin__unmap_window (MFrame *frame, MDrawWindow win)
{
XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
}
-void
+static void
mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
MDrawMetric *geometry)
{
}
}
-void
+static void
mwin__adjust_window (MFrame *frame, MDrawWindow win,
MDrawMetric *current, MDrawMetric *new)
{
}
if (mask)
XConfigureWindow (display, (Window) win, mask, &values);
+ XClearWindow (display, (Window) win);
}
-MSymbol
+static MSymbol
mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
{
XEvent *event = (XEvent *) arg;
- MDisplayInfo *disp_info = frame->device->display_info;
+ MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
int len;
char buf[512];
KeySym keysym;
len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
if (len > 1)
return Mnil;
- if (len == 1)
+ if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
+ return Mnil;
+ if (len == 1 && keysym >= XK_space && keysym <= XK_asciitilde)
{
- int c = buf[0];
+ int c = keysym;
- if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
- *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
- if (((XKeyEvent *) event)->state & ControlMask)
- {
- c &= 0x1F;
- if (((XKeyEvent *) event)->state & ShiftMask)
- *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
- }
- if (((XKeyEvent *) event)->state & disp_info->meta_mask)
- c |= 0x80;
key = minput__char_to_key (c);
+ if (c == ' ' && ((XKeyEvent *) event)->state & ShiftMask)
+ *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
}
- else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
- return Mnil;
else
{
char *str = XKeysymToString (keysym);
key = msymbol (str);
if (((XKeyEvent *) event)->state & ShiftMask)
*modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
- if (((XKeyEvent *) event)->state & ControlMask)
- *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
}
+ if (((XKeyEvent *) event)->state & ControlMask)
+ *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
if (((XKeyEvent *) event)->state & disp_info->meta_mask)
*modifiers |= MINPUT_KEY_META_MODIFIER;
if (((XKeyEvent *) event)->state & disp_info->alt_mask)
}
-MText *
-mwin__get_selection_text (MFrame *frame)
-{
- return NULL;
-}
-
-
void
mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
{
unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
XGCValues values;
Display *display = FRAME_DISPLAY (frame);
- GC *gcs = rface->info;
+ GCInfo *info = rface->info;
int i;
- for (i = 0; i <= MFACE_GC_SCRATCH; i++)
+ for (i = 0; i <= GC_INVERSE; i++)
{
- XGetGCValues (display, gcs[i], valuemask, &values);
+ XGetGCValues (display, info->gc[i], valuemask, &values);
fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
values.foreground, values.background);
fprintf (stderr, "\n");
}
}
-/*** @} */
-#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
+static MDeviceDriver x_driver =
+ {
+ mwin__close_device,
+ mwin__device_get_prop,
+ mwin__realize_face,
+ mwin__free_realized_face,
+ mwin__fill_space,
+ mwin__draw_empty_boxes,
+ mwin__draw_hline,
+ mwin__draw_box,
+ mwin__draw_points,
+ mwin__region_from_rect,
+ mwin__union_rect_with_region,
+ mwin__intersect_region,
+ mwin__region_add_rect,
+ mwin__region_to_rect,
+ mwin__free_region,
+ mwin__dump_region,
+ mwin__create_window,
+ mwin__destroy_window,
+ mwin__map_window,
+ mwin__unmap_window,
+ mwin__window_geometry,
+ mwin__adjust_window,
+ 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.list = mfont__ft_driver.list;
+ xft_driver.list_family_names = mfont__ft_driver.list_family_names;
+#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;
+}
+
+
+#ifdef X_SET_ERROR_HANDLER
+static int
+x_error_handler (Display *display, XErrorEvent *error)
+{
+ mdebug_hook ();
+ return 0;
+}
+
+static int
+x_io_error_handler (Display *display)
+{
+ mdebug_hook ();
+ return 0;
+}
+#endif
+
+/** 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;
+ MFont *font = NULL;
+ 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 ();
+ find_modifier_bits (disp_info);
+ disp_info->MULE_BASELINE_OFFSET
+ = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
+ disp_info->AVERAGE_WIDTH
+ = XInternAtom (display, "AVERAGE_WIDTH", False);
+ 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
+ && device->screen_num == screen_num)
+ break;
+ }
+
+ if (mplist_key (plist) != Mnil)
+ M17N_OBJECT_REF (device);
+ else
+ {
+ unsigned long valuemask = GCForeground;
+ XGCValues values;
+ double pixels, mm;
+
+ 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;
+ pixels = DisplayHeight (display, screen_num);
+ mm = DisplayHeightMM (display, screen_num);
+ device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
+ device->realized_face_list = mplist ();
+ device->realized_font_list = mplist ();
+ mplist_add (device->realized_font_list, Mt, NULL);
+ 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->dpi = device->resy;
+ 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;
+ }
+
+ if (strcmp (app_data.font, DEFAULT_FONT) != 0)
+ {
+ XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
+ unsigned long value;
+ char *name;
+
+ if (xfont)
+ {
+ font = mfont_parse_name (app_data.font, Mx);
+ if (! font
+ && XGetFontProperty (xfont, XA_FONT, &value)
+ && (name = ((char *) XGetAtomName (display, (Atom) value))))
+ font = mfont_parse_name (name, Mx);
+ XFreeFont (display, xfont);
+ }
+ }
+ if (! font)
+ font = mfont_parse_name (DEFAULT_FONT, Mx);
+ else if (! font->size)
+ font->size = 130;
+ face = mface_from_font (font);
+ free (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
-/* External API */
-/*=*/
-/*** @addtogroup m17nFrame */
-/*** @{ */
-/*=*/
+/* XIM (X Input Method) handler */
-/***en
- @name Variables: Keys of frame parameter (X specific).
+typedef struct MInputXIMMethodInfo
+{
+ Display *display;
+ XIM xim;
+ MSymbol language;
+ MSymbol coding;
+} MInputXIMMethodInfo;
- These are the symbols to use as parameter keys for the function
- mframe () (which see). They are also keys of a frame property
- (except for #Mwidget). */
+typedef struct MInputXIMContextInfo
+{
+ XIC xic;
+ Window win;
+ MConverter *converter;
+} MInputXIMContextInfo;
+
+static int
+xim_open_im (MInputMethod *im)
+{
+ MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
+ MLocale *saved, *this;
+ char *save_modifier_list;
+ XIM xim;
+ MInputXIMMethodInfo *im_info;
+
+ saved = mlocale_set (LC_CTYPE, NULL);
+ this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
+ if (! this)
+ /* The specified locale is not supported. */
+ MERROR (MERROR_LOCALE, -1);
+ if (mlocale_get_prop (this, Mcoding) == Mnil)
+ {
+ /* Unable to decode the output of XIM. */
+ mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
+ MERROR (MERROR_LOCALE, -1);
+ }
+
+ if (arg->modifier_list)
+ save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
+ else
+ save_modifier_list = XSetLocaleModifiers ("");
+ if (! save_modifier_list)
+ {
+ /* The specified locale is not supported by X. */
+ mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
+ MERROR (MERROR_LOCALE, -1);
+ }
+
+ xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
+ if (! xim)
+ {
+ /* No input method is available in the current locale. */
+ XSetLocaleModifiers (save_modifier_list);
+ mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
+ MERROR (MERROR_WIN, -1);
+ }
+
+ MSTRUCT_MALLOC (im_info, MERROR_WIN);
+ im_info->display = arg->display;
+ im_info->xim = xim;
+ im_info->language = mlocale_get_prop (this, Mlanguage);
+ im_info->coding = mlocale_get_prop (this, Mcoding);
+ im->info = im_info;
+
+ XSetLocaleModifiers (save_modifier_list);
+ mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
+
+ return 0;
+}
+
+static void
+xim_close_im (MInputMethod *im)
+{
+ MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
+
+ XCloseIM (im_info->xim);
+ free (im_info);
+}
+
+static int
+xim_create_ic (MInputContext *ic)
+{
+ MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
+ MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
+ MInputXIMContextInfo *ic_info;
+ XIC xic;
+
+ if (! arg->input_style)
+ {
+ /* By default, use Root style. */
+ arg->input_style = XIMPreeditNothing | XIMStatusNothing;
+ arg->preedit_attrs = NULL;
+ arg->status_attrs = NULL;
+ }
+
+ if (! arg->preedit_attrs && ! arg->status_attrs)
+ xic = XCreateIC (im_info->xim,
+ XNInputStyle, arg->input_style,
+ XNClientWindow, arg->client_win,
+ XNFocusWindow, arg->focus_win,
+ NULL);
+ else if (arg->preedit_attrs && ! arg->status_attrs)
+ xic = XCreateIC (im_info->xim,
+ XNInputStyle, arg->input_style,
+ XNClientWindow, arg->client_win,
+ XNFocusWindow, arg->focus_win,
+ XNPreeditAttributes, arg->preedit_attrs,
+ NULL);
+ else if (! arg->preedit_attrs && arg->status_attrs)
+ xic = XCreateIC (im_info->xim,
+ XNInputStyle, arg->input_style,
+ XNClientWindow, arg->client_win,
+ XNFocusWindow, arg->focus_win,
+ XNStatusAttributes, arg->status_attrs,
+ NULL);
+ else
+ xic = XCreateIC (im_info->xim,
+ XNInputStyle, arg->input_style,
+ XNClientWindow, arg->client_win,
+ XNFocusWindow, arg->focus_win,
+ XNPreeditAttributes, arg->preedit_attrs,
+ XNStatusAttributes, arg->status_attrs,
+ NULL);
+ if (! xic)
+ MERROR (MERROR_WIN, -1);
+
+ MSTRUCT_MALLOC (ic_info, MERROR_WIN);
+ ic_info->xic = xic;
+ ic_info->win = arg->focus_win;
+ ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
+ ic->info = ic_info;
+ return 0;
+}
+
+static void
+xim_destroy_ic (MInputContext *ic)
+{
+ MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
+
+ XDestroyIC (ic_info->xic);
+ mconv_free_converter (ic_info->converter);
+ free (ic_info);
+ ic->info = NULL;
+}
+
+static int
+xim_filter (MInputContext *ic, MSymbol key, void *event)
+{
+ MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
+
+ return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
+}
+
+
+static int
+xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
+{
+ MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
+ MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
+ XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
+ KeySym keysym;
+ Status status;
+ char *buf;
+ int len;
+
+ buf = (char *) alloca (512);
+ len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
+ if (status == XBufferOverflow)
+ {
+ buf = (char *) alloca (len);
+ len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
+ }
+
+ mtext_reset (ic->produced);
+ if (len == 0)
+ return 1;
+
+ mconv_reset_converter (ic_info->converter);
+ mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
+ mconv_decode (ic_info->converter, ic->produced);
+ mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
+ Mlanguage, (void *) im_info->language);
+ mtext_cpy (mt, ic->produced);
+ mtext_reset (ic->produced);
+ return 0;
+}
+
+\f
/*=*/
-/*** @{ */
-/* Keywords for mwin__open_device (). */
-MSymbol Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap;
/*** @} */
-/*** @} */
+#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
+\f
+/* External API */
-/*=*/
/*** @addtogroup m17nInputMethodWin */
-/*=*/
+
/*** @{ */
/***en
- @brief Input driver for XIM.
+ @brief Input method driver for XIM.
- The input driver #minput_xim_driver is for the foreign input
- method of name #Mxim. It uses XIM (X Input Methods) as a
- background input engine.
+ The driver #minput_xim_driver is for the foreign input method of
+ name #Mxim. It uses XIM (X Input Methods) as a background input
+ engine.
As the symbol #Mxim has property #Minput_driver whose value is
a pointer to this driver, the input method of language #Mnil
The argument $ARG of the function minput_open_im () must be a
pointer to the structure #MInputXIMArgIM. See the documentation
- of #MInputXIMArgIM for more detail.
+ of #MInputXIMArgIM for more details.
The argument $ARG of the function minput_create_ic () must be a
pointer to the structure #MInputXIMArgIC. See the documentation
- of #MInputXIMArgIC for more detail.
+ of #MInputXIMArgIC for more details.
The argument $ARG of the function minput_filter () must be a
pointer to the structure @c XEvent. The argument $KEY is ignored.
$KEY is ignored. */
/***ja
- @brief XIMÍÑÆþÎϥɥ饤¥Ð
+ @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,
xim_filter, xim_lookup, NULL };
-/*=*/
-
-/***en
- @brief Symbol of the name "xim".
+/*** @} */
- The variable Mxim is a symbol of name "xim". It is a name of the
- input method driver #minput_xim_driver. */
+#else /* not HAVE_X11 */
-MSymbol Mxim;
+int device_open () { return -1; }
-/*** @} */
+#endif /* not HAVE_X11 */
/*
Local Variables: