1 /* m17n-X.c -- implementation of the GUI API on X Windows.
2 Copyright (C) 2003, 2004
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
28 /*** @addtogroup m17nInternal
38 #include <X11/keysym.h>
39 #include <X11/Xlocale.h>
40 #include <X11/Xutil.h>
41 #include <X11/Xresource.h>
42 #include <X11/Xatom.h>
43 #include <X11/StringDefs.h>
44 #include <X11/Intrinsic.h>
47 #include <X11/Xft/Xft.h>
48 #include <fontconfig/fcfreetype.h>
49 #endif /* HAVE_XFT2 */
53 #include "m17n-misc.h"
55 #include "internal-gui.h"
62 typedef struct _MFontX MFontX;
66 /* Record a font of the smallest pixel size. */
68 /* Nth bit tells the existence of a font of size N + 5. So this is
69 for 5..36 pixel size fonts. Usually this covers all sizes. */
70 unsigned int size5_36;
71 /* Fonts of (size < 5 || size > 36) are listed here (except for a
72 scalable whose size is 0). */
76 /* S must satisfy the condition (S >= 5 && S < 36). */
78 #define SET_SIZE(FONTX, S) ((FONTX)->size5_36 |= (1 << ((S) - 5)))
80 #define HAVE_SIZE(FONTX, S) ((FONTX)->size5_36 & (1 << ((S) - 5)))
84 /* Common header for the m17n object. */
89 /* If nonzero, <display> is opened by this library. Thus it should
90 be closed on freeing this structure. */
93 /** List of available X-core fonts on the display. Keys are
94 registries and values are plists whose keys are families and
95 values are pointers to MFontX. */
98 /** Nonzero means that <font_list> already contains all available
99 fonts on the display. */
100 int all_fonts_scaned;
102 /** Modifier bit masks of the display. */
108 Atom MULE_BASELINE_OFFSET;
112 /* Anchor of the chain of MDisplayInfo objects. */
113 static MPlist *display_info_list;
116 /* Color value and the corresponding GC. */
119 unsigned int rgb; /* (red << 16) | (green << 8) | blue */
126 GC_NORMAL = GC_INVERSE + 7,
139 /* The first 8 elements are indexed by an intensity for
140 anti-aliasing. The 2nd to 7th are created on demand. */
143 XftColor xft_color_fore, xft_color_back;
149 /* Common header for the m17n object. */
152 MDisplayInfo *display_info;
170 /** List of pointers to realized faces on the frame. */
171 MPlist *realized_face_list;
173 /* List of single element whose value is a root of chain of realized
175 MPlist *realized_font_list;
177 /** List of pointers to realized fontsets on the frame. */
178 MPlist *realized_fontset_list;
180 /** List of XColors vs GCs on the frame. */
184 static MPlist *device_list;
186 static MSymbol M_iso8859_1, M_iso10646_1;
188 #define FRAME_DEVICE(frame) ((MWDevice *) (frame)->device)
189 #define FRAME_DISPLAY(frame) (FRAME_DEVICE (frame)->display_info->display)
190 #define FRAME_SCREEN(frame) (FRAME_DEVICE (frame)->screen_num)
191 #define FRAME_CMAP(frame) (FRAME_DEVICE (frame)->cmap)
192 #define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
193 FRAME_SCREEN (frame))
195 #define DEFAULT_FONT "-*-*-medium-r-normal--13-*-*-*-c-*-iso8859-1"
202 Boolean reverse_video;
203 } AppData, *AppDataPtr;
206 free_display_info (void *object)
208 MDisplayInfo *disp_info = (MDisplayInfo *) object;
211 MPLIST_DO (plist, disp_info->font_list)
213 MPLIST_DO (pl, MPLIST_VAL (plist))
215 MFontX *fontx, *next;
217 for (fontx = MPLIST_VAL (pl); fontx; fontx = next)
223 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
225 M17N_OBJECT_UNREF (disp_info->font_list);
227 if (disp_info->auto_display)
228 XCloseDisplay (disp_info->display);
234 free_device (void *object)
236 MWDevice *device = object;
239 for (plist = device->realized_fontset_list;
240 mplist_key (plist) != Mnil; plist = mplist_next (plist))
241 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
242 M17N_OBJECT_UNREF (device->realized_fontset_list);
244 if (MPLIST_VAL (device->realized_font_list))
245 mfont__free_realized (MPLIST_VAL (device->realized_font_list));
246 M17N_OBJECT_UNREF (device->realized_font_list);
248 MPLIST_DO (plist, device->realized_face_list)
250 MRealizedFace *rface = MPLIST_VAL (plist);
253 mface__free_realized (rface);
255 M17N_OBJECT_UNREF (device->realized_face_list);
257 MPLIST_DO (plist, device->gc_list)
259 XFreeGC (device->display_info->display,
260 ((RGB_GC *) MPLIST_VAL (plist))->gc);
261 free (MPLIST_VAL (plist));
263 M17N_OBJECT_UNREF (device->gc_list);
264 XFreeGC (device->display_info->display, device->scratch_gc);
267 XftDrawDestroy (device->xft_draw);
270 XFreePixmap (device->display_info->display, device->drawable);
271 M17N_OBJECT_UNREF (device->display_info);
277 find_modifier_bits (MDisplayInfo *disp_info)
279 Display *display = disp_info->display;
280 XModifierKeymap *mods;
281 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
282 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
283 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
284 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
285 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
286 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
287 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
288 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
291 mods = XGetModifierMapping (display);
292 /* We skip the first three sets for Shift, Lock, and Control. The
293 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
294 for (i = 3; i < 8; i++)
295 for (j = 0; j < mods->max_keypermod; j++)
297 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
301 if (code == meta_l || code == meta_r)
302 disp_info->meta_mask |= (1 << i);
303 else if (code == alt_l || code == alt_r)
304 disp_info->alt_mask |= (1 << i);
305 else if (code == super_l || code == super_r)
306 disp_info->super_mask |= (1 << i);
307 else if (code == hyper_l || code == hyper_r)
308 disp_info->hyper_mask |= (1 << i);
311 /* If meta keys are not in any modifier, use alt keys as meta
313 if (! disp_info->meta_mask)
315 disp_info->meta_mask = disp_info->alt_mask;
316 disp_info->alt_mask = 0;
318 /* If both meta and alt are assigned to the same modifier, give meta
320 if (disp_info->meta_mask & disp_info->alt_mask)
321 disp_info->alt_mask &= ~disp_info->meta_mask;
323 XFreeModifiermap (mods);
327 get_rgb_gc (MWDevice *device, XColor *xcolor)
329 int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
330 | (xcolor->blue >> 8));
333 unsigned long valuemask = GCForeground;
336 MPLIST_DO (plist, device->gc_list)
338 rgb_gc = MPLIST_VAL (plist);
340 if (rgb_gc->rgb == rgb)
342 if (rgb_gc->rgb > rgb)
346 if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
349 rgb_gc = malloc (sizeof (RGB_GC));
351 values.foreground = xcolor->pixel;
352 rgb_gc->gc = XCreateGC (device->display_info->display,
353 device->drawable, valuemask, &values);
354 mplist_push (plist, Mt, rgb_gc);
359 get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
361 MWDevice *device = FRAME_DEVICE (frame);
369 color = for_foreground ? frame->foreground : frame->background;
371 if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
372 msymbol_name (color), &xcolor))
374 rgb_gc = get_rgb_gc (device, &xcolor);
378 *rgb_ret = rgb_gc->rgb;
383 GCInfo *info = frame->rface->info;
388 rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
390 rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
398 get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
400 int rgb_fore, rgb_back;
405 if (info->gc[intensity])
406 return info->gc[intensity];
408 rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
409 xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
410 + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
411 xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
412 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
413 xcolor.blue = (((rgb_fore & 0xFF) * intensity
414 + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
415 rgb_gc = get_rgb_gc (device, &xcolor);
419 gc =get_gc_for_anti_alias (device, info,
420 intensity < 4 ? intensity - 1 : intensity + 1);
421 return (info->gc[intensity] = gc);
425 set_region (MFrame *frame, GC gc, MDrawRegion region)
427 unsigned long valuemask = GCForeground;
429 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
430 FRAME_DEVICE (frame)->scratch_gc);
431 XSetRegion (FRAME_DISPLAY (frame), FRAME_DEVICE (frame)->scratch_gc, region);
432 return FRAME_DEVICE (frame)->scratch_gc;
436 /** X font handler */
438 static MFont *xfont_select (MFrame *, MFont *, int);
439 static MRealizedFont *xfont_open (MFrame *, MFont *, MFont *, MRealizedFont *);
440 static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
441 static int xfont_has_char (MFrame *, MFont *, MFont *, int, unsigned);
442 static unsigned xfont_encode_char (MFrame *, MFont *, MFont *, unsigned);
443 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
444 MGlyph *, MGlyph *, int, MDrawRegion);
445 static int xfont_list (MFrame *, MPlist *, MFont *, int);
448 static MFontDriver xfont_driver =
449 { xfont_select, xfont_open,
450 xfont_find_metric, xfont_has_char, xfont_encode_char,
451 xfont_render, xfont_list };
454 font_compare (const void *p1, const void *p2)
456 return strcmp (*(char **) p1, *(char **) p2);
460 xfont_registry_list (MFrame *frame, MSymbol registry)
462 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
463 MPlist *font_list = disp_info->font_list;
466 char **font_names, **names;
472 plist = mplist_get (font_list, registry);
476 mplist_add (font_list, registry, plist);
477 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", msymbol_name (registry));
478 font_names = XListFonts (disp_info->display, pattern, 0x8000, &nfonts);
482 char *reg_name = msymbol_name (registry);
484 for_full_width = (strncmp (reg_name, "jis", 3) == 0
485 || strncmp (reg_name, "gb", 2) == 0
486 || strncmp (reg_name, "big5", 4) == 0
487 || strncmp (reg_name, "ksc", 3) == 0);
489 names = alloca (sizeof (char *) * nfonts);
490 memcpy (names, font_names, sizeof (char *) * nfonts);
491 qsort (names, nfonts, sizeof (char *), font_compare);
493 for (i = 0, p = NULL; i < nfonts; i++)
494 if (mfont__parse_name_into_font (names[i], Mx, &font) == 0
495 && (font.size >= 50 || font.property[MFONT_RESY] == 0))
497 MSymbol family = FONT_PROPERTY (&font, MFONT_FAMILY);
498 MFontX *fontx, *fontx2;
506 if (p && MPLIST_KEY (p) != family)
507 p = mplist_find_by_key (plist, family);
509 p = mplist_push (plist, family, NULL);
511 /* Calculate how many bytes to compare to detect fonts of the
513 for (base_end = names[i], fields = 0; *base_end; base_end++)
515 && ++fields == 7 /* PIXEL_SIZE */)
517 base_len = base_end - names[i] + 1;
519 size = smallest = font.size / 10;
520 sizes[nsizes++] = size;
521 for (j = i + 1; j < nfonts && ! strncmp (names[i], names[j], base_len);
523 if (mfont__parse_name_into_font (names[j], Mx, &font) == 0
524 && (font.size >= 50 || font.property[MFONT_RESY] == 0))
526 size = font.size / 10;
530 sizes[nsizes++] = size;
533 font.for_full_width = for_full_width;
534 font.type = MFONT_TYPE_OBJECT;
535 font.source = MFONT_SOURCE_X;
536 MSTRUCT_CALLOC (fontx, MERROR_WIN);
538 fontx->core.size = smallest * 10;
539 fontx->next = MPLIST_VAL (p);
540 MPLIST_VAL (p) = fontx;
542 for (j = 0; j < nsizes; j++)
546 if (sizes[j] != smallest)
547 SET_SIZE (fontx, sizes[j]);
551 MSTRUCT_CALLOC (fontx2, MERROR_WIN);
553 fontx2->core.size = sizes[j] * 10;
554 fontx2->next = MPLIST_VAL (p);
555 MPLIST_VAL (p) = fontx2;
559 XFreeFontNames (font_names);
564 xfont_list_all (MFrame *frame)
566 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
567 MPlist *font_encoding_list, *p;
569 if (disp_info->all_fonts_scaned)
571 disp_info->all_fonts_scaned = 1;
572 font_encoding_list = mfont__encoding_list ();
573 if (! font_encoding_list)
575 MPLIST_DO (p, font_encoding_list)
576 xfont_registry_list (frame, MPLIST_KEY (p));
586 /* The X font driver function SELECT. */
589 xfont_select (MFrame *frame, MFont *font, int limited_size)
591 MPlist *plist = mplist (), *pl;
592 int num = xfont_list (frame, plist, font, 0);
596 MPLIST_DO (pl, plist)
598 font = MPLIST_VAL (pl);
599 if (limited_size == 0
601 || font->size <= limited_size)
607 M17N_OBJECT_UNREF (plist);
611 /* The X font driver function CLOSE. */
614 close_xfont (void *object)
616 MRealizedFontX *x_rfont = object;
618 XFreeFont (x_rfont->display, x_rfont->xfont);
622 /* The X font driver function OPEN. */
624 static MRealizedFont *
625 xfont_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
627 int size = spec->size;
628 MRealizedFontX *x_rfont;
630 Display *display = FRAME_DISPLAY (frame);
632 int mdebug_mask = MDEBUG_FONT;
637 for (; rfont; rfont = rfont->next)
638 if (rfont->font == font && rfont->spec.size == size)
644 /* This never fail to generate a valid fontname. */
645 name = mfont_unparse_name (&this, Mx);
646 xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
649 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
651 font->type = MFONT_TYPE_FAILURE;
654 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
656 M17N_OBJECT (x_rfont, close_xfont, MERROR_FONT_X);
657 x_rfont->display = display;
658 x_rfont->xfont = xfont;
659 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
661 rfont->spec.type = MFONT_TYPE_REALIZED;
662 rfont->spec.source = MFONT_SOURCE_X;
663 rfont->frame = frame;
665 rfont->driver = &xfont_driver;
666 rfont->info = x_rfont;
668 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
671 rfont->baseline_offset
672 = (XGetFontProperty (xfont, disp_info->MULE_BASELINE_OFFSET, &value)
675 = (XGetFontProperty (xfont, disp_info->AVERAGE_WIDTH, &value)
676 ? (int) value / 10 : 0);
678 rfont->ascent = xfont->ascent + rfont->baseline_offset;
679 rfont->descent = xfont->descent - rfont->baseline_offset;
680 rfont->max_advance = xfont->max_bounds.width;
681 rfont->fontp = xfont;
682 rfont->next = MPLIST_VAL (frame->realized_font_list);
683 MPLIST_VAL (frame->realized_font_list) = rfont;
688 /* The X font driver function FIND_METRIC. */
691 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
694 XFontStruct *xfont = rfont->fontp;
695 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
697 for (; g != gend; g++)
699 if (g->code == MCHAR_INVALID_CODE)
701 g->lbearing = xfont->max_bounds.lbearing;
702 g->rbearing = xfont->max_bounds.rbearing;
703 g->width = xfont->max_bounds.width;
704 g->ascent = xfont->ascent;
705 g->descent = xfont->descent;
709 int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
710 XCharStruct *pcm = NULL;
712 if (xfont->per_char != NULL)
714 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
717 && byte2 >= xfont->min_char_or_byte2
718 && byte2 <= xfont->max_char_or_byte2)
719 pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
723 if (byte1 >= xfont->min_byte1
724 && byte1 <= xfont->max_byte1
725 && byte2 >= xfont->min_char_or_byte2
726 && byte2 <= xfont->max_char_or_byte2)
728 pcm = (xfont->per_char
729 + ((xfont->max_char_or_byte2
730 - xfont->min_char_or_byte2 + 1)
731 * (byte1 - xfont->min_byte1))
732 + (byte2 - xfont->min_char_or_byte2));
739 g->lbearing = pcm->lbearing;
740 g->rbearing = pcm->rbearing;
741 g->width = pcm->width;
742 g->ascent = pcm->ascent;
743 g->descent = pcm->descent;
747 /* If the per_char pointer is null, all glyphs between
748 the first and last character indexes inclusive have
749 the same information, as given by both min_bounds and
752 g->rbearing = xfont->max_bounds.width;
753 g->width = xfont->max_bounds.width;
754 g->ascent = xfont->ascent;
755 g->descent = xfont->descent;
758 g->ascent += rfont->baseline_offset;
759 g->descent -= rfont->baseline_offset;
765 xfont_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
767 return (xfont_encode_char (frame, font, spec, code) != MCHAR_INVALID_CODE);
770 /* The X font driver function GET_GLYPH_ID. */
773 xfont_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
775 MRealizedFont *rfont;
777 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
780 if (font->type == MFONT_TYPE_REALIZED)
781 rfont = (MRealizedFont *) font;
782 else if (font->type == MFONT_TYPE_OBJECT)
784 int size = spec->size;
786 for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
788 if (rfont->font == font && rfont->spec.size == size)
792 rfont = xfont_open (frame, font, spec, NULL);
794 return MCHAR_INVALID_CODE;
798 MFATAL (MERROR_FONT_X);
799 xfont = rfont->fontp;
800 all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True);
801 min_byte1 = xfont->min_byte1;
802 max_byte1 = xfont->max_byte1;
803 min_byte2 = xfont->min_char_or_byte2;
804 max_byte2 = xfont->max_char_or_byte2;
806 if (min_byte1 == 0 && max_byte1 == 0)
810 if (code < min_byte2 || code > max_byte2)
811 return MCHAR_INVALID_CODE;
814 pcm = xfont->per_char + (code - min_byte2);
815 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
816 ? code : MCHAR_INVALID_CODE);
820 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
823 if (byte1 < min_byte1 || byte1 > max_byte1
824 || byte2 < min_byte2 || byte2 > max_byte2)
825 return MCHAR_INVALID_CODE;
829 pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
830 + (byte2 - min_byte2));
831 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
832 ? code : MCHAR_INVALID_CODE);
836 /* The X font driver function RENDER. */
839 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
840 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
842 MRealizedFace *rface = from->rface;
843 Display *display = FRAME_DISPLAY (rface->frame);
845 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
853 baseline_offset = rface->rfont->baseline_offset;
855 gc = set_region (rface->frame, gc, region);
856 XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
857 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
858 for (i = 0, g = from; g < to; i++, g++)
860 code[i].byte1 = g->code >> 8;
861 code[i].byte2 = g->code & 0xFF;
867 if (g->type == GLYPH_PAD)
869 else if (g->type == GLYPH_SPACE)
870 for (; g < to && g->type == GLYPH_SPACE; g++)
872 else if (! g->rface->rfont)
874 if ((g->c >= 0x200B && g->c <= 0x200F)
875 || (g->c >= 0x202A && g->c <= 0x202E))
879 /* As a font is not found for this character, draw an
881 int box_width = g->width;
882 int box_height = gstring->ascent + gstring->descent;
888 XDrawRectangle (display, (Window) win, gc,
889 x, y - gstring->ascent, box_width, box_height);
893 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
895 XDrawString16 (display, (Window) win, gc,
896 x + g->xoff, y + g->yoff - baseline_offset,
897 code + (g - from), 1);
904 int code_idx = g - from;
907 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
910 XDrawString16 (display, (Window) win, gc,
911 orig_x, y - baseline_offset, code + code_idx, i);
917 xfont_list (MFrame *frame, MPlist *plist, MFont *font, int maxnum)
919 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
920 MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil;
921 MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil;
922 int size = font ? font->size : 0;
925 int mdebug_mask = MDEBUG_FONT;
927 MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
928 family ? msymbol_name (family) : "*",
929 registry ? msymbol_name (registry) : "*");
931 if (registry == Mnil)
932 xfont_list_all (frame);
934 xfont_registry_list (frame, registry);
936 MPLIST_DO (pl, disp_info->font_list)
938 if (registry != Mnil && registry != MPLIST_KEY (pl))
940 MPLIST_DO (p, MPLIST_VAL (pl))
944 if (family != Mnil && family != MPLIST_KEY (p))
946 for (fontx = MPLIST_VAL (p); fontx; fontx = fontx->next)
948 || (mfont__match_p (&fontx->core, font, MFONT_REGISTRY)))
950 if (fontx->core.size == size
951 || fontx->core.size == 0)
953 mplist_push (plist, MPLIST_KEY (p), fontx);
957 || (size <= 360 && HAVE_SIZE (fontx, (size / 10))))
959 unsigned size5_36 = fontx->size5_36;
964 for (i = fontx->core.size / 10; i <= 36; i++)
965 if (size5_36 & (1 << (i - 5)))
967 MSTRUCT_CALLOC (fontx2, MERROR_WIN);
968 fontx2->core = fontx->core;
969 fontx2->core.size = i * 10;
970 fontx2->next = fontx->next;
971 fontx->next = fontx2;
973 if ((size == 0 || size == fontx->core.size)
974 && (maxnum == 0 || num < maxnum))
976 mplist_push (plist, MPLIST_KEY (p), fontx);
981 if (maxnum > 0 && maxnum == num)
984 if (maxnum > 0 && maxnum == num)
987 if (maxnum > 0 && maxnum == num)
991 MDEBUG_PRINT1 (" %d found\n", num);
1005 XftFont *font_no_aa;
1007 /* Pointer to MRealizedFontFT */
1011 static MRealizedFont *xft_open (MFrame *frame, MFont *font, MFont *spec,
1013 static int xft_has_char (MFrame *frame, MFont *font, MFont *spec,
1014 int c, unsigned code);
1015 static unsigned xft_encode_char (MFrame *frame, MFont *font, MFont *spec,
1017 static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
1018 static void xft_render (MDrawWindow, int, int, MGlyphString *,
1019 MGlyph *, MGlyph *, int, MDrawRegion);
1021 MFontDriver xft_driver =
1023 xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL };
1026 close_xft (void *object)
1028 MRealizedFontXft *rfont_xft = object;
1030 if (rfont_xft->font_aa)
1031 XftFontClose (rfont_xft->display, rfont_xft->font_aa);
1032 if (rfont_xft->font_no_aa)
1033 XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
1034 M17N_OBJECT_UNREF (rfont_xft->info);
1040 xft_open_font (Display *display, MSymbol file, double size,
1046 pattern = FcPatternCreate ();
1047 FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
1048 FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
1049 FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
1050 font = XftFontOpenPattern (display, pattern);
1055 static MRealizedFont *
1056 xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
1058 Display *display = FRAME_DISPLAY (frame);
1059 int reg = spec->property[MFONT_REGISTRY];
1061 MRealizedFontXft *rfont_xft;
1062 FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
1063 double size = font->size ? font->size : spec->size;
1065 int ascent, descent, max_advance, average_width, baseline_offset;
1069 MRealizedFont *save = NULL;
1071 for (; rfont; rfont = rfont->next)
1072 if (rfont->font == font
1073 && (rfont->font->size ? rfont->font->size == size
1074 : rfont->spec.size == size)
1075 && rfont->spec.property[MFONT_REGISTRY] == reg)
1079 if (rfont->driver == &xft_driver)
1084 rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
1087 ascent = rfont->ascent;
1088 descent = rfont->descent;
1089 max_advance = rfont->max_advance;
1090 average_width = rfont->average_width;
1091 baseline_offset = rfont->baseline_offset;
1092 spec = &rfont->spec;
1093 ft_face = rfont->fontp;
1094 xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
1097 M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
1098 rfont_xft->display = display;
1099 if (anti_alias == FcTrue)
1100 rfont_xft->font_aa = xft_font;
1102 rfont_xft->font_no_aa = xft_font;
1103 rfont_xft->ft_face = ft_face;
1104 rfont_xft->info = rfont->info;
1105 M17N_OBJECT_REF (rfont->info);
1106 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
1107 rfont->spec = *spec;
1108 rfont->frame = frame;
1110 rfont->driver = &xft_driver;
1111 rfont->info = rfont_xft;
1112 rfont->ascent = ascent;
1113 rfont->descent = descent;
1114 rfont->max_advance = max_advance;
1115 rfont->average_width = average_width;
1116 rfont->baseline_offset = baseline_offset;
1117 rfont->fontp = xft_font;
1118 rfont->next = MPLIST_VAL (frame->realized_font_list);
1119 MPLIST_VAL (frame->realized_font_list) = rfont;
1124 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1127 Display *display = FRAME_DISPLAY (rfont->frame);
1128 XftFont *xft_font = rfont->fontp;
1129 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1131 for (; g != gend; g++)
1133 if (g->code == MCHAR_INVALID_CODE)
1136 g->rbearing = xft_font->max_advance_width;
1137 g->width = g->rbearing;
1138 g->ascent = xft_font->ascent;
1139 g->descent = xft_font->descent;
1145 XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
1146 g->lbearing = - extents.x;
1147 g->rbearing = extents.width - extents.x;
1148 g->width = extents.xOff;
1149 g->ascent = extents.y;
1150 g->descent = extents.height - extents.y;
1156 xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
1160 if (font->type == MFONT_TYPE_REALIZED)
1162 MRealizedFont *rfont = (MRealizedFont *) font;
1163 MRealizedFontXft *rfont_xft = rfont->info;
1165 rfont->info = rfont_xft->info;
1166 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1167 rfont->info = rfont_xft;
1170 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1175 xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
1177 if (font->type == MFONT_TYPE_REALIZED)
1179 MRealizedFont *rfont = (MRealizedFont *) font;
1180 MRealizedFontXft *rfont_xft = rfont->info;
1182 rfont->info = rfont_xft->info;
1183 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1184 rfont->info = rfont_xft;
1187 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1192 xft_render (MDrawWindow win, int x, int y,
1193 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1194 int reverse, MDrawRegion region)
1196 MRealizedFace *rface = from->rface;
1197 MFrame *frame = rface->frame;
1198 Display *display = FRAME_DISPLAY (frame);
1199 MRealizedFont *rfont = rface->rfont;
1200 MRealizedFontXft *rfont_xft = rfont->info;
1201 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1202 XftColor *xft_color = (! reverse
1203 ? &((GCInfo *) rface->info)->xft_color_fore
1204 : &((GCInfo *) rface->info)->xft_color_back);
1205 int anti_alias = (gstring->control.anti_alias
1206 && FRAME_DEVICE (frame)->depth > 1);
1218 if (rfont_xft->font_aa)
1219 xft_font = rfont_xft->font_aa;
1222 double size = rfont->spec.size;
1224 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1227 rfont_xft->font_aa = xft_font;
1229 xft_font = rfont->fontp;
1234 if (rfont_xft->font_no_aa)
1235 xft_font = rfont_xft->font_no_aa;
1238 double size = rfont->spec.size;
1240 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1243 rfont_xft->font_no_aa = xft_font;
1245 xft_font = rfont->fontp;
1249 XftDrawChange (xft_draw, (Drawable) win);
1250 XftDrawSetClip (xft_draw, (Region) region);
1252 y -= rfont->baseline_offset;
1253 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1254 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
1256 if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
1257 glyphs[nglyphs++] = g->code;
1261 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1262 last_x, y, glyphs, nglyphs);
1264 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1265 x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
1266 last_x = x + g->width;
1270 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1273 #endif /* HAVE_XFT2 */
1276 /* Functions for the device driver. */
1279 mwin__close_device (MFrame *frame)
1281 MWDevice *device = FRAME_DEVICE (frame);
1283 M17N_OBJECT_UNREF (device);
1287 mwin__device_get_prop (MFrame *frame, MSymbol key)
1289 MWDevice *device = FRAME_DEVICE (frame);
1291 if (key == Mdisplay)
1292 return (void *) device->display_info->display;
1294 return (void *) ScreenOfDisplay(device->display_info->display,
1295 device->screen_num);
1296 if (key == Mcolormap)
1297 return (void *) device->cmap;
1299 return (void *) device->depth;
1304 mwin__realize_face (MRealizedFace *rface)
1307 MSymbol foreground, background, videomode;
1308 MFaceHLineProp *hline;
1312 if (rface != rface->ascii_rface)
1314 rface->info = rface->ascii_rface->info;
1318 frame = rface->frame;
1319 MSTRUCT_CALLOC (info, MERROR_WIN);
1321 foreground = rface->face.property[MFACE_FOREGROUND];
1322 background = rface->face.property[MFACE_BACKGROUND];
1323 videomode = rface->face.property[MFACE_VIDEOMODE];
1325 videomode = frame->videomode;
1326 if (videomode != Mreverse)
1328 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1329 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1333 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1334 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1337 if (foreground == Mnil)
1338 foreground = frame->foreground;
1339 if (background == Mnil)
1340 background = frame->background;
1341 if (videomode == Mreverse)
1343 MSymbol temp = foreground;
1344 foreground = background;
1347 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1348 FRAME_VISUAL (frame),
1350 MSYMBOL_NAME (foreground),
1351 &info->xft_color_fore))
1353 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1354 FRAME_VISUAL (frame),
1356 MSYMBOL_NAME (background),
1357 &info->xft_color_back))
1359 #endif /* HAVE_XFT2 */
1361 hline = rface->hline;
1365 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1367 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1374 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1376 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1378 if (box->color_left && box->color_left != box->color_top)
1379 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1381 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1383 if (box->color_bottom && box->color_bottom != box->color_top)
1384 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1386 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1388 if (box->color_right && box->color_right != box->color_bottom)
1389 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1391 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1399 mwin__free_realized_face (MRealizedFace *rface)
1401 if (rface == rface->ascii_rface)
1407 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1409 int x, int y, int width, int height, MDrawRegion region)
1411 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1414 gc = set_region (frame, gc, region);
1416 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1417 x, y, width, height);
1422 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1423 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1424 int reverse, MDrawRegion region)
1426 MRealizedFace *rface = from->rface;
1427 Display *display = FRAME_DISPLAY (rface->frame);
1428 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1434 gc = set_region (rface->frame, gc, region);
1435 for (; from < to; from++)
1437 XDrawRectangle (display, (Window) win, gc,
1438 x, y - gstring->ascent + 1, from->width - 1,
1439 gstring->ascent + gstring->descent - 2);
1446 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1447 MRealizedFace *rface, int reverse,
1448 int x, int y, int width, MDrawRegion region)
1450 enum MFaceHLineType type = rface->hline->type;
1451 GCInfo *info = rface->info;
1452 GC gc = gc = info->gc[GC_HLINE];
1455 y = (type == MFACE_HLINE_BOTTOM
1456 ? y + gstring->text_descent - rface->hline->width
1457 : type == MFACE_HLINE_UNDER
1459 : type == MFACE_HLINE_STRIKE_THROUGH
1460 ? y - ((gstring->ascent + gstring->descent) / 2)
1461 : y - gstring->text_ascent);
1463 gc = set_region (frame, gc, region);
1465 for (i = 0; i < rface->hline->width; i++)
1466 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1467 x, y + i, x + width - 1, y + i);
1472 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1473 MGlyph *g, int x, int y, int width, MDrawRegion region)
1475 Display *display = FRAME_DISPLAY (frame);
1476 MRealizedFace *rface = g->rface;
1477 MFaceBoxProp *box = rface->box;
1478 GCInfo *info = rface->info;
1479 GC gc_top, gc_left, gc_right, gc_btm;
1483 y0 = y - (gstring->text_ascent
1484 + rface->box->inner_vmargin + rface->box->width);
1485 y1 = y + (gstring->text_descent
1486 + rface->box->inner_vmargin + rface->box->width - 1);
1488 gc_top = info->gc[GC_BOX_TOP];
1490 gc_top = set_region (frame, gc_top, region);
1491 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1494 gc_btm = info->gc[GC_BOX_BOTTOM];
1496 if (g->type == GLYPH_BOX)
1500 if (g->left_padding)
1501 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1503 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1505 /* Draw the top side. */
1506 for (i = 0; i < box->width; i++)
1507 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1509 /* Draw the bottom side. */
1510 if (region && gc_btm != gc_top)
1511 gc_btm = set_region (frame, gc_btm, region);
1512 for (i = 0; i < box->width; i++)
1513 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1515 if (g->left_padding > 0)
1517 /* Draw the left side. */
1518 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1522 gc_left = info->gc[GC_BOX_LEFT];
1524 gc_left = set_region (frame, gc_left, region);
1526 for (i = 0; i < rface->box->width; i++)
1527 XDrawLine (display, (Window) win, gc_left,
1528 x0 + i, y0 + i, x0 + i, y1 - i);
1532 /* Draw the right side. */
1533 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1537 gc_right = info->gc[GC_BOX_RIGHT];
1539 gc_right = set_region (frame, gc_right, region);
1541 for (i = 0; i < rface->box->width; i++)
1542 XDrawLine (display, (Window) win, gc_right,
1543 x1 - i, y0 + i, x1 - i, y1 - i);
1548 /* Draw the top side. */
1549 for (i = 0; i < box->width; i++)
1550 XDrawLine (display, (Window) win, gc_top,
1551 x, y0 + i, x + width - 1, y0 + i);
1553 /* Draw the bottom side. */
1554 if (region && gc_btm != gc_top)
1555 gc_btm = set_region (frame, gc_btm, region);
1556 for (i = 0; i < box->width; i++)
1557 XDrawLine (display, (Window) win, gc_btm,
1558 x, y1 - i, x + width - 1, y1 - i);
1565 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1566 int reverse, int x, int y,
1567 int width, int height, int row_bytes, unsigned char *bmp,
1570 Display *display = FRAME_DISPLAY (frame);
1572 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1575 gc = set_region (frame, gc, region);
1577 for (i = 0; i < height; i++, bmp += row_bytes)
1578 for (j = 0; j < width; j++)
1579 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1580 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1585 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1586 int intensity, MDrawPoint *points, int num,
1589 GCInfo *info = rface->info;
1592 if (! (gc = info->gc[intensity]))
1593 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1596 gc = set_region (frame, gc, region);
1598 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1599 (XPoint *) points, num, CoordModeOrigin);
1604 mwin__region_from_rect (MDrawMetric *rect)
1606 MDrawRegion region1 = XCreateRegion ();
1607 MDrawRegion region2 = XCreateRegion ();
1612 xrect.width = rect->width;
1613 xrect.height = rect->height;
1614 XUnionRectWithRegion (&xrect, region1, region2);
1615 XDestroyRegion (region1);
1620 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1622 MDrawRegion region1 = XCreateRegion ();
1627 xrect.width = rect->width;
1628 xrect.height = rect->height;
1630 XUnionRegion (region, region, region1);
1631 XUnionRectWithRegion (&xrect, region1, region);
1632 XDestroyRegion (region1);
1636 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1638 MDrawRegion region = XCreateRegion ();
1640 XUnionRegion (region1, region1, region);
1641 XIntersectRegion (region, region2, region1);
1642 XDestroyRegion (region);
1646 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1648 MDrawRegion region1 = XCreateRegion ();
1653 xrect.width = rect->width;
1654 xrect.height = rect->height;
1655 XUnionRectWithRegion (&xrect, region1, region);
1656 XDestroyRegion (region1);
1660 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1664 XClipBox (region, &xrect);
1667 rect->width = xrect.width;
1668 rect->height = xrect.height;
1672 mwin__free_region (MDrawRegion region)
1674 XDestroyRegion (region);
1678 mwin__dump_region (MDrawRegion region)
1681 XClipBox (region, &rect);
1682 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1687 mwin__create_window (MFrame *frame, MDrawWindow parent)
1689 Display *display = FRAME_DISPLAY (frame);
1691 XWMHints wm_hints = { InputHint, False };
1692 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1693 XSetWindowAttributes set_attrs;
1696 GCInfo *info = frame->rface->info;
1699 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1700 mask = GCForeground;
1701 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1702 set_attrs.background_pixel = values.foreground;
1703 set_attrs.backing_store = Always;
1704 set_attrs.override_redirect = True;
1705 set_attrs.save_under = True;
1706 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1707 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1708 CopyFromParent, InputOutput, CopyFromParent,
1710 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1711 NULL, &wm_hints, &class_hints);
1712 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1713 return (MDrawWindow) win;
1717 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1719 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1724 mwin__event_window (void *event)
1726 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1730 mwin__print_event (void *arg, char *win_name)
1733 XEvent *event = (XEvent *) arg;
1735 switch (event->xany.type)
1737 case 2: event_name = "KeyPress"; break;
1738 case 3: event_name = "KeyRelease"; break;
1739 case 4: event_name = "ButtonPress"; break;
1740 case 5: event_name = "ButtonRelease"; break;
1741 case 6: event_name = "MotionNotify"; break;
1742 case 7: event_name = "EnterNotify"; break;
1743 case 8: event_name = "LeaveNotify"; break;
1744 case 9: event_name = "FocusIn"; break;
1745 case 10: event_name = "FocusOut"; break;
1746 case 11: event_name = "KeymapNotify"; break;
1747 case 12: event_name = "Expose"; break;
1748 case 13: event_name = "GraphicsExpose"; break;
1749 case 14: event_name = "NoExpose"; break;
1750 case 15: event_name = "VisibilityNotify"; break;
1751 case 16: event_name = "CreateNotify"; break;
1752 case 17: event_name = "DestroyNotify"; break;
1753 case 18: event_name = "UnmapNotify"; break;
1754 case 19: event_name = "MapNotify"; break;
1755 case 20: event_name = "MapRequest"; break;
1756 case 21: event_name = "ReparentNotify"; break;
1757 case 22: event_name = "ConfigureNotify"; break;
1758 case 23: event_name = "ConfigureRequest"; break;
1759 case 24: event_name = "GravityNotify"; break;
1760 case 25: event_name = "ResizeRequest"; break;
1761 case 26: event_name = "CirculateNotify"; break;
1762 case 27: event_name = "CirculateRequest"; break;
1763 case 28: event_name = "PropertyNotify"; break;
1764 case 29: event_name = "SelectionClear"; break;
1765 case 30: event_name = "SelectionRequest"; break;
1766 case 31: event_name = "SelectionNotify"; break;
1767 case 32: event_name = "ColormapNotify"; break;
1768 case 33: event_name = "ClientMessage"; break;
1769 case 34: event_name = "MappingNotify"; break;
1770 default: event_name = "unknown";
1773 fprintf (stderr, "%s: %s\n", win_name, event_name);
1778 mwin__map_window (MFrame *frame, MDrawWindow win)
1780 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1784 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1786 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1790 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1791 MDrawMetric *geometry)
1793 Display *display = FRAME_DISPLAY (frame);
1794 XWindowAttributes attr;
1795 Window parent = (Window) parent_win, root;
1797 XGetWindowAttributes (display, (Window) win, &attr);
1798 geometry->x = attr.x + attr.border_width;
1799 geometry->y = attr.y + attr.border_width;
1800 geometry->width = attr.width;
1801 geometry->height = attr.height;
1804 parent = RootWindow (display, FRAME_SCREEN (frame));
1807 Window this_parent, *children;
1810 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1813 if (this_parent == parent || this_parent == root)
1815 win = (MDrawWindow) this_parent;
1816 XGetWindowAttributes (display, (Window) win, &attr);
1817 geometry->x += attr.x + attr.border_width;
1818 geometry->y += attr.y + attr.border_width;
1823 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1824 MDrawMetric *current, MDrawMetric *new)
1826 Display *display = FRAME_DISPLAY (frame);
1827 unsigned int mask = 0;
1828 XWindowChanges values;
1830 if (current->width != new->width)
1833 if (new->width <= 0)
1835 values.width = current->width = new->width;
1837 if (current->height != new->height)
1840 if (new->height <= 0)
1842 values.height = current->height = new->height;
1844 if (current->x != new->x)
1847 values.x = current->x = new->x;
1849 if (current->y != new->y)
1852 current->y = new->y;
1853 values.y = current->y = new->y;
1856 XConfigureWindow (display, (Window) win, mask, &values);
1857 XClearWindow (display, (Window) win);
1861 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1863 XEvent *event = (XEvent *) arg;
1864 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
1871 if (event->xany.type != KeyPress
1872 /* && event->xany.type != KeyRelease */
1875 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
1882 if (c < XK_space || c > XK_asciitilde)
1884 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
1885 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1886 if (((XKeyEvent *) event)->state & ControlMask)
1888 if (c >= 'a' && c <= 'z')
1890 if (c >= ' ' && c < 127)
1891 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1893 key = minput__char_to_key (c);
1895 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
1899 char *str = XKeysymToString (keysym);
1903 key = msymbol (str);
1904 if (((XKeyEvent *) event)->state & ShiftMask)
1905 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1906 if (((XKeyEvent *) event)->state & ControlMask)
1907 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1909 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
1910 *modifiers |= MINPUT_KEY_META_MODIFIER;
1911 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
1912 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
1913 if (((XKeyEvent *) event)->state & disp_info->super_mask)
1914 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
1915 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
1916 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
1923 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
1925 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
1927 Display *display = FRAME_DISPLAY (frame);
1928 GCInfo *info = rface->info;
1931 for (i = 0; i <= GC_INVERSE; i++)
1933 XGetGCValues (display, info->gc[i], valuemask, &values);
1934 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
1935 values.foreground, values.background);
1936 fprintf (stderr, "\n");
1940 static MDeviceDriver x_driver =
1943 mwin__device_get_prop,
1945 mwin__free_realized_face,
1947 mwin__draw_empty_boxes,
1951 mwin__region_from_rect,
1952 mwin__union_rect_with_region,
1953 mwin__intersect_region,
1954 mwin__region_add_rect,
1955 mwin__region_to_rect,
1958 mwin__create_window,
1959 mwin__destroy_window,
1962 mwin__window_geometry,
1963 mwin__adjust_window,
1967 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
1972 M_iso8859_1 = msymbol ("iso8859-1");
1973 M_iso10646_1 = msymbol ("iso10646-1");
1975 display_info_list = mplist ();
1976 device_list = mplist ();
1979 xft_driver.select = mfont__ft_driver.select;
1980 xft_driver.list = mfont__ft_driver.list;
1983 Mxim = msymbol ("xim");
1984 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
1992 M17N_OBJECT_UNREF (display_info_list);
1993 M17N_OBJECT_UNREF (device_list);
1998 #ifdef X_SET_ERROR_HANDLER
2000 x_error_handler (Display *display, XErrorEvent *error)
2007 x_io_error_handler (Display *display)
2014 /** Return an MWDevice object corresponding to a display specified in
2017 It searches device_list for a device matching the display. If
2018 found, return the found object. Otherwise, return a newly created
2022 device_open (MFrame *frame, MPlist *param)
2024 Display *display = NULL;
2025 Screen *screen = NULL;
2027 Drawable drawable = 0;
2028 Widget widget = NULL;
2030 int auto_display = 0;
2031 MDisplayInfo *disp_info = NULL;
2032 MWDevice *device = NULL;
2034 XWindowAttributes attr;
2040 int use_xfont = 0, use_freetype = 0, use_xft = 0;
2042 for (plist = param; (key = mplist_key (plist)) != Mnil;
2043 plist = mplist_next (plist))
2045 if (key == Mdisplay)
2046 display = (Display *) mplist_value (plist);
2047 else if (key == Mscreen)
2048 screen = mplist_value (plist);
2049 else if (key == Mdrawable)
2050 drawable = (Drawable) mplist_value (plist);
2051 else if (key == Mdepth)
2052 depth = (unsigned) mplist_value (plist);
2053 else if (key == Mwidget)
2054 widget = (Widget) mplist_value (plist);
2055 else if (key == Mcolormap)
2056 cmap = (Colormap) mplist_value (plist);
2057 else if (key == Mfont)
2059 MSymbol val = MPLIST_SYMBOL (plist);
2063 #ifdef HAVE_FREETYPE
2064 else if (val == Mfreetype)
2067 else if (val == Mxft)
2074 /* If none of them is specified, use all of them. */
2075 if (! use_xfont && ! use_freetype && ! use_xft)
2076 use_xfont = use_freetype = use_xft = 1;
2080 display = XtDisplay (widget);
2081 screen_num = XScreenNumberOfScreen (XtScreen (widget));
2082 depth = DefaultDepth (display, screen_num);
2088 unsigned width, height, border_width;
2091 MERROR (MERROR_WIN, -1);
2092 XGetGeometry (display, drawable, &root_window,
2093 &x, &y, &width, &height, &border_width, &depth);
2094 XGetWindowAttributes (display, root_window, &attr);
2095 screen_num = XScreenNumberOfScreen (attr.screen);
2100 display = DisplayOfScreen (screen);
2105 display = XOpenDisplay (NULL);
2107 MERROR (MERROR_WIN, -1);
2110 screen = DefaultScreenOfDisplay (display);
2112 screen_num = XScreenNumberOfScreen (screen);
2114 depth = DefaultDepth (display, screen_num);
2118 cmap = DefaultColormap (display, screen_num);
2120 for (plist = display_info_list; mplist_key (plist) != Mnil;
2121 plist = mplist_next (plist))
2123 disp_info = (MDisplayInfo *) mplist_value (plist);
2124 if (disp_info->display == display)
2128 if (mplist_key (plist) != Mnil)
2129 M17N_OBJECT_REF (disp_info);
2132 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2133 disp_info->display = display;
2134 disp_info->auto_display = auto_display;
2135 disp_info->font_list = mplist ();
2136 find_modifier_bits (disp_info);
2137 disp_info->MULE_BASELINE_OFFSET
2138 = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
2139 disp_info->AVERAGE_WIDTH
2140 = XInternAtom (display, "AVERAGE_WIDTH", False);
2141 mplist_add (display_info_list, Mt, disp_info);
2144 for (plist = device_list; mplist_key (plist) != Mnil;
2145 plist = mplist_next (plist))
2147 device = (MWDevice *) mplist_value (plist);
2148 if (device->display_info == disp_info
2149 && device->depth == depth
2150 && device->cmap == cmap
2151 && device->screen_num == screen_num)
2155 if (mplist_key (plist) != Mnil)
2156 M17N_OBJECT_REF (device);
2159 unsigned long valuemask = GCForeground;
2163 M17N_OBJECT (device, free_device, MERROR_WIN);
2164 device->display_info = disp_info;
2165 device->screen_num = screen_num;
2166 /* A drawable on which to create GCs. */
2167 device->drawable = XCreatePixmap (display,
2168 RootWindow (display, screen_num),
2170 device->depth = depth;
2171 device->cmap = cmap;
2172 pixels = DisplayHeight (display, screen_num);
2173 mm = DisplayHeightMM (display, screen_num);
2174 device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
2175 device->realized_face_list = mplist ();
2176 device->realized_font_list = mplist ();
2177 mplist_add (device->realized_font_list, Mt, NULL);
2178 device->realized_fontset_list = mplist ();
2179 device->gc_list = mplist ();
2180 values.foreground = BlackPixel (display, screen_num);
2181 device->scratch_gc = XCreateGC (display, device->drawable,
2182 valuemask, &values);
2184 device->xft_draw = XftDrawCreate (display, device->drawable,
2185 DefaultVisual (display, screen_num),
2190 frame->device = device;
2191 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2192 frame->dpi = device->resy;
2193 frame->driver = &x_driver;
2194 frame->font_driver_list = mplist ();
2198 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2201 #endif /* HAVE_XFT2 */
2202 #ifdef HAVE_FREETYPE
2204 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2205 #endif /* HAVE_FREETYPE */
2206 if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
2207 mplist_push (frame->font_driver_list, Mx, &xfont_driver);
2209 frame->realized_font_list = device->realized_font_list;
2210 frame->realized_face_list = device->realized_face_list;
2211 frame->realized_fontset_list = device->realized_fontset_list;
2215 XtResource resources[] = {
2216 { XtNfont, XtCFont, XtRString, sizeof (String),
2217 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2218 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2219 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2220 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2221 XtOffset (AppDataPtr, background), XtRString, "white" },
2222 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2223 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2226 XtGetApplicationResources (widget, &app_data,
2227 resources, XtNumber (resources), NULL, 0);
2228 frame->foreground = msymbol (app_data.foreground);
2229 frame->background = msymbol (app_data.background);
2230 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2234 app_data.font = DEFAULT_FONT;
2235 frame->foreground = msymbol ("black");
2236 frame->background = msymbol ("white");
2237 frame->videomode = Mnormal;
2240 if (strcmp (app_data.font, DEFAULT_FONT) != 0)
2242 XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
2243 unsigned long value;
2248 font = mfont_parse_name (app_data.font, Mx);
2250 && XGetFontProperty (xfont, XA_FONT, &value)
2251 && (name = ((char *) XGetAtomName (display, (Atom) value))))
2252 font = mfont_parse_name (name, Mx);
2253 XFreeFont (display, xfont);
2257 font = mfont_parse_name (DEFAULT_FONT, Mx);
2258 else if (! font->size)
2260 face = mface_from_font (font);
2262 face->property[MFACE_FONTSET] = mfontset (NULL);
2263 face->property[MFACE_FOREGROUND] = frame->foreground;
2264 face->property[MFACE_BACKGROUND] = frame->background;
2265 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2266 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2267 face->property[MFACE_VIDEOMODE] = frame->videomode;
2268 mface_put_prop (face, Mhook_func,
2269 mface_get_prop (mface__default, Mhook_func));
2270 face->property[MFACE_RATIO] = (void *) 100;
2271 mplist_push (param, Mface, face);
2272 M17N_OBJECT_UNREF (face);
2274 #ifdef X_SET_ERROR_HANDLER
2275 XSetErrorHandler (x_error_handler);
2276 XSetIOErrorHandler (x_io_error_handler);
2283 /* XIM (X Input Method) handler */
2285 typedef struct MInputXIMMethodInfo
2291 } MInputXIMMethodInfo;
2293 typedef struct MInputXIMContextInfo
2297 MConverter *converter;
2298 } MInputXIMContextInfo;
2301 xim_open_im (MInputMethod *im)
2303 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
2304 MLocale *saved, *this;
2305 char *save_modifier_list;
2307 MInputXIMMethodInfo *im_info;
2309 saved = mlocale_set (LC_CTYPE, NULL);
2310 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
2312 /* The specified locale is not supported. */
2313 MERROR (MERROR_LOCALE, -1);
2314 if (mlocale_get_prop (this, Mcoding) == Mnil)
2316 /* Unable to decode the output of XIM. */
2317 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2318 MERROR (MERROR_LOCALE, -1);
2321 if (arg->modifier_list)
2322 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
2324 save_modifier_list = XSetLocaleModifiers ("");
2325 if (! save_modifier_list)
2327 /* The specified locale is not supported by X. */
2328 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2329 MERROR (MERROR_LOCALE, -1);
2332 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
2335 /* No input method is available in the current locale. */
2336 XSetLocaleModifiers (save_modifier_list);
2337 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2338 MERROR (MERROR_WIN, -1);
2341 MSTRUCT_MALLOC (im_info, MERROR_WIN);
2342 im_info->display = arg->display;
2344 im_info->language = mlocale_get_prop (this, Mlanguage);
2345 im_info->coding = mlocale_get_prop (this, Mcoding);
2348 XSetLocaleModifiers (save_modifier_list);
2349 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2355 xim_close_im (MInputMethod *im)
2357 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
2359 XCloseIM (im_info->xim);
2364 xim_create_ic (MInputContext *ic)
2366 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
2367 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2368 MInputXIMContextInfo *ic_info;
2371 if (! arg->input_style)
2373 /* By default, use Root style. */
2374 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
2375 arg->preedit_attrs = NULL;
2376 arg->status_attrs = NULL;
2379 if (! arg->preedit_attrs && ! arg->status_attrs)
2380 xic = XCreateIC (im_info->xim,
2381 XNInputStyle, arg->input_style,
2382 XNClientWindow, arg->client_win,
2383 XNFocusWindow, arg->focus_win,
2385 else if (arg->preedit_attrs && ! arg->status_attrs)
2386 xic = XCreateIC (im_info->xim,
2387 XNInputStyle, arg->input_style,
2388 XNClientWindow, arg->client_win,
2389 XNFocusWindow, arg->focus_win,
2390 XNPreeditAttributes, arg->preedit_attrs,
2392 else if (! arg->preedit_attrs && arg->status_attrs)
2393 xic = XCreateIC (im_info->xim,
2394 XNInputStyle, arg->input_style,
2395 XNClientWindow, arg->client_win,
2396 XNFocusWindow, arg->focus_win,
2397 XNStatusAttributes, arg->status_attrs,
2400 xic = XCreateIC (im_info->xim,
2401 XNInputStyle, arg->input_style,
2402 XNClientWindow, arg->client_win,
2403 XNFocusWindow, arg->focus_win,
2404 XNPreeditAttributes, arg->preedit_attrs,
2405 XNStatusAttributes, arg->status_attrs,
2408 MERROR (MERROR_WIN, -1);
2410 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
2412 ic_info->win = arg->focus_win;
2413 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
2419 xim_destroy_ic (MInputContext *ic)
2421 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2423 XDestroyIC (ic_info->xic);
2424 mconv_free_converter (ic_info->converter);
2430 xim_filter (MInputContext *ic, MSymbol key, void *event)
2432 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2434 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
2439 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2441 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2442 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2443 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
2449 buf = (char *) alloca (512);
2450 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
2451 if (status == XBufferOverflow)
2453 buf = (char *) alloca (len);
2454 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
2457 mtext_reset (ic->produced);
2461 mconv_reset_converter (ic_info->converter);
2462 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
2463 mconv_decode (ic_info->converter, ic->produced);
2464 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2465 Mlanguage, (void *) im_info->language);
2466 mtext_cpy (mt, ic->produced);
2467 mtext_reset (ic->produced);
2475 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2479 /*** @addtogroup m17nInputMethodWin */
2484 @brief Input method driver for XIM.
2486 The driver #minput_xim_driver is for the foreign input method of
2487 name #Mxim. It uses XIM (X Input Methods) as a background input
2490 As the symbol #Mxim has property #Minput_driver whose value is
2491 a pointer to this driver, the input method of language #Mnil
2492 and name #Mxim uses this driver.
2494 Therefore, for such input methods, the driver dependent arguments
2495 to the functions whose name begin with minput_ must be as follows.
2497 The argument $ARG of the function minput_open_im () must be a
2498 pointer to the structure #MInputXIMArgIM. See the documentation
2499 of #MInputXIMArgIM for more details.
2501 The argument $ARG of the function minput_create_ic () must be a
2502 pointer to the structure #MInputXIMArgIC. See the documentation
2503 of #MInputXIMArgIC for more details.
2505 The argument $ARG of the function minput_filter () must be a
2506 pointer to the structure @c XEvent. The argument $KEY is ignored.
2508 The argument $ARG of the function minput_lookup () must be the
2509 same one as that of the function minput_filter (). The argument
2513 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2515 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
2516 XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2518 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2519 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
2520 ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2522 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
2523 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2525 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
2526 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
2528 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
2529 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
2531 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
2532 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2534 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2535 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
2537 MInputDriver minput_xim_driver =
2538 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2539 xim_filter, xim_lookup, NULL };
2543 #else /* not HAVE_X11 */
2545 int device_open () { return -1; }
2547 #endif /* not HAVE_X11 */