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;
111 /* Anchor of the chain of MDisplayInfo objects. */
112 static MPlist *display_info_list;
115 /* Color value and the corresponding GC. */
118 unsigned int rgb; /* (red << 16) | (green << 8) | blue */
125 GC_NORMAL = GC_INVERSE + 7,
138 /* The first 8 elements are indexed by an intensity for
139 anti-aliasing. The 2nd to 7th are created on demand. */
142 XftColor xft_color_fore, xft_color_back;
148 /* Common header for the m17n object. */
151 MDisplayInfo *display_info;
169 /** List of pointers to realized faces on the frame. */
170 MPlist *realized_face_list;
172 /* List of single element whose value is a root of chain of realized
174 MPlist *realized_font_list;
176 /** List of pointers to realized fontsets on the frame. */
177 MPlist *realized_fontset_list;
179 /** List of XColors vs GCs on the frame. */
183 static MPlist *device_list;
185 static MSymbol M_iso8859_1, M_iso10646_1;
187 #define FRAME_DEVICE(frame) ((MWDevice *) (frame)->device)
188 #define FRAME_DISPLAY(frame) (FRAME_DEVICE (frame)->display_info->display)
189 #define FRAME_SCREEN(frame) (FRAME_DEVICE (frame)->screen_num)
190 #define FRAME_CMAP(frame) (FRAME_DEVICE (frame)->cmap)
191 #define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
192 FRAME_SCREEN (frame))
194 #define DEFAULT_FONT "-*-*-medium-r-normal--13-*-*-*-c-*-iso8859-1"
201 Boolean reverse_video;
202 } AppData, *AppDataPtr;
205 free_display_info (void *object)
207 MDisplayInfo *disp_info = (MDisplayInfo *) object;
210 MPLIST_DO (plist, disp_info->font_list)
212 MPLIST_DO (pl, MPLIST_VAL (plist))
214 MFontX *fontx, *next;
216 for (fontx = MPLIST_VAL (pl); fontx; fontx = next)
222 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
224 M17N_OBJECT_UNREF (disp_info->font_list);
226 if (disp_info->auto_display)
227 XCloseDisplay (disp_info->display);
233 free_device (void *object)
235 MWDevice *device = object;
238 for (plist = device->realized_fontset_list;
239 mplist_key (plist) != Mnil; plist = mplist_next (plist))
240 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
241 M17N_OBJECT_UNREF (device->realized_fontset_list);
243 if (MPLIST_VAL (device->realized_font_list))
244 mfont__free_realized (MPLIST_VAL (device->realized_font_list));
245 M17N_OBJECT_UNREF (device->realized_font_list);
247 MPLIST_DO (plist, device->realized_face_list)
249 MRealizedFace *rface = MPLIST_VAL (plist);
252 mface__free_realized (rface);
254 M17N_OBJECT_UNREF (device->realized_face_list);
256 MPLIST_DO (plist, device->gc_list)
258 XFreeGC (device->display_info->display,
259 ((RGB_GC *) MPLIST_VAL (plist))->gc);
260 free (MPLIST_VAL (plist));
262 M17N_OBJECT_UNREF (device->gc_list);
263 XFreeGC (device->display_info->display, device->scratch_gc);
266 XftDrawDestroy (device->xft_draw);
269 XFreePixmap (device->display_info->display, device->drawable);
270 M17N_OBJECT_UNREF (device->display_info);
276 find_modifier_bits (MDisplayInfo *disp_info)
278 Display *display = disp_info->display;
279 XModifierKeymap *mods;
280 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
281 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
282 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
283 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
284 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
285 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
286 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
287 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
290 mods = XGetModifierMapping (display);
291 /* We skip the first three sets for Shift, Lock, and Control. The
292 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
293 for (i = 3; i < 8; i++)
294 for (j = 0; j < mods->max_keypermod; j++)
296 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
300 if (code == meta_l || code == meta_r)
301 disp_info->meta_mask |= (1 << i);
302 else if (code == alt_l || code == alt_r)
303 disp_info->alt_mask |= (1 << i);
304 else if (code == super_l || code == super_r)
305 disp_info->super_mask |= (1 << i);
306 else if (code == hyper_l || code == hyper_r)
307 disp_info->hyper_mask |= (1 << i);
310 /* If meta keys are not in any modifier, use alt keys as meta
312 if (! disp_info->meta_mask)
314 disp_info->meta_mask = disp_info->alt_mask;
315 disp_info->alt_mask = 0;
317 /* If both meta and alt are assigned to the same modifier, give meta
319 if (disp_info->meta_mask & disp_info->alt_mask)
320 disp_info->alt_mask &= ~disp_info->meta_mask;
322 XFreeModifiermap (mods);
326 get_rgb_gc (MWDevice *device, XColor *xcolor)
328 int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
329 | (xcolor->blue >> 8));
332 unsigned long valuemask = GCForeground;
335 MPLIST_DO (plist, device->gc_list)
337 rgb_gc = MPLIST_VAL (plist);
339 if (rgb_gc->rgb == rgb)
341 if (rgb_gc->rgb > rgb)
345 if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
348 rgb_gc = malloc (sizeof (RGB_GC));
350 values.foreground = xcolor->pixel;
351 rgb_gc->gc = XCreateGC (device->display_info->display,
352 device->drawable, valuemask, &values);
353 mplist_push (plist, Mt, rgb_gc);
358 get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
360 MWDevice *device = FRAME_DEVICE (frame);
368 color = for_foreground ? frame->foreground : frame->background;
370 if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
371 msymbol_name (color), &xcolor))
373 rgb_gc = get_rgb_gc (device, &xcolor);
377 *rgb_ret = rgb_gc->rgb;
382 GCInfo *info = frame->rface->info;
387 rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
389 rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
397 get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
399 int rgb_fore, rgb_back;
404 if (info->gc[intensity])
405 return info->gc[intensity];
407 rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
408 xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
409 + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
410 xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
411 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
412 xcolor.blue = (((rgb_fore & 0xFF) * intensity
413 + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
414 rgb_gc = get_rgb_gc (device, &xcolor);
418 gc =get_gc_for_anti_alias (device, info,
419 intensity < 4 ? intensity - 1 : intensity + 1);
420 return (info->gc[intensity] = gc);
424 set_region (MFrame *frame, GC gc, MDrawRegion region)
426 unsigned long valuemask = GCForeground;
428 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
429 FRAME_DEVICE (frame)->scratch_gc);
430 XSetRegion (FRAME_DISPLAY (frame), FRAME_DEVICE (frame)->scratch_gc, region);
431 return FRAME_DEVICE (frame)->scratch_gc;
435 /** X font handler */
437 static MFont *xfont_select (MFrame *, MFont *, int);
438 static MRealizedFont *xfont_open (MFrame *, MFont *, MFont *, MRealizedFont *);
439 static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
440 static int xfont_has_char (MFrame *, MFont *, MFont *, int, unsigned);
441 static unsigned xfont_encode_char (MFrame *, MFont *, MFont *, unsigned);
442 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
443 MGlyph *, MGlyph *, int, MDrawRegion);
444 static int xfont_list (MFrame *, MPlist *, MFont *, int);
447 static MFontDriver xfont_driver =
448 { xfont_select, xfont_open,
449 xfont_find_metric, xfont_has_char, xfont_encode_char,
450 xfont_render, xfont_list };
453 font_compare (const void *p1, const void *p2)
455 return strcmp (*(char **) p1, *(char **) p2);
459 xfont_registry_list (MFrame *frame, MSymbol registry)
461 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
462 MPlist *font_list = disp_info->font_list;
465 char **font_names, **names;
471 plist = mplist_get (font_list, registry);
475 mplist_add (font_list, registry, plist);
476 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", msymbol_name (registry));
477 font_names = XListFonts (disp_info->display, pattern, 0x8000, &nfonts);
481 char *reg_name = msymbol_name (registry);
483 for_full_width = (strncmp (reg_name, "jis", 3) == 0
484 || strncmp (reg_name, "gb", 2) == 0
485 || strncmp (reg_name, "big5", 4) == 0
486 || strncmp (reg_name, "ksc", 3) == 0);
488 names = alloca (sizeof (char *) * nfonts);
489 memcpy (names, font_names, sizeof (char *) * nfonts);
490 qsort (names, nfonts, sizeof (char *), font_compare);
492 for (i = 0, p = NULL; i < nfonts; i++)
493 if (mfont__parse_name_into_font (names[i], Mx, &font) == 0
494 && (font.size >= 50 || font.property[MFONT_RESY] == 0))
496 MSymbol family = FONT_PROPERTY (&font, MFONT_FAMILY);
497 MFontX *fontx, *fontx2;
505 if (p && MPLIST_KEY (p) != family)
506 p = mplist_find_by_key (plist, family);
508 p = mplist_push (plist, family, NULL);
510 /* Calculate how many bytes to compare to detect fonts of the
512 for (base_end = names[i], fields = 0; *base_end; base_end++)
514 && ++fields == 7 /* PIXEL_SIZE */)
516 base_len = base_end - names[i] + 1;
518 size = smallest = font.size / 10;
519 sizes[nsizes++] = size;
520 for (j = i + 1; j < nfonts && ! strncmp (names[i], names[j], base_len);
522 if (mfont__parse_name_into_font (names[j], Mx, &font) == 0
523 && (font.size >= 50 || font.property[MFONT_RESY] == 0))
525 size = font.size / 10;
529 sizes[nsizes++] = size;
532 font.for_full_width = for_full_width;
533 font.type = MFONT_TYPE_OBJECT;
534 font.source = MFONT_SOURCE_X;
535 MSTRUCT_CALLOC (fontx, MERROR_WIN);
537 fontx->core.size = smallest * 10;
538 fontx->next = MPLIST_VAL (p);
539 MPLIST_VAL (p) = fontx;
541 for (j = 0; j < nsizes; j++)
545 if (sizes[j] != smallest)
546 SET_SIZE (fontx, sizes[j]);
550 MSTRUCT_CALLOC (fontx2, MERROR_WIN);
552 fontx2->core.size = sizes[j] * 10;
553 fontx2->next = MPLIST_VAL (p);
554 MPLIST_VAL (p) = fontx2;
558 XFreeFontNames (font_names);
563 xfont_list_all (MFrame *frame)
565 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
566 MPlist *font_encoding_list, *p;
568 if (disp_info->all_fonts_scaned)
570 disp_info->all_fonts_scaned = 1;
571 font_encoding_list = mfont__encoding_list ();
572 if (! font_encoding_list)
574 MPLIST_DO (p, font_encoding_list)
575 xfont_registry_list (frame, MPLIST_KEY (p));
585 /* The X font driver function SELECT. */
588 xfont_select (MFrame *frame, MFont *font, int limited_size)
590 MPlist *plist = mplist (), *pl;
591 int num = xfont_list (frame, plist, font, 0);
595 MPLIST_DO (pl, plist)
597 font = MPLIST_VAL (pl);
598 if (limited_size == 0
600 || font->size <= limited_size)
606 M17N_OBJECT_UNREF (plist);
610 /* The X font driver function CLOSE. */
613 close_xfont (void *object)
615 MRealizedFontX *x_rfont = object;
617 XFreeFont (x_rfont->display, x_rfont->xfont);
621 /* The X font driver function OPEN. */
623 static MRealizedFont *
624 xfont_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
626 int size = spec->size;
627 MRealizedFontX *x_rfont;
629 Display *display = FRAME_DISPLAY (frame);
631 int mdebug_mask = MDEBUG_FONT;
636 for (; rfont; rfont = rfont->next)
637 if (rfont->font == font && rfont->spec.size == size)
643 /* This never fail to generate a valid fontname. */
644 name = mfont_unparse_name (&this, Mx);
645 xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
648 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
650 font->type = MFONT_TYPE_FAILURE;
653 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
655 M17N_OBJECT (x_rfont, close_xfont, MERROR_FONT_X);
656 x_rfont->display = display;
657 x_rfont->xfont = xfont;
658 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
660 rfont->spec.type = MFONT_TYPE_REALIZED;
661 rfont->spec.source = MFONT_SOURCE_X;
662 rfont->frame = frame;
664 rfont->driver = &xfont_driver;
665 rfont->info = x_rfont;
667 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
670 rfont->baseline_offset
671 = (XGetFontProperty (xfont, disp_info->MULE_BASELINE_OFFSET, &value)
674 rfont->ascent = xfont->ascent + rfont->baseline_offset;
675 rfont->descent = xfont->descent - rfont->baseline_offset;
676 rfont->max_advance = xfont->max_bounds.width;
677 rfont->fontp = xfont;
678 rfont->next = MPLIST_VAL (frame->realized_font_list);
679 MPLIST_VAL (frame->realized_font_list) = rfont;
684 /* The X font driver function FIND_METRIC. */
687 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
690 XFontStruct *xfont = rfont->fontp;
691 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
693 for (; g != gend; g++)
695 if (g->code == MCHAR_INVALID_CODE)
697 g->lbearing = xfont->max_bounds.lbearing;
698 g->rbearing = xfont->max_bounds.rbearing;
699 g->width = xfont->max_bounds.width;
700 g->ascent = xfont->ascent;
701 g->descent = xfont->descent;
705 int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
706 XCharStruct *pcm = NULL;
708 if (xfont->per_char != NULL)
710 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
713 && byte2 >= xfont->min_char_or_byte2
714 && byte2 <= xfont->max_char_or_byte2)
715 pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
719 if (byte1 >= xfont->min_byte1
720 && byte1 <= xfont->max_byte1
721 && byte2 >= xfont->min_char_or_byte2
722 && byte2 <= xfont->max_char_or_byte2)
724 pcm = (xfont->per_char
725 + ((xfont->max_char_or_byte2
726 - xfont->min_char_or_byte2 + 1)
727 * (byte1 - xfont->min_byte1))
728 + (byte2 - xfont->min_char_or_byte2));
735 g->lbearing = pcm->lbearing;
736 g->rbearing = pcm->rbearing;
737 g->width = pcm->width;
738 g->ascent = pcm->ascent;
739 g->descent = pcm->descent;
743 /* If the per_char pointer is null, all glyphs between
744 the first and last character indexes inclusive have
745 the same information, as given by both min_bounds and
748 g->rbearing = xfont->max_bounds.width;
749 g->width = xfont->max_bounds.width;
750 g->ascent = xfont->ascent;
751 g->descent = xfont->descent;
754 g->ascent += rfont->baseline_offset;
755 g->descent -= rfont->baseline_offset;
761 xfont_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
763 return (xfont_encode_char (frame, font, spec, code) != MCHAR_INVALID_CODE);
766 /* The X font driver function GET_GLYPH_ID. */
769 xfont_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
771 MRealizedFont *rfont;
773 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
776 if (font->type == MFONT_TYPE_REALIZED)
777 rfont = (MRealizedFont *) font;
778 else if (font->type == MFONT_TYPE_OBJECT)
780 int size = spec->size;
782 for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
784 if (rfont->font == font && rfont->spec.size == size)
788 rfont = xfont_open (frame, font, spec, NULL);
790 return MCHAR_INVALID_CODE;
794 MFATAL (MERROR_FONT_X);
795 xfont = rfont->fontp;
796 all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True);
797 min_byte1 = xfont->min_byte1;
798 max_byte1 = xfont->max_byte1;
799 min_byte2 = xfont->min_char_or_byte2;
800 max_byte2 = xfont->max_char_or_byte2;
802 if (min_byte1 == 0 && max_byte1 == 0)
806 if (code < min_byte2 || code > max_byte2)
807 return MCHAR_INVALID_CODE;
810 pcm = xfont->per_char + (code - min_byte2);
811 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
812 ? code : MCHAR_INVALID_CODE);
816 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
819 if (byte1 < min_byte1 || byte1 > max_byte1
820 || byte2 < min_byte2 || byte2 > max_byte2)
821 return MCHAR_INVALID_CODE;
825 pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
826 + (byte2 - min_byte2));
827 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
828 ? code : MCHAR_INVALID_CODE);
832 /* The X font driver function RENDER. */
835 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
836 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
838 MRealizedFace *rface = from->rface;
839 Display *display = FRAME_DISPLAY (rface->frame);
841 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
849 baseline_offset = rface->rfont->baseline_offset;
851 gc = set_region (rface->frame, gc, region);
852 XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
853 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
854 for (i = 0, g = from; g < to; i++, g++)
856 code[i].byte1 = g->code >> 8;
857 code[i].byte2 = g->code & 0xFF;
863 if (g->type == GLYPH_PAD)
865 else if (g->type == GLYPH_SPACE)
866 for (; g < to && g->type == GLYPH_SPACE; g++)
868 else if (! g->rface->rfont)
870 if ((g->c >= 0x200B && g->c <= 0x200F)
871 || (g->c >= 0x202A && g->c <= 0x202E))
875 /* As a font is not found for this character, draw an
877 int box_width = g->width;
878 int box_height = gstring->ascent + gstring->descent;
884 XDrawRectangle (display, (Window) win, gc,
885 x, y - gstring->ascent, box_width, box_height);
889 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
891 XDrawString16 (display, (Window) win, gc,
892 x + g->xoff, y + g->yoff - baseline_offset,
893 code + (g - from), 1);
900 int code_idx = g - from;
903 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
906 XDrawString16 (display, (Window) win, gc,
907 orig_x, y - baseline_offset, code + code_idx, i);
913 xfont_list (MFrame *frame, MPlist *plist, MFont *font, int maxnum)
915 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
916 MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil;
917 MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil;
918 int size = font ? font->size : 0;
921 int mdebug_mask = MDEBUG_FONT;
923 MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
924 family ? msymbol_name (family) : "*",
925 registry ? msymbol_name (registry) : "*");
927 if (registry == Mnil)
928 xfont_list_all (frame);
930 xfont_registry_list (frame, registry);
932 MPLIST_DO (pl, disp_info->font_list)
934 if (registry != Mnil && registry != MPLIST_KEY (pl))
936 MPLIST_DO (p, MPLIST_VAL (pl))
940 if (family != Mnil && family != MPLIST_KEY (p))
942 for (fontx = MPLIST_VAL (p); fontx; fontx = fontx->next)
944 || (mfont__match_p (&fontx->core, font, MFONT_REGISTRY)))
946 if (fontx->core.size == size
947 || fontx->core.size == 0)
949 mplist_push (plist, MPLIST_KEY (p), fontx);
953 || (size <= 360 && HAVE_SIZE (fontx, (size / 10))))
955 unsigned size5_36 = fontx->size5_36;
960 for (i = fontx->core.size / 10; i <= 36; i++)
961 if (size5_36 & (1 << (i - 5)))
963 MSTRUCT_CALLOC (fontx2, MERROR_WIN);
964 fontx2->core = fontx->core;
965 fontx2->core.size = i * 10;
966 fontx2->next = fontx->next;
967 fontx->next = fontx2;
969 if ((size == 0 || size == fontx->core.size)
970 && (maxnum == 0 || num < maxnum))
972 mplist_push (plist, MPLIST_KEY (p), fontx);
977 if (maxnum > 0 && maxnum == num)
980 if (maxnum > 0 && maxnum == num)
983 if (maxnum > 0 && maxnum == num)
987 MDEBUG_PRINT1 (" %d found\n", num);
1001 XftFont *font_no_aa;
1003 /* Pointer to MRealizedFontFT */
1007 static MRealizedFont *xft_open (MFrame *frame, MFont *font, MFont *spec,
1009 static int xft_has_char (MFrame *frame, MFont *font, MFont *spec,
1010 int c, unsigned code);
1011 static unsigned xft_encode_char (MFrame *frame, MFont *font, MFont *spec,
1013 static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
1014 static void xft_render (MDrawWindow, int, int, MGlyphString *,
1015 MGlyph *, MGlyph *, int, MDrawRegion);
1017 MFontDriver xft_driver =
1019 xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL };
1022 close_xft (void *object)
1024 MRealizedFontXft *rfont_xft = object;
1026 if (rfont_xft->font_aa)
1027 XftFontClose (rfont_xft->display, rfont_xft->font_aa);
1028 if (rfont_xft->font_no_aa)
1029 XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
1030 M17N_OBJECT_UNREF (rfont_xft->info);
1036 xft_open_font (Display *display, MSymbol file, double size,
1042 pattern = FcPatternCreate ();
1043 FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
1044 FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
1045 FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
1046 font = XftFontOpenPattern (display, pattern);
1051 static MRealizedFont *
1052 xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
1054 Display *display = FRAME_DISPLAY (frame);
1055 int reg = spec->property[MFONT_REGISTRY];
1057 MRealizedFontXft *rfont_xft;
1058 FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
1059 double size = font->size ? font->size : spec->size;
1061 int ascent, descent, max_advance, baseline_offset;
1065 MRealizedFont *save = NULL;
1067 for (; rfont; rfont = rfont->next)
1068 if (rfont->font == font
1069 && (rfont->font->size ? rfont->font->size == size
1070 : rfont->spec.size == size)
1071 && rfont->spec.property[MFONT_REGISTRY] == reg)
1075 if (rfont->driver == &xft_driver)
1080 rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
1083 ascent = rfont->ascent;
1084 descent = rfont->descent;
1085 max_advance = rfont->max_advance;
1086 baseline_offset = rfont->baseline_offset;
1087 spec = &rfont->spec;
1088 ft_face = rfont->fontp;
1089 xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
1092 M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
1093 rfont_xft->display = display;
1094 if (anti_alias == FcTrue)
1095 rfont_xft->font_aa = xft_font;
1097 rfont_xft->font_no_aa = xft_font;
1098 rfont_xft->ft_face = ft_face;
1099 rfont_xft->info = rfont->info;
1100 M17N_OBJECT_REF (rfont->info);
1101 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
1102 rfont->spec = *spec;
1103 rfont->frame = frame;
1105 rfont->driver = &xft_driver;
1106 rfont->info = rfont_xft;
1107 rfont->ascent = ascent;
1108 rfont->descent = descent;
1109 rfont->max_advance = max_advance;
1110 rfont->baseline_offset = baseline_offset;
1111 rfont->fontp = xft_font;
1112 rfont->next = MPLIST_VAL (frame->realized_font_list);
1113 MPLIST_VAL (frame->realized_font_list) = rfont;
1118 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1121 Display *display = FRAME_DISPLAY (rfont->frame);
1122 XftFont *xft_font = rfont->fontp;
1123 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1125 for (; g != gend; g++)
1127 if (g->code == MCHAR_INVALID_CODE)
1130 g->rbearing = xft_font->max_advance_width;
1131 g->width = g->rbearing;
1132 g->ascent = xft_font->ascent;
1133 g->descent = xft_font->descent;
1139 XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
1140 g->lbearing = - extents.x;
1141 g->rbearing = extents.width - extents.x;
1142 g->width = extents.xOff;
1143 g->ascent = extents.y;
1144 g->descent = extents.height - extents.y;
1150 xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
1154 if (font->type == MFONT_TYPE_REALIZED)
1156 MRealizedFont *rfont = (MRealizedFont *) font;
1157 MRealizedFontXft *rfont_xft = rfont->info;
1159 rfont->info = rfont_xft->info;
1160 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1161 rfont->info = rfont_xft;
1164 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1169 xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
1171 if (font->type == MFONT_TYPE_REALIZED)
1173 MRealizedFont *rfont = (MRealizedFont *) font;
1174 MRealizedFontXft *rfont_xft = rfont->info;
1176 rfont->info = rfont_xft->info;
1177 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1178 rfont->info = rfont_xft;
1181 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1186 xft_render (MDrawWindow win, int x, int y,
1187 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1188 int reverse, MDrawRegion region)
1190 MRealizedFace *rface = from->rface;
1191 MFrame *frame = rface->frame;
1192 Display *display = FRAME_DISPLAY (frame);
1193 MRealizedFont *rfont = rface->rfont;
1194 MRealizedFontXft *rfont_xft = rfont->info;
1195 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1196 XftColor *xft_color = (! reverse
1197 ? &((GCInfo *) rface->info)->xft_color_fore
1198 : &((GCInfo *) rface->info)->xft_color_back);
1199 int anti_alias = (gstring->control.anti_alias
1200 && FRAME_DEVICE (frame)->depth > 1);
1212 if (rfont_xft->font_aa)
1213 xft_font = rfont_xft->font_aa;
1216 double size = rfont->spec.size;
1218 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1221 rfont_xft->font_aa = xft_font;
1223 xft_font = rfont->fontp;
1228 if (rfont_xft->font_no_aa)
1229 xft_font = rfont_xft->font_no_aa;
1232 double size = rfont->spec.size;
1234 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1237 rfont_xft->font_no_aa = xft_font;
1239 xft_font = rfont->fontp;
1243 XftDrawChange (xft_draw, (Drawable) win);
1244 XftDrawSetClip (xft_draw, (Region) region);
1246 y -= rfont->baseline_offset;
1247 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1248 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
1250 if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
1251 glyphs[nglyphs++] = g->code;
1255 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1256 last_x, y, glyphs, nglyphs);
1258 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1259 x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
1260 last_x = x + g->width;
1264 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1267 #endif /* HAVE_XFT2 */
1270 /* Functions for the device driver. */
1273 mwin__close_device (MFrame *frame)
1275 MWDevice *device = FRAME_DEVICE (frame);
1277 M17N_OBJECT_UNREF (device);
1281 mwin__device_get_prop (MFrame *frame, MSymbol key)
1283 MWDevice *device = FRAME_DEVICE (frame);
1285 if (key == Mdisplay)
1286 return (void *) device->display_info->display;
1288 return (void *) ScreenOfDisplay(device->display_info->display,
1289 device->screen_num);
1290 if (key == Mcolormap)
1291 return (void *) device->cmap;
1293 return (void *) device->depth;
1298 mwin__realize_face (MRealizedFace *rface)
1301 MSymbol foreground, background, videomode;
1302 MFaceHLineProp *hline;
1306 if (rface != rface->ascii_rface)
1308 rface->info = rface->ascii_rface->info;
1312 frame = rface->frame;
1313 MSTRUCT_CALLOC (info, MERROR_WIN);
1315 foreground = rface->face.property[MFACE_FOREGROUND];
1316 background = rface->face.property[MFACE_BACKGROUND];
1317 videomode = rface->face.property[MFACE_VIDEOMODE];
1319 videomode = frame->videomode;
1320 if (videomode != Mreverse)
1322 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1323 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1327 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1328 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1331 if (foreground == Mnil)
1332 foreground = frame->foreground;
1333 if (background == Mnil)
1334 background = frame->background;
1335 if (videomode == Mreverse)
1337 MSymbol temp = foreground;
1338 foreground = background;
1341 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1342 FRAME_VISUAL (frame),
1344 MSYMBOL_NAME (foreground),
1345 &info->xft_color_fore))
1347 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1348 FRAME_VISUAL (frame),
1350 MSYMBOL_NAME (background),
1351 &info->xft_color_back))
1353 #endif /* HAVE_XFT2 */
1355 hline = rface->hline;
1359 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1361 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1368 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1370 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1372 if (box->color_left && box->color_left != box->color_top)
1373 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1375 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1377 if (box->color_bottom && box->color_bottom != box->color_top)
1378 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1380 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1382 if (box->color_right && box->color_right != box->color_bottom)
1383 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1385 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1393 mwin__free_realized_face (MRealizedFace *rface)
1395 if (rface == rface->ascii_rface)
1401 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1403 int x, int y, int width, int height, MDrawRegion region)
1405 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1408 gc = set_region (frame, gc, region);
1410 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1411 x, y, width, height);
1416 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1417 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1418 int reverse, MDrawRegion region)
1420 MRealizedFace *rface = from->rface;
1421 Display *display = FRAME_DISPLAY (rface->frame);
1422 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1428 gc = set_region (rface->frame, gc, region);
1429 for (; from < to; from++)
1431 XDrawRectangle (display, (Window) win, gc,
1432 x, y - gstring->ascent + 1, from->width - 1,
1433 gstring->ascent + gstring->descent - 2);
1440 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1441 MRealizedFace *rface, int reverse,
1442 int x, int y, int width, MDrawRegion region)
1444 enum MFaceHLineType type = rface->hline->type;
1445 GCInfo *info = rface->info;
1446 GC gc = gc = info->gc[GC_HLINE];
1449 y = (type == MFACE_HLINE_BOTTOM
1450 ? y + gstring->text_descent - rface->hline->width
1451 : type == MFACE_HLINE_UNDER
1453 : type == MFACE_HLINE_STRIKE_THROUGH
1454 ? y - ((gstring->ascent + gstring->descent) / 2)
1455 : y - gstring->text_ascent);
1457 gc = set_region (frame, gc, region);
1459 for (i = 0; i < rface->hline->width; i++)
1460 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1461 x, y + i, x + width - 1, y + i);
1466 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1467 MGlyph *g, int x, int y, int width, MDrawRegion region)
1469 Display *display = FRAME_DISPLAY (frame);
1470 MRealizedFace *rface = g->rface;
1471 MFaceBoxProp *box = rface->box;
1472 GCInfo *info = rface->info;
1473 GC gc_top, gc_left, gc_right, gc_btm;
1477 y0 = y - (gstring->text_ascent
1478 + rface->box->inner_vmargin + rface->box->width);
1479 y1 = y + (gstring->text_descent
1480 + rface->box->inner_vmargin + rface->box->width - 1);
1482 gc_top = info->gc[GC_BOX_TOP];
1484 gc_top = set_region (frame, gc_top, region);
1485 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1488 gc_btm = info->gc[GC_BOX_BOTTOM];
1490 if (g->type == GLYPH_BOX)
1494 if (g->left_padding)
1495 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1497 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1499 /* Draw the top side. */
1500 for (i = 0; i < box->width; i++)
1501 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1503 /* Draw the bottom side. */
1504 if (region && gc_btm != gc_top)
1505 gc_btm = set_region (frame, gc_btm, region);
1506 for (i = 0; i < box->width; i++)
1507 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1509 if (g->left_padding > 0)
1511 /* Draw the left side. */
1512 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1516 gc_left = info->gc[GC_BOX_LEFT];
1518 gc_left = set_region (frame, gc_left, region);
1520 for (i = 0; i < rface->box->width; i++)
1521 XDrawLine (display, (Window) win, gc_left,
1522 x0 + i, y0 + i, x0 + i, y1 - i);
1526 /* Draw the right side. */
1527 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1531 gc_right = info->gc[GC_BOX_RIGHT];
1533 gc_right = set_region (frame, gc_right, region);
1535 for (i = 0; i < rface->box->width; i++)
1536 XDrawLine (display, (Window) win, gc_right,
1537 x1 - i, y0 + i, x1 - i, y1 - i);
1542 /* Draw the top side. */
1543 for (i = 0; i < box->width; i++)
1544 XDrawLine (display, (Window) win, gc_top,
1545 x, y0 + i, x + width - 1, y0 + i);
1547 /* Draw the bottom side. */
1548 if (region && gc_btm != gc_top)
1549 gc_btm = set_region (frame, gc_btm, region);
1550 for (i = 0; i < box->width; i++)
1551 XDrawLine (display, (Window) win, gc_btm,
1552 x, y1 - i, x + width - 1, y1 - i);
1559 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1560 int reverse, int x, int y,
1561 int width, int height, int row_bytes, unsigned char *bmp,
1564 Display *display = FRAME_DISPLAY (frame);
1566 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1569 gc = set_region (frame, gc, region);
1571 for (i = 0; i < height; i++, bmp += row_bytes)
1572 for (j = 0; j < width; j++)
1573 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1574 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1579 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1580 int intensity, MDrawPoint *points, int num,
1583 GCInfo *info = rface->info;
1586 if (! (gc = info->gc[intensity]))
1587 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1590 gc = set_region (frame, gc, region);
1592 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1593 (XPoint *) points, num, CoordModeOrigin);
1598 mwin__region_from_rect (MDrawMetric *rect)
1600 MDrawRegion region1 = XCreateRegion ();
1601 MDrawRegion region2 = XCreateRegion ();
1606 xrect.width = rect->width;
1607 xrect.height = rect->height;
1608 XUnionRectWithRegion (&xrect, region1, region2);
1609 XDestroyRegion (region1);
1614 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1616 MDrawRegion region1 = XCreateRegion ();
1621 xrect.width = rect->width;
1622 xrect.height = rect->height;
1624 XUnionRegion (region, region, region1);
1625 XUnionRectWithRegion (&xrect, region1, region);
1626 XDestroyRegion (region1);
1630 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1632 MDrawRegion region = XCreateRegion ();
1634 XUnionRegion (region1, region1, region);
1635 XIntersectRegion (region, region2, region1);
1636 XDestroyRegion (region);
1640 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1642 MDrawRegion region1 = XCreateRegion ();
1647 xrect.width = rect->width;
1648 xrect.height = rect->height;
1649 XUnionRectWithRegion (&xrect, region1, region);
1650 XDestroyRegion (region1);
1654 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1658 XClipBox (region, &xrect);
1661 rect->width = xrect.width;
1662 rect->height = xrect.height;
1666 mwin__free_region (MDrawRegion region)
1668 XDestroyRegion (region);
1672 mwin__dump_region (MDrawRegion region)
1675 XClipBox (region, &rect);
1676 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1681 mwin__create_window (MFrame *frame, MDrawWindow parent)
1683 Display *display = FRAME_DISPLAY (frame);
1685 XWMHints wm_hints = { InputHint, False };
1686 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1687 XSetWindowAttributes set_attrs;
1690 GCInfo *info = frame->rface->info;
1693 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1694 mask = GCForeground;
1695 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1696 set_attrs.background_pixel = values.foreground;
1697 set_attrs.backing_store = Always;
1698 set_attrs.override_redirect = True;
1699 set_attrs.save_under = True;
1700 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1701 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1702 CopyFromParent, InputOutput, CopyFromParent,
1704 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1705 NULL, &wm_hints, &class_hints);
1706 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1707 return (MDrawWindow) win;
1711 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1713 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1718 mwin__event_window (void *event)
1720 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1724 mwin__print_event (void *arg, char *win_name)
1727 XEvent *event = (XEvent *) arg;
1729 switch (event->xany.type)
1731 case 2: event_name = "KeyPress"; break;
1732 case 3: event_name = "KeyRelease"; break;
1733 case 4: event_name = "ButtonPress"; break;
1734 case 5: event_name = "ButtonRelease"; break;
1735 case 6: event_name = "MotionNotify"; break;
1736 case 7: event_name = "EnterNotify"; break;
1737 case 8: event_name = "LeaveNotify"; break;
1738 case 9: event_name = "FocusIn"; break;
1739 case 10: event_name = "FocusOut"; break;
1740 case 11: event_name = "KeymapNotify"; break;
1741 case 12: event_name = "Expose"; break;
1742 case 13: event_name = "GraphicsExpose"; break;
1743 case 14: event_name = "NoExpose"; break;
1744 case 15: event_name = "VisibilityNotify"; break;
1745 case 16: event_name = "CreateNotify"; break;
1746 case 17: event_name = "DestroyNotify"; break;
1747 case 18: event_name = "UnmapNotify"; break;
1748 case 19: event_name = "MapNotify"; break;
1749 case 20: event_name = "MapRequest"; break;
1750 case 21: event_name = "ReparentNotify"; break;
1751 case 22: event_name = "ConfigureNotify"; break;
1752 case 23: event_name = "ConfigureRequest"; break;
1753 case 24: event_name = "GravityNotify"; break;
1754 case 25: event_name = "ResizeRequest"; break;
1755 case 26: event_name = "CirculateNotify"; break;
1756 case 27: event_name = "CirculateRequest"; break;
1757 case 28: event_name = "PropertyNotify"; break;
1758 case 29: event_name = "SelectionClear"; break;
1759 case 30: event_name = "SelectionRequest"; break;
1760 case 31: event_name = "SelectionNotify"; break;
1761 case 32: event_name = "ColormapNotify"; break;
1762 case 33: event_name = "ClientMessage"; break;
1763 case 34: event_name = "MappingNotify"; break;
1764 default: event_name = "unknown";
1767 fprintf (stderr, "%s: %s\n", win_name, event_name);
1772 mwin__map_window (MFrame *frame, MDrawWindow win)
1774 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1778 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1780 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1784 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1785 MDrawMetric *geometry)
1787 Display *display = FRAME_DISPLAY (frame);
1788 XWindowAttributes attr;
1789 Window parent = (Window) parent_win, root;
1791 XGetWindowAttributes (display, (Window) win, &attr);
1792 geometry->x = attr.x + attr.border_width;
1793 geometry->y = attr.y + attr.border_width;
1794 geometry->width = attr.width;
1795 geometry->height = attr.height;
1798 parent = RootWindow (display, FRAME_SCREEN (frame));
1801 Window this_parent, *children;
1804 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1807 if (this_parent == parent || this_parent == root)
1809 win = (MDrawWindow) this_parent;
1810 XGetWindowAttributes (display, (Window) win, &attr);
1811 geometry->x += attr.x + attr.border_width;
1812 geometry->y += attr.y + attr.border_width;
1817 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1818 MDrawMetric *current, MDrawMetric *new)
1820 Display *display = FRAME_DISPLAY (frame);
1821 unsigned int mask = 0;
1822 XWindowChanges values;
1824 if (current->width != new->width)
1827 if (new->width <= 0)
1829 values.width = current->width = new->width;
1831 if (current->height != new->height)
1834 if (new->height <= 0)
1836 values.height = current->height = new->height;
1838 if (current->x != new->x)
1841 values.x = current->x = new->x;
1843 if (current->y != new->y)
1846 current->y = new->y;
1847 values.y = current->y = new->y;
1850 XConfigureWindow (display, (Window) win, mask, &values);
1851 XClearWindow (display, (Window) win);
1855 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1857 XEvent *event = (XEvent *) arg;
1858 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
1865 if (event->xany.type != KeyPress
1866 /* && event->xany.type != KeyRelease */
1869 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
1876 if (c < XK_space || c > XK_asciitilde)
1878 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
1879 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1880 if (((XKeyEvent *) event)->state & ControlMask)
1882 if (c >= 'a' && c <= 'z')
1884 if (c >= ' ' && c < 127)
1885 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1887 key = minput__char_to_key (c);
1889 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
1893 char *str = XKeysymToString (keysym);
1897 key = msymbol (str);
1898 if (((XKeyEvent *) event)->state & ShiftMask)
1899 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1900 if (((XKeyEvent *) event)->state & ControlMask)
1901 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1903 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
1904 *modifiers |= MINPUT_KEY_META_MODIFIER;
1905 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
1906 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
1907 if (((XKeyEvent *) event)->state & disp_info->super_mask)
1908 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
1909 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
1910 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
1917 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
1919 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
1921 Display *display = FRAME_DISPLAY (frame);
1922 GCInfo *info = rface->info;
1925 for (i = 0; i <= GC_INVERSE; i++)
1927 XGetGCValues (display, info->gc[i], valuemask, &values);
1928 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
1929 values.foreground, values.background);
1930 fprintf (stderr, "\n");
1934 static MDeviceDriver x_driver =
1937 mwin__device_get_prop,
1939 mwin__free_realized_face,
1941 mwin__draw_empty_boxes,
1945 mwin__region_from_rect,
1946 mwin__union_rect_with_region,
1947 mwin__intersect_region,
1948 mwin__region_add_rect,
1949 mwin__region_to_rect,
1952 mwin__create_window,
1953 mwin__destroy_window,
1956 mwin__window_geometry,
1957 mwin__adjust_window,
1961 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
1966 M_iso8859_1 = msymbol ("iso8859-1");
1967 M_iso10646_1 = msymbol ("iso10646-1");
1969 display_info_list = mplist ();
1970 device_list = mplist ();
1973 xft_driver.select = mfont__ft_driver.select;
1974 xft_driver.list = mfont__ft_driver.list;
1977 Mxim = msymbol ("xim");
1978 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
1986 M17N_OBJECT_UNREF (display_info_list);
1987 M17N_OBJECT_UNREF (device_list);
1992 #ifdef X_SET_ERROR_HANDLER
1994 x_error_handler (Display *display, XErrorEvent *error)
2001 x_io_error_handler (Display *display)
2008 /** Return an MWDevice object corresponding to a display specified in
2011 It searches device_list for a device matching the display. If
2012 found, return the found object. Otherwise, return a newly created
2016 device_open (MFrame *frame, MPlist *param)
2018 Display *display = NULL;
2019 Screen *screen = NULL;
2021 Drawable drawable = 0;
2022 Widget widget = NULL;
2024 int auto_display = 0;
2025 MDisplayInfo *disp_info = NULL;
2026 MWDevice *device = NULL;
2028 XWindowAttributes attr;
2034 int use_xfont = 0, use_freetype = 0, use_xft = 0;
2036 for (plist = param; (key = mplist_key (plist)) != Mnil;
2037 plist = mplist_next (plist))
2039 if (key == Mdisplay)
2040 display = (Display *) mplist_value (plist);
2041 else if (key == Mscreen)
2042 screen = mplist_value (plist);
2043 else if (key == Mdrawable)
2044 drawable = (Drawable) mplist_value (plist);
2045 else if (key == Mdepth)
2046 depth = (unsigned) mplist_value (plist);
2047 else if (key == Mwidget)
2048 widget = (Widget) mplist_value (plist);
2049 else if (key == Mcolormap)
2050 cmap = (Colormap) mplist_value (plist);
2051 else if (key == Mfont)
2053 MSymbol val = MPLIST_SYMBOL (plist);
2057 #ifdef HAVE_FREETYPE
2058 else if (val == Mfreetype)
2061 else if (val == Mxft)
2068 /* If none of them is specified, use all of them. */
2069 if (! use_xfont && ! use_freetype && ! use_xft)
2070 use_xfont = use_freetype = use_xft = 1;
2074 display = XtDisplay (widget);
2075 screen_num = XScreenNumberOfScreen (XtScreen (widget));
2076 depth = DefaultDepth (display, screen_num);
2082 unsigned width, height, border_width;
2085 MERROR (MERROR_WIN, -1);
2086 XGetGeometry (display, drawable, &root_window,
2087 &x, &y, &width, &height, &border_width, &depth);
2088 XGetWindowAttributes (display, root_window, &attr);
2089 screen_num = XScreenNumberOfScreen (attr.screen);
2094 display = DisplayOfScreen (screen);
2099 display = XOpenDisplay (NULL);
2101 MERROR (MERROR_WIN, -1);
2104 screen = DefaultScreenOfDisplay (display);
2106 screen_num = XScreenNumberOfScreen (screen);
2108 depth = DefaultDepth (display, screen_num);
2112 cmap = DefaultColormap (display, screen_num);
2114 for (plist = display_info_list; mplist_key (plist) != Mnil;
2115 plist = mplist_next (plist))
2117 disp_info = (MDisplayInfo *) mplist_value (plist);
2118 if (disp_info->display == display)
2122 if (mplist_key (plist) != Mnil)
2123 M17N_OBJECT_REF (disp_info);
2126 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2127 disp_info->display = display;
2128 disp_info->auto_display = auto_display;
2129 disp_info->font_list = mplist ();
2130 find_modifier_bits (disp_info);
2131 disp_info->MULE_BASELINE_OFFSET
2132 = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
2133 mplist_add (display_info_list, Mt, disp_info);
2136 for (plist = device_list; mplist_key (plist) != Mnil;
2137 plist = mplist_next (plist))
2139 device = (MWDevice *) mplist_value (plist);
2140 if (device->display_info == disp_info
2141 && device->depth == depth
2142 && device->cmap == cmap
2143 && device->screen_num == screen_num)
2147 if (mplist_key (plist) != Mnil)
2148 M17N_OBJECT_REF (device);
2151 unsigned long valuemask = GCForeground;
2155 M17N_OBJECT (device, free_device, MERROR_WIN);
2156 device->display_info = disp_info;
2157 device->screen_num = screen_num;
2158 /* A drawable on which to create GCs. */
2159 device->drawable = XCreatePixmap (display,
2160 RootWindow (display, screen_num),
2162 device->depth = depth;
2163 device->cmap = cmap;
2164 pixels = DisplayHeight (display, screen_num);
2165 mm = DisplayHeightMM (display, screen_num);
2166 device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
2167 device->realized_face_list = mplist ();
2168 device->realized_font_list = mplist ();
2169 mplist_add (device->realized_font_list, Mt, NULL);
2170 device->realized_fontset_list = mplist ();
2171 device->gc_list = mplist ();
2172 values.foreground = BlackPixel (display, screen_num);
2173 device->scratch_gc = XCreateGC (display, device->drawable,
2174 valuemask, &values);
2176 device->xft_draw = XftDrawCreate (display, device->drawable,
2177 DefaultVisual (display, screen_num),
2182 frame->device = device;
2183 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2184 frame->dpi = device->resy;
2185 frame->driver = &x_driver;
2186 frame->font_driver_list = mplist ();
2190 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2193 #endif /* HAVE_XFT2 */
2194 #ifdef HAVE_FREETYPE
2196 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2197 #endif /* HAVE_FREETYPE */
2198 if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
2199 mplist_push (frame->font_driver_list, Mx, &xfont_driver);
2201 frame->realized_font_list = device->realized_font_list;
2202 frame->realized_face_list = device->realized_face_list;
2203 frame->realized_fontset_list = device->realized_fontset_list;
2207 XtResource resources[] = {
2208 { XtNfont, XtCFont, XtRString, sizeof (String),
2209 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2210 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2211 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2212 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2213 XtOffset (AppDataPtr, background), XtRString, "white" },
2214 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2215 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2218 XtGetApplicationResources (widget, &app_data,
2219 resources, XtNumber (resources), NULL, 0);
2220 frame->foreground = msymbol (app_data.foreground);
2221 frame->background = msymbol (app_data.background);
2222 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2226 app_data.font = DEFAULT_FONT;
2227 frame->foreground = msymbol ("black");
2228 frame->background = msymbol ("white");
2229 frame->videomode = Mnormal;
2232 if (strcmp (app_data.font, DEFAULT_FONT) != 0)
2234 XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
2235 unsigned long value;
2240 font = mfont_parse_name (app_data.font, Mx);
2242 && XGetFontProperty (xfont, XA_FONT, &value)
2243 && (name = ((char *) XGetAtomName (display, (Atom) value))))
2244 font = mfont_parse_name (name, Mx);
2245 XFreeFont (display, xfont);
2249 font = mfont_parse_name (DEFAULT_FONT, Mx);
2250 else if (! font->size)
2252 face = mface_from_font (font);
2254 face->property[MFACE_FONTSET] = mfontset (NULL);
2255 face->property[MFACE_FOREGROUND] = frame->foreground;
2256 face->property[MFACE_BACKGROUND] = frame->background;
2257 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2258 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2259 face->property[MFACE_VIDEOMODE] = frame->videomode;
2260 mface_put_prop (face, Mhook_func,
2261 mface_get_prop (mface__default, Mhook_func));
2262 face->property[MFACE_RATIO] = (void *) 100;
2263 mplist_push (param, Mface, face);
2264 M17N_OBJECT_UNREF (face);
2266 #ifdef X_SET_ERROR_HANDLER
2267 XSetErrorHandler (x_error_handler);
2268 XSetIOErrorHandler (x_io_error_handler);
2275 /* XIM (X Input Method) handler */
2277 typedef struct MInputXIMMethodInfo
2283 } MInputXIMMethodInfo;
2285 typedef struct MInputXIMContextInfo
2289 MConverter *converter;
2290 } MInputXIMContextInfo;
2293 xim_open_im (MInputMethod *im)
2295 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
2296 MLocale *saved, *this;
2297 char *save_modifier_list;
2299 MInputXIMMethodInfo *im_info;
2301 saved = mlocale_set (LC_CTYPE, NULL);
2302 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
2304 /* The specified locale is not supported. */
2305 MERROR (MERROR_LOCALE, -1);
2306 if (mlocale_get_prop (this, Mcoding) == Mnil)
2308 /* Unable to decode the output of XIM. */
2309 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2310 MERROR (MERROR_LOCALE, -1);
2313 if (arg->modifier_list)
2314 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
2316 save_modifier_list = XSetLocaleModifiers ("");
2317 if (! save_modifier_list)
2319 /* The specified locale is not supported by X. */
2320 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2321 MERROR (MERROR_LOCALE, -1);
2324 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
2327 /* No input method is available in the current locale. */
2328 XSetLocaleModifiers (save_modifier_list);
2329 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2330 MERROR (MERROR_WIN, -1);
2333 MSTRUCT_MALLOC (im_info, MERROR_WIN);
2334 im_info->display = arg->display;
2336 im_info->language = mlocale_get_prop (this, Mlanguage);
2337 im_info->coding = mlocale_get_prop (this, Mcoding);
2340 XSetLocaleModifiers (save_modifier_list);
2341 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2347 xim_close_im (MInputMethod *im)
2349 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
2351 XCloseIM (im_info->xim);
2356 xim_create_ic (MInputContext *ic)
2358 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
2359 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2360 MInputXIMContextInfo *ic_info;
2363 if (! arg->input_style)
2365 /* By default, use Root style. */
2366 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
2367 arg->preedit_attrs = NULL;
2368 arg->status_attrs = NULL;
2371 if (! arg->preedit_attrs && ! arg->status_attrs)
2372 xic = XCreateIC (im_info->xim,
2373 XNInputStyle, arg->input_style,
2374 XNClientWindow, arg->client_win,
2375 XNFocusWindow, arg->focus_win,
2377 else if (arg->preedit_attrs && ! arg->status_attrs)
2378 xic = XCreateIC (im_info->xim,
2379 XNInputStyle, arg->input_style,
2380 XNClientWindow, arg->client_win,
2381 XNFocusWindow, arg->focus_win,
2382 XNPreeditAttributes, arg->preedit_attrs,
2384 else if (! arg->preedit_attrs && arg->status_attrs)
2385 xic = XCreateIC (im_info->xim,
2386 XNInputStyle, arg->input_style,
2387 XNClientWindow, arg->client_win,
2388 XNFocusWindow, arg->focus_win,
2389 XNStatusAttributes, arg->status_attrs,
2392 xic = XCreateIC (im_info->xim,
2393 XNInputStyle, arg->input_style,
2394 XNClientWindow, arg->client_win,
2395 XNFocusWindow, arg->focus_win,
2396 XNPreeditAttributes, arg->preedit_attrs,
2397 XNStatusAttributes, arg->status_attrs,
2400 MERROR (MERROR_WIN, -1);
2402 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
2404 ic_info->win = arg->focus_win;
2405 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
2411 xim_destroy_ic (MInputContext *ic)
2413 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2415 XDestroyIC (ic_info->xic);
2416 mconv_free_converter (ic_info->converter);
2422 xim_filter (MInputContext *ic, MSymbol key, void *event)
2424 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2426 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
2431 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2433 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2434 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2435 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
2441 buf = (char *) alloca (512);
2442 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
2443 if (status == XBufferOverflow)
2445 buf = (char *) alloca (len);
2446 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
2449 mtext_reset (ic->produced);
2453 mconv_reset_converter (ic_info->converter);
2454 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
2455 mconv_decode (ic_info->converter, ic->produced);
2456 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2457 Mlanguage, (void *) im_info->language);
2458 mtext_cpy (mt, ic->produced);
2459 mtext_reset (ic->produced);
2467 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2471 /*** @addtogroup m17nInputMethodWin */
2476 @brief Input method driver for XIM.
2478 The driver #minput_xim_driver is for the foreign input method of
2479 name #Mxim. It uses XIM (X Input Methods) as a background input
2482 As the symbol #Mxim has property #Minput_driver whose value is
2483 a pointer to this driver, the input method of language #Mnil
2484 and name #Mxim uses this driver.
2486 Therefore, for such input methods, the driver dependent arguments
2487 to the functions whose name begin with minput_ must be as follows.
2489 The argument $ARG of the function minput_open_im () must be a
2490 pointer to the structure #MInputXIMArgIM. See the documentation
2491 of #MInputXIMArgIM for more details.
2493 The argument $ARG of the function minput_create_ic () must be a
2494 pointer to the structure #MInputXIMArgIC. See the documentation
2495 of #MInputXIMArgIC for more details.
2497 The argument $ARG of the function minput_filter () must be a
2498 pointer to the structure @c XEvent. The argument $KEY is ignored.
2500 The argument $ARG of the function minput_lookup () must be the
2501 same one as that of the function minput_filter (). The argument
2505 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2507 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
2508 XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2510 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2511 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
2512 ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2514 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
2515 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2517 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
2518 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
2520 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
2521 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
2523 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
2524 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2526 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2527 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
2529 MInputDriver minput_xim_driver =
2530 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2531 xim_filter, xim_lookup, NULL };
2535 #else /* not HAVE_X11 */
2537 int device_open () { return -1; }
2539 #endif /* not HAVE_X11 */