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 "config.h"
-
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef HAVE_XFT2
#include <X11/Xft/Xft.h>
+#include <fontconfig/fcfreetype.h>
#endif /* HAVE_XFT2 */
#include "m17n-gui.h"
#include "fontset.h"
#include "face.h"
-typedef struct {
- MFont core;
- unsigned int sizes[2];
-} MXFont;
-
-#define SET_SIZE(xfont, s) ((xfont)->sizes[(s) / 32] |= (1 << ((s) & 0x1F)))
-#define HAVE_SIZE(xfont, s) ((xfont)->sizes[(s) / 32] & (1 << ((s) & 0x1F)))
-
-typedef struct {
- int size, inc, used;
- MXFont *fonts;
-} MXFontList;
-
typedef struct
{
/* Common header for the m17n object. */
/** List of available X-core fonts on the display. Keys are
registries and values are plists whose keys are families and
- values are pointers to MXFontList. */
+ values are pointers to MFont. */
MPlist *font_list;
- /** List of available X-core fonts on the display. Keys are
- families and values are pointers to MFont. For each MFont, only
- these properties are important; FOUNDRY, FAMILY, REGISTRY. */
- MPlist *base_font_list;
-
/** Nonzero means that <font_list> already contains all available
fonts on the display. */
int all_fonts_scaned;
int alt_mask;
int super_mask;
int hyper_mask;
+
+ Atom MULE_BASELINE_OFFSET;
+ Atom AVERAGE_WIDTH;
} MDisplayInfo;
/* Anchor of the chain of MDisplayInfo objects. */
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 information about each font. Keys are font registries,
- values are (MFontInfo *). */
+ /* 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. */
#define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
FRAME_SCREEN (frame))
-#define DEFAULT_FONT "-misc-fixed-medium-r-normal--*-120-*-*-*-*-iso8859-1"
-#define FALLBACK_FONT "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1"
+#define DEFAULT_FONT "-*-*-medium-r-normal--13-*-*-*-c-*-iso8859-1"
typedef struct
{
free_display_info (void *object)
{
MDisplayInfo *disp_info = (MDisplayInfo *) object;
- MPlist *plist, *p;
+ MPlist *plist, *pl;
MPLIST_DO (plist, disp_info->font_list)
{
- MPLIST_DO (p, MPLIST_VAL (plist))
- free (MPLIST_VAL (p));
+ MPLIST_DO (pl, MPLIST_VAL (plist))
+ free (MPLIST_VAL (pl));
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
}
M17N_OBJECT_UNREF (disp_info->font_list);
- MPLIST_DO (plist, disp_info->base_font_list)
- free (MPLIST_VAL (plist));
- M17N_OBJECT_UNREF (disp_info->base_font_list);
if (disp_info->auto_display)
XCloseDisplay (disp_info->display);
mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
M17N_OBJECT_UNREF (device->realized_fontset_list);
- MPLIST_DO (plist, device->realized_font_list)
- mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist));
+ 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)
\f
/** X font handler */
-static MRealizedFont *xfont_select (MFrame *, MFont *, MFont *, int);
-static int xfont_open (MRealizedFont *);
+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 unsigned xfont_encode_char (MRealizedFont *, unsigned);
+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 *frame, MPlist *plist,
- MFont *font, MSymbol language, int maxnum);
-
+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 MFontDriver xfont_driver =
{ xfont_select, xfont_open,
- xfont_find_metric, xfont_encode_char, xfont_render, xfont_list };
+ xfont_find_metric, xfont_has_char, xfont_encode_char,
+ xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability };
static int
font_compare (const void *p1, const void *p2)
{
MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
MPlist *font_list = disp_info->font_list;
- MPlist *base_font_list = disp_info->base_font_list;
MPlist *plist, *p;
char pattern[1024];
char **font_names, **names;
int nfonts;
int i, j;
- MXFont font;
- MXFontList *xfont_table;
- MFont *bfont = NULL;
+ MFont font;
+ int for_full_width;
plist = mplist_get (font_list, registry);
if (plist)
return plist;
- plist = mplist ();
+ 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);
- for (i = 0, p = NULL; i < nfonts; i++)
- if (mfont__parse_name_into_font (names[i], Mx, (MFont *) &font) == 0
- && (font.core.property[MFONT_SIZE] > 0
- || font.core.property[MFONT_RESY] == 0))
+ 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 ((MFont *) &font, MFONT_FAMILY);
- int size = font.core.property[MFONT_SIZE] / 10;
+ 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;
- font.sizes[0] = font.sizes[1] = 0;
- SET_SIZE (&font, size);
-
- /* Handle fonts of the same base. */
+ /* 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];
- for (j = i + 1; j < nfonts && ! strncmp (names[i], names[j], base_len);
+ 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, (MFont *) &font) == 0
- && (font.core.property[MFONT_SIZE] > 0
- || font.core.property[MFONT_RESY] == 0))
+ if (mfont__parse_name_into_font (names[j], Mx, &font) == 0
+ && (font.size > 0 || font.property[MFONT_RESY] == 0))
{
- size = font.core.property[MFONT_SIZE] / 10;
- SET_SIZE (&font, size);
+ size = font.size / 10;
+ sizes[nsizes++] = size;
+ normal_size |= (size >= 6 && size <= 29);
}
- if (p && MPLIST_KEY (p) != family)
- p = mplist_find_by_key (plist, family);
- if (p)
- xfont_table = MPLIST_VAL (p);
- else
- {
- p = plist;
- MSTRUCT_MALLOC (xfont_table, MERROR_WIN);
- MLIST_INIT1 (xfont_table, fonts, 4);
- mplist_push (p, family, xfont_table);
- }
- MLIST_APPEND1 (xfont_table, fonts, font, MERROR_WIN);
- if (! bfont
- || (font.core.property[MFONT_FOUNDRY]
- != bfont->property[MFONT_FOUNDRY])
- || (font.core.property[MFONT_FAMILY]
- != bfont->property[MFONT_FAMILY]))
+ font.for_full_width = for_full_width;
+ font.type = MFONT_TYPE_OBJECT;
+ font.source = MFONT_SOURCE_X;
+ if (normal_size)
{
- MSTRUCT_MALLOC (bfont, MERROR_WIN);
- *bfont = font.core;
- for (j = MFONT_WEIGHT; j <= MFONT_ADSTYLE; j++)
- bfont->property[j] = 0;
- bfont->property[MFONT_SIZE] = bfont->property[MFONT_RESY] = 0;
- mplist_push (base_font_list, family, bfont);
+ 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);
}
+ 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;
xfont_registry_list (frame, MPLIST_KEY (p));
}
-
typedef struct
{
M17NObject control;
Display *display;
XFontStruct *xfont;
-} MXFontInfo;
+} MRealizedFontX;
/* The X font driver function SELECT. */
-static MRealizedFont *
-xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size){
-
- MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY);
- MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
- int requested_size = request->property[MFONT_SIZE];
- MRealizedFont *rfont;
- MPlist *plist;
- int i;
- MFont *best_font;
- int best_score, score;
-
- if (registry == Mnil
- || ! strchr (MSYMBOL_NAME (registry), '-'))
- return NULL;
-
- plist = xfont_registry_list (frame, registry);
- if (MPLIST_TAIL_P (plist))
- return NULL;
- best_score = -1, best_font = NULL;
- MPLIST_DO (plist, plist)
- {
- if (family == Mnil || family == MPLIST_KEY (plist))
- {
- MXFontList *xfont_table = MPLIST_VAL (plist);
+static MFont *
+xfont_select (MFrame *frame, MFont *font, int limited_size)
+{
+ MPlist *plist = mplist (), *pl;
+ int num = xfont_list (frame, plist, font, 0);
+ MFont *found = NULL;
- for (i = 0; i < xfont_table->used; i++)
- {
- MXFont *xfont = xfont_table->fonts + i;
- MFont *font = (MFont *) xfont;
- int size = requested_size / 10, s0, s1;
-
- for (s0 = size; s0 > 0 && ! HAVE_SIZE (xfont, s0); s0--);
- if (s0 * 10 == requested_size)
- /* Exact size match. */
- ;
- else if (xfont->sizes[0] & 1)
- /* Scalable font. */
- size = 0;
- else if (limited_size)
- /* We can't use a larger font. */
- continue;
- else if (s0 == 0)
- {
- for (s0 = size + 1; s0 < 64 && ! HAVE_SIZE (xfont, s0); s0++);
- if (s0 == 64)
- continue;
- size = s0;
- }
- else
- {
- for (s1 = size + (size - s0) - 1;
- s1 > size && HAVE_SIZE (xfont, s1); s1++);
- size = (s1 > size ? s1 : s0);
- }
- font->property[MFONT_SIZE] = size * 10;
-
- if ((score = mfont__score (font, spec, request,
- limited_size)) >= 0
- && (best_score < 0 || score < best_score))
- {
- best_score = score;
- best_font = (MFont *) (xfont_table->fonts + i);
- if (best_score == 0)
- break;
- }
- }
- if (best_score == 0)
+ 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;
- }
- }
- if (! best_font)
- return NULL;
-
- MSTRUCT_CALLOC (rfont, MERROR_WIN);
- rfont->frame = frame;
- rfont->spec = *spec;
- rfont->request = *request;
- rfont->font = *best_font;
- if (best_font->property[MFONT_SIZE] == 0)
- rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE];
- rfont->score = best_score;
- return rfont;
+ }
+ }
+ M17N_OBJECT_UNREF (plist);
+ return found;
}
-
/* The X font driver function CLOSE. */
static void
close_xfont (void *object)
{
- MXFontInfo *xfont_info = object;
+ MRealizedFontX *x_rfont = object;
- XFreeFont (xfont_info->display, xfont_info->xfont);
- 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)
{
+ int size;
+ MRealizedFontX *x_rfont;
char *name;
- MXFontInfo *xfont_info;
- MFrame *frame = rfont->frame;
+ Display *display = FRAME_DISPLAY (frame);
+ XFontStruct *xfont;
int mdebug_mask = MDEBUG_FONT;
+ MFont this;
+
+ size = spec->size;
+ if (size)
+ {
+ int ratio = mfont_resize_ratio (font);
- /* This never fail to generate a valid fontname because open_spec
- should correspond to a font available on the system. */
- name = mfont_unparse_name (&rfont->font, Mx);
- M17N_OBJECT (xfont_info, close_xfont, MERROR_WIN);
- xfont_info->display = FRAME_DISPLAY (frame);
- xfont_info->xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
- if (! xfont_info->xfont)
+ if (ratio != 100)
+ size = size * ratio / 100;
+ }
+ 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;
+ }
+
+ if (rfont)
+ {
+ for (; rfont; rfont = rfont->next)
+ if (rfont->font == font && rfont->spec.size == size)
+ return rfont;
+ }
+
+ 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)
{
- rfont->status = -1;
- free (xfont_info);
MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
free (name);
- return -1;
+ font->type = MFONT_TYPE_FAILURE;
+ return NULL;
}
- rfont->info = xfont_info;
MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
free (name);
- rfont->status = 1;
- rfont->ascent = xfont_info->xfont->ascent;
- rfont->descent = xfont_info->xfont->descent;
- rfont->type = Mx;
- rfont->fontp = xfont_info->xfont;
- return 0;
+ 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;
}
xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
int from, int to)
{
- MXFontInfo *xfont_info = rfont->info;
- XFontStruct *xfont = xfont_info->xfont;
+ XFontStruct *xfont = rfont->fontp;
MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
for (; g != gend; g++)
g->descent = xfont->descent;
}
}
+ g->ascent += rfont->baseline_offset;
+ g->descent -= rfont->baseline_offset;
}
}
+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, unsigned code)
+xfont_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
{
- MXFontInfo *xfont_info;
+ MRealizedFont *rfont;
XFontStruct *xfont;
unsigned min_byte1, max_byte1, min_byte2, max_byte2;
int all_chars_exist;
- if (rfont->status < 0 || code >= 0x10000)
- return MCHAR_INVALID_CODE;
- 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 MCHAR_INVALID_CODE;
+ 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_info = rfont->info;
- xfont = xfont_info->xfont;
+ 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;
MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
{
MRealizedFace *rface = from->rface;
- MXFontInfo *xfont_info = rface->rfont->info;
- Display *display;
+ Display *display = FRAME_DISPLAY (rface->frame);
XChar2b *code;
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 (rface->frame, gc, region);
- XSetFont (display, gc, xfont_info->xfont->fid);
+ XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
for (i = 0, g = from; g < to; i++, g++)
{
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);
}
}
}
static int
-xfont_list (MFrame *frame, MPlist *plist, MFont *font, MSymbol language,
- int maxnum)
+xfont_list (MFrame *frame, MPlist *plist, MFont *font, int maxnum)
{
MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil;
MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil;
- MPlist *p, *pl;
+ int size = font ? font->size : 0;
+ MPlist *pl, *p;
int num = 0;
+ int mdebug_mask = MDEBUG_FONT;
- if (registry != Mnil)
- xfont_registry_list (frame, registry);
- else
- xfont_list_all (frame);
+ MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
+ family ? msymbol_name (family) : "*",
+ registry ? msymbol_name (registry) : "*");
- /* As we have not yet implemented the language check, return all
- base fonts. */
- if (! font)
- MPLIST_DO (p, disp_info->base_font_list)
- {
- mplist_add (plist, MPLIST_KEY (p), MPLIST_VAL (p));
- num++;
- if (num == maxnum)
- return num;
- }
+ if (registry == Mnil)
+ xfont_list_all (frame);
else
- {
- MXFontList *xfontlist;
- MXFont *xfont;
- int i;
-
- pl = disp_info->font_list;
- if (registry != Mnil)
- {
- pl = mplist_find_by_key (pl, registry);
- if (! pl)
- return 0;
- }
+ xfont_registry_list (frame, registry);
- MPLIST_DO (pl, pl)
- {
- p = MPLIST_VAL (pl);
- if (family != Mnil)
- {
- p = mplist_find_by_key (p, family);
- if (! p)
- return 0;
- }
- MPLIST_DO (p, p)
+ 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))
{
- xfontlist = MPLIST_VAL (p);
- for (i = 0; i < xfontlist->used; i++)
+ MFont *fontx = MPLIST_VAL (p);
+
+ if (! font || (mfont__match_p (fontx, font, MFONT_REGISTRY)))
{
- xfont = xfontlist->fonts + i;
- if (mfont__match_p (&xfont->core, font, MFONT_REGISTRY))
+ if (fontx->size != 0 && size)
{
- mplist_add (plist, MPLIST_KEY (p), &xfont->core);
- num++;
- if (num == maxnum)
- return num;
+ 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;
}
- if (family != Mnil)
- break;
}
- if (registry != Mnil)
+ }
+
+ done:
+ MDEBUG_PRINT1 (" %d found\n", num);
+ return num;
+}
+
+static void
+xfont_list_family_names (MFrame *frame, MPlist *plist)
+{
+ 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);
+
+ 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);
}
- return num;
+ if (font_names)
+ XFreeFontNames (font_names);
+}
+
+static int
+xfont_check_capability (MRealizedFont *rfont, MSymbol capability)
+{
+ /* Currently X font driver doesn't support any capability. */
+ return -1;
}
\f
typedef struct
{
M17NObject control;
+ FT_Face ft_face; /* This must be the 2nd member. */
Display *display;
XftFont *font_aa;
XftFont *font_no_aa;
-} MXftFontInfo;
-
-static int xft_open (MRealizedFont *);
+ /* 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);
-MFontDriver xft_driver =
- { NULL, /* Set to ft_select in device_init (). */
- xft_open, xft_find_metric,
- NULL, /* Set to ft_encode_char in device_init (). */
- xft_render,
- NULL /* Set to ft_list in device_init (). */
+static MFontDriver xft_driver =
+ { NULL, xft_open,
+ xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL, NULL,
+ xft_check_capability
};
-
static void
close_xft (void *object)
{
- MXftFontInfo *font_info = object;
+ MRealizedFontXft *rfont_xft = object;
- XftFontClose (font_info->display, font_info->font_aa);
- XftFontClose (font_info->display, font_info->font_no_aa);
- free (font_info);
+ 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 XftFont *
-xft_open_font (MFrame *frame, MFTInfo *ft_info, int size, int anti_alias)
+xft_open_font (Display *display, MSymbol file, double size,
+ FcBool anti_alias)
{
- XftPattern *pattern;
- XftFontInfo *xft_font_info;
+ FcPattern *pattern;
XftFont *font;
- pattern = XftPatternCreate ();
- XftPatternAddString (pattern, XFT_FILE, ft_info->filename);
- XftPatternAddDouble (pattern, XFT_PIXEL_SIZE, (double) size);
- XftPatternAddBool (pattern, XFT_ANTIALIAS, anti_alias);
- xft_font_info = XftFontInfoCreate (FRAME_DISPLAY (frame), pattern);
- if (! xft_font_info)
- return NULL;
- font = XftFontOpenInfo (FRAME_DISPLAY (frame), pattern, xft_font_info);
- XftFontInfoDestroy (FRAME_DISPLAY (frame), xft_font_info);
+ 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
-xft_open (MRealizedFont *rfont)
+static MRealizedFont *
+xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
{
- MFrame *frame;
- MFTInfo *ft_info;
- MXftFontInfo *font_info;
+ 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 ((mfont__ft_driver.open) (rfont) < 0)
- return -1;
+ if (font->size)
+ /* non-scalable font */
+ size = font->size;
+ else if (spec->size)
+ {
+ int ratio = mfont_resize_ratio (font);
- size = rfont->font.property[MFONT_SIZE] / 10;
- frame = rfont->frame;
+ size = ratio == 100 ? spec->size : spec->size * ratio / 100;
+ }
+ else
+ size = 120;
- ft_info = rfont->info;
- M17N_OBJECT (font_info, close_xft, MERROR_WIN);
- ft_info->extra_info = font_info;
- font_info->display = FRAME_DISPLAY (frame);
- font_info->font_aa = xft_open_font (frame, ft_info, size, 1);
- if (font_info->font_aa)
+ if (rfont)
{
- font_info->font_no_aa = xft_open_font (frame, ft_info, size, 0);
- if (font_info->font_no_aa)
- {
- rfont->type = Mxft;
- rfont->fontp = font_info->font_no_aa;
- return 0;
- }
- XftFontClose (FRAME_DISPLAY (rfont->frame), font_info->font_aa);
+ MRealizedFont *save = NULL;
+
+ 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;
}
- free (font_info);
- ft_info->extra_info = NULL;
- rfont->status = -1;
- return -1;
+ 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;
}
-
static void
xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
int from, int to)
{
- MFTInfo *ft_info = rfont->info;
- MXftFontInfo *font_info = ft_info->extra_info;
+ Display *display = FRAME_DISPLAY (rfont->frame);
+ XftFont *xft_font = rfont->fontp;
MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
for (; g != gend; g++)
{
if (g->code == MCHAR_INVALID_CODE)
{
- MGlyph *start = g++;
-
- while (g != gend && g->code == MCHAR_INVALID_CODE) g++;
- (mfont__ft_driver.find_metric) (rfont, gstring, GLYPH_INDEX (start),
- GLYPH_INDEX (g));
- g--;
+ 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 (FRAME_DISPLAY (gstring->frame),
- font_info->font_aa, &g->code, 1, &extents);
+ XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
g->lbearing = - extents.x;
g->rbearing = extents.width - extents.x;
g->width = extents.xOff;
}
}
+static int
+xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
+{
+ int result;
+
+ 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;
+}
+
+static unsigned
+xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
+{
+ 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;
+}
static void
xft_render (MDrawWindow win, int x, int y,
{
MRealizedFace *rface = from->rface;
MFrame *frame = rface->frame;
- MFTInfo *ft_info = rface->rfont->info;
- MXftFontInfo *font_info = ft_info->extra_info;
+ 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);
- XftFont *xft_font = (gstring->control.anti_alias
- && FRAME_DEVICE (frame)->depth > 1
- ? font_info->font_aa : font_info->font_no_aa);
+ int anti_alias = (gstring->control.anti_alias
+ && FRAME_DEVICE (frame)->depth > 1);
+ XftFont *xft_font;
MGlyph *g;
FT_UInt *glyphs;
int last_x;
if (from == to)
return;
+ if (anti_alias)
+ {
+ if (rfont_xft->font_aa)
+ xft_font = rfont_xft->font_aa;
+ else
+ {
+ double size = rfont->spec.size;
+
+ 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;
+ }
+ }
+ else
+ {
+ if (rfont_xft->font_no_aa)
+ xft_font = rfont_xft->font_no_aa;
+ else
+ {
+ double size = rfont->spec.size;
+
+ 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;
+ }
+ }
+
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)
{
XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
}
-#endif
+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;
+}
+
+#endif /* HAVE_XFT2 */
\f
/* Functions for the device driver. */
static void
mwin__close_device (MFrame *frame)
{
- M17N_OBJECT_UNREF (FRAME_DEVICE (frame));
+ MWDevice *device = FRAME_DEVICE (frame);
+
+ M17N_OBJECT_UNREF (device);
}
static void *
MSYMBOL_NAME (background),
&info->xft_color_back))
mdebug_hook ();
-#endif
+#endif /* HAVE_XFT2 */
hline = rface->hline;
if (hline)
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);
}
int len;
char buf[512];
KeySym keysym;
- MSymbol key = Mnil;
+ MSymbol key;
*modifiers = 0;
if (event->xany.type != KeyPress
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 = keysym;
- if (c < XK_space || c > XK_asciitilde)
- c = buf[0];
- if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
- *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
- if (((XKeyEvent *) event)->state & ControlMask)
- {
- if (c >= 'a' && c <= 'z')
- c += 'A' - 'a';
- if (c >= ' ' && c < 127)
- *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
- }
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;
- if (key == 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)
#ifdef HAVE_XFT2
xft_driver.select = mfont__ft_driver.select;
- xft_driver.encode_char = mfont__ft_driver.encode_char;
xft_driver.list = mfont__ft_driver.list;
+ xft_driver.list_family_names = mfont__ft_driver.list_family_names;
#endif
Mxim = msymbol ("xim");
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.
unsigned depth = 0;
MPlist *plist;
AppData app_data;
+ MFont *font = NULL;
MFace *face;
int use_xfont = 0, use_freetype = 0, use_xft = 0;
disp_info->display = display;
disp_info->auto_display = auto_display;
disp_info->font_list = mplist ();
- disp_info->base_font_list = mplist ();
find_modifier_bits (disp_info);
+ 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);
}
device = (MWDevice *) mplist_value (plist);
if (device->display_info == disp_info
&& device->depth == depth
- && device->cmap == cmap)
+ && device->cmap == cmap
+ && device->screen_num == screen_num)
break;
}
{
unsigned long valuemask = GCForeground;
XGCValues values;
+ double pixels, mm;
M17N_OBJECT (device, free_device, MERROR_WIN);
device->display_info = disp_info;
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);
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
frame->videomode = Mnormal;
}
- {
- int nfonts;
- char **names = XListFonts (display, app_data.font, 1, &nfonts);
-
- if (nfonts > 0)
- {
- if (! (frame->font = mfont_parse_name (names[0], Mx)))
- {
- /* The font name does not conform to XLFD. Try to open the
- font and get XA_FONT property. */
- XFontStruct *xfont = XLoadQueryFont (display, names[0]);
-
- nfonts = 0;
- if (xfont)
- {
- unsigned long value;
- char *name;
-
- if (XGetFontProperty (xfont, XA_FONT, &value)
- && (name = ((char *)
- XGetAtomName (display, (Atom) value))))
- {
- if ((frame->font = mfont_parse_name (name, Mx)))
- nfonts = 1;
- }
- XFreeFont (display, xfont);
- }
- }
- XFreeFontNames (names);
- }
- if (! nfonts)
- frame->font = mfont_parse_name (FALLBACK_FONT, Mx);
- }
+ if (strcmp (app_data.font, DEFAULT_FONT) != 0)
+ {
+ XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
+ unsigned long value;
+ char *name;
- face = mface_from_font (frame->font);
+ 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;
XSetErrorHandler (x_error_handler);
XSetIOErrorHandler (x_io_error_handler);
#endif
-
return 0;
}
}
\f
-
-#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
-
/*=*/
/*** @} */
/* External API */
/*** @addtogroup m17nInputMethodWin */
-/*=*/
+
/*** @{ */
/***en
/***ja
@brief XIMÍÑÆþÎϥɥ饤¥Ð.
- ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã
- ¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸
- ¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
+ ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
+ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
- #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç¤¢¤ëÆþÎÏ
- ¥á¥½¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
+ #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
+ ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
- ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø
- ¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
+ ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
+ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
- ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM ¤Ø¤Î¥Ý
- ¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò
- »²¾È¡£
+ ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
+ ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
- ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC ¤Ø¤Î
- ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ
- ¤ò»²¾È¡£
+ ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
+ ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
- ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿
- ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
+ ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
+ ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
- ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì
- ¤ë¡£ */
+ ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
MInputDriver minput_xim_driver =
{ xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
/*** @} */
+#else /* not HAVE_X11 */
+
+int device_open () { return -1; }
+
+#endif /* not HAVE_X11 */
+
/*
Local Variables:
coding: euc-japan