X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fm17n-X.c;h=80cbeb37f1c294e1eaeb766ea76368f561af1af3;hb=6ac495c3a791ab71a4fb0a19b2d9f88f77efb558;hp=81b00e53d870c98365b938f6cb78a7dbebf8d443;hpb=2fec1623fce1ba514533b04dc98daf38e4fb4ce9;p=m17n%2Fm17n-lib.git diff --git a/src/m17n-X.c b/src/m17n-X.c index 81b00e5..80cbeb3 100644 --- a/src/m17n-X.c +++ b/src/m17n-X.c @@ -17,15 +17,17 @@ 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 #include #include @@ -43,6 +45,7 @@ #ifdef HAVE_XFT2 #include +#include #endif /* HAVE_XFT2 */ #include "m17n-gui.h" @@ -56,19 +59,6 @@ #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. */ @@ -82,14 +72,9 @@ typedef struct /** 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 already contains all available fonts on the display. */ int all_fonts_scaned; @@ -99,6 +84,9 @@ typedef struct int alt_mask; int super_mask; int hyper_mask; + + Atom MULE_BASELINE_OFFSET; + Atom AVERAGE_WIDTH; } MDisplayInfo; /* Anchor of the chain of MDisplayInfo objects. */ @@ -153,6 +141,8 @@ typedef struct GC scratch_gc; + int resy; + #ifdef HAVE_XFT2 XftDraw *xft_draw; #endif @@ -160,8 +150,8 @@ typedef struct /** List of pointers to realized faces on the frame. */ MPlist *realized_face_list; - /* List of information about each font. Keys are font registries, - values are (MFontInfo *). */ + /* 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. */ @@ -182,8 +172,7 @@ static MSymbol M_iso8859_1, M_iso10646_1; #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 { @@ -197,18 +186,15 @@ static void 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); @@ -227,8 +213,8 @@ free_device (void *object) mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist)); M17N_OBJECT_UNREF (device->realized_fontset_list); - MPLIST_DO (plist, device->realized_font_list) - mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist)); + 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) @@ -421,19 +407,21 @@ set_region (MFrame *frame, GC gc, MDrawRegion region) /** 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) @@ -446,83 +434,96 @@ xfont_registry_list (MFrame *frame, MSymbol registry) { MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info; MPlist *font_list = disp_info->font_list; - MPlist *base_font_list = disp_info->base_font_list; MPlist *plist, *p; char pattern[1024]; 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; @@ -544,147 +545,148 @@ xfont_list_all (MFrame *frame) 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; } @@ -694,8 +696,7 @@ static void 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++) @@ -759,29 +760,46 @@ xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring, 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; @@ -825,23 +843,20 @@ xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring, 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++) { @@ -881,7 +896,8 @@ xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring, 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++; } @@ -894,82 +910,113 @@ xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring, 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; } @@ -980,118 +1027,165 @@ xfont_list (MFrame *frame, MPlist *plist, MFont *font, MSymbol language, 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; @@ -1101,6 +1195,41 @@ xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring, } } +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, @@ -1109,15 +1238,16 @@ 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; @@ -1126,9 +1256,43 @@ xft_render (MDrawWindow win, int x, int y, 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) { @@ -1149,7 +1313,19 @@ xft_render (MDrawWindow win, int x, int y, 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 */ /* Functions for the device driver. */ @@ -1157,7 +1333,9 @@ xft_render (MDrawWindow win, int x, int y, static void mwin__close_device (MFrame *frame) { - M17N_OBJECT_UNREF (FRAME_DEVICE (frame)); + MWDevice *device = FRAME_DEVICE (frame); + + M17N_OBJECT_UNREF (device); } static void * @@ -1233,7 +1411,7 @@ mwin__realize_face (MRealizedFace *rface) MSYMBOL_NAME (background), &info->xft_color_back)) mdebug_hook (); -#endif +#endif /* HAVE_XFT2 */ hline = rface->hline; if (hline) @@ -1593,6 +1771,12 @@ mwin__create_window (MFrame *frame, MDrawWindow parent) 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); } @@ -1742,7 +1926,7 @@ mwin__parse_event (MFrame *frame, void *arg, int *modifiers) int len; char buf[512]; KeySym keysym; - MSymbol key = Mnil; + MSymbol key; *modifiers = 0; if (event->xany.type != KeyPress @@ -1752,26 +1936,17 @@ mwin__parse_event (MFrame *frame, void *arg, int *modifiers) 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); @@ -1780,9 +1955,9 @@ mwin__parse_event (MFrame *frame, void *arg, int *modifiers) 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) @@ -1854,8 +2029,8 @@ device_init () #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"); @@ -1872,6 +2047,23 @@ device_fini () 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. @@ -1896,6 +2088,7 @@ device_open (MFrame *frame, MPlist *param) unsigned depth = 0; MPlist *plist; AppData app_data; + MFont *font = NULL; MFace *face; int use_xfont = 0, use_freetype = 0, use_xft = 0; @@ -1993,8 +2186,11 @@ device_open (MFrame *frame, MPlist *param) 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); } @@ -2004,7 +2200,8 @@ device_open (MFrame *frame, MPlist *param) 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; } @@ -2014,6 +2211,7 @@ device_open (MFrame *frame, MPlist *param) { unsigned long valuemask = GCForeground; XGCValues values; + double pixels, mm; M17N_OBJECT (device, free_device, MERROR_WIN); device->display_info = disp_info; @@ -2024,8 +2222,12 @@ device_open (MFrame *frame, MPlist *param) 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); @@ -2040,6 +2242,7 @@ device_open (MFrame *frame, MPlist *param) 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 @@ -2087,41 +2290,28 @@ device_open (MFrame *frame, MPlist *param) 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; @@ -2138,7 +2328,6 @@ device_open (MFrame *frame, MPlist *param) XSetErrorHandler (x_error_handler); XSetIOErrorHandler (x_io_error_handler); #endif - return 0; } @@ -2333,23 +2522,6 @@ xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt) } - -#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 - /*=*/ /*** @} */ @@ -2358,7 +2530,7 @@ x_io_error_handler (Display *display) /* External API */ /*** @addtogroup m17nInputMethodWin */ -/*=*/ + /*** @{ */ /***en @@ -2393,31 +2565,27 @@ x_io_error_handler (Display *display) /***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, @@ -2425,6 +2593,12 @@ MInputDriver minput_xim_driver = /*** @} */ +#else /* not HAVE_X11 */ + +int device_open () { return -1; } + +#endif /* not HAVE_X11 */ + /* Local Variables: coding: euc-japan