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 if (XftDrawDrawable (xft_draw) != (Drawable) win)
1250 XftDrawChange (xft_draw, (Drawable) win);
1251 XftDrawSetClip (xft_draw, (Region) region);
1253 y -= rfont->baseline_offset;
1254 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1255 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
1257 if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
1258 glyphs[nglyphs++] = g->code;
1262 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1263 last_x, y, glyphs, nglyphs);
1265 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1266 x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
1267 last_x = x + g->width;
1271 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1274 #endif /* HAVE_XFT2 */
1277 /* Functions for the device driver. */
1280 mwin__close_device (MFrame *frame)
1282 MWDevice *device = FRAME_DEVICE (frame);
1284 M17N_OBJECT_UNREF (device);
1288 mwin__device_get_prop (MFrame *frame, MSymbol key)
1290 MWDevice *device = FRAME_DEVICE (frame);
1292 if (key == Mdisplay)
1293 return (void *) device->display_info->display;
1295 return (void *) ScreenOfDisplay(device->display_info->display,
1296 device->screen_num);
1297 if (key == Mcolormap)
1298 return (void *) device->cmap;
1300 return (void *) device->depth;
1305 mwin__realize_face (MRealizedFace *rface)
1308 MSymbol foreground, background, videomode;
1309 MFaceHLineProp *hline;
1313 if (rface != rface->ascii_rface)
1315 rface->info = rface->ascii_rface->info;
1319 frame = rface->frame;
1320 MSTRUCT_CALLOC (info, MERROR_WIN);
1322 foreground = rface->face.property[MFACE_FOREGROUND];
1323 background = rface->face.property[MFACE_BACKGROUND];
1324 videomode = rface->face.property[MFACE_VIDEOMODE];
1326 videomode = frame->videomode;
1327 if (videomode != Mreverse)
1329 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1330 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1334 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1335 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1338 if (foreground == Mnil)
1339 foreground = frame->foreground;
1340 if (background == Mnil)
1341 background = frame->background;
1342 if (videomode == Mreverse)
1344 MSymbol temp = foreground;
1345 foreground = background;
1348 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1349 FRAME_VISUAL (frame),
1351 MSYMBOL_NAME (foreground),
1352 &info->xft_color_fore))
1354 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1355 FRAME_VISUAL (frame),
1357 MSYMBOL_NAME (background),
1358 &info->xft_color_back))
1360 #endif /* HAVE_XFT2 */
1362 hline = rface->hline;
1366 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1368 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1375 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1377 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1379 if (box->color_left && box->color_left != box->color_top)
1380 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1382 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1384 if (box->color_bottom && box->color_bottom != box->color_top)
1385 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1387 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1389 if (box->color_right && box->color_right != box->color_bottom)
1390 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1392 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1400 mwin__free_realized_face (MRealizedFace *rface)
1402 if (rface == rface->ascii_rface)
1408 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1410 int x, int y, int width, int height, MDrawRegion region)
1412 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1415 gc = set_region (frame, gc, region);
1417 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1418 x, y, width, height);
1423 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1424 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1425 int reverse, MDrawRegion region)
1427 MRealizedFace *rface = from->rface;
1428 Display *display = FRAME_DISPLAY (rface->frame);
1429 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1435 gc = set_region (rface->frame, gc, region);
1436 for (; from < to; from++)
1438 XDrawRectangle (display, (Window) win, gc,
1439 x, y - gstring->ascent + 1, from->width - 1,
1440 gstring->ascent + gstring->descent - 2);
1447 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1448 MRealizedFace *rface, int reverse,
1449 int x, int y, int width, MDrawRegion region)
1451 enum MFaceHLineType type = rface->hline->type;
1452 GCInfo *info = rface->info;
1453 GC gc = gc = info->gc[GC_HLINE];
1456 y = (type == MFACE_HLINE_BOTTOM
1457 ? y + gstring->text_descent - rface->hline->width
1458 : type == MFACE_HLINE_UNDER
1460 : type == MFACE_HLINE_STRIKE_THROUGH
1461 ? y - ((gstring->ascent + gstring->descent) / 2)
1462 : y - gstring->text_ascent);
1464 gc = set_region (frame, gc, region);
1466 for (i = 0; i < rface->hline->width; i++)
1467 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1468 x, y + i, x + width - 1, y + i);
1473 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1474 MGlyph *g, int x, int y, int width, MDrawRegion region)
1476 Display *display = FRAME_DISPLAY (frame);
1477 MRealizedFace *rface = g->rface;
1478 MFaceBoxProp *box = rface->box;
1479 GCInfo *info = rface->info;
1480 GC gc_top, gc_left, gc_right, gc_btm;
1484 y0 = y - (gstring->text_ascent
1485 + rface->box->inner_vmargin + rface->box->width);
1486 y1 = y + (gstring->text_descent
1487 + rface->box->inner_vmargin + rface->box->width - 1);
1489 gc_top = info->gc[GC_BOX_TOP];
1491 gc_top = set_region (frame, gc_top, region);
1492 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1495 gc_btm = info->gc[GC_BOX_BOTTOM];
1497 if (g->type == GLYPH_BOX)
1501 if (g->left_padding)
1502 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1504 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1506 /* Draw the top side. */
1507 for (i = 0; i < box->width; i++)
1508 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1510 /* Draw the bottom side. */
1511 if (region && gc_btm != gc_top)
1512 gc_btm = set_region (frame, gc_btm, region);
1513 for (i = 0; i < box->width; i++)
1514 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1516 if (g->left_padding > 0)
1518 /* Draw the left side. */
1519 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1523 gc_left = info->gc[GC_BOX_LEFT];
1525 gc_left = set_region (frame, gc_left, region);
1527 for (i = 0; i < rface->box->width; i++)
1528 XDrawLine (display, (Window) win, gc_left,
1529 x0 + i, y0 + i, x0 + i, y1 - i);
1533 /* Draw the right side. */
1534 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1538 gc_right = info->gc[GC_BOX_RIGHT];
1540 gc_right = set_region (frame, gc_right, region);
1542 for (i = 0; i < rface->box->width; i++)
1543 XDrawLine (display, (Window) win, gc_right,
1544 x1 - i, y0 + i, x1 - i, y1 - i);
1549 /* Draw the top side. */
1550 for (i = 0; i < box->width; i++)
1551 XDrawLine (display, (Window) win, gc_top,
1552 x, y0 + i, x + width - 1, y0 + i);
1554 /* Draw the bottom side. */
1555 if (region && gc_btm != gc_top)
1556 gc_btm = set_region (frame, gc_btm, region);
1557 for (i = 0; i < box->width; i++)
1558 XDrawLine (display, (Window) win, gc_btm,
1559 x, y1 - i, x + width - 1, y1 - i);
1566 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1567 int reverse, int x, int y,
1568 int width, int height, int row_bytes, unsigned char *bmp,
1571 Display *display = FRAME_DISPLAY (frame);
1573 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1576 gc = set_region (frame, gc, region);
1578 for (i = 0; i < height; i++, bmp += row_bytes)
1579 for (j = 0; j < width; j++)
1580 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1581 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1586 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1587 int intensity, MDrawPoint *points, int num,
1590 GCInfo *info = rface->info;
1593 if (! (gc = info->gc[intensity]))
1594 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1597 gc = set_region (frame, gc, region);
1599 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1600 (XPoint *) points, num, CoordModeOrigin);
1605 mwin__region_from_rect (MDrawMetric *rect)
1607 MDrawRegion region1 = XCreateRegion ();
1608 MDrawRegion region2 = XCreateRegion ();
1613 xrect.width = rect->width;
1614 xrect.height = rect->height;
1615 XUnionRectWithRegion (&xrect, region1, region2);
1616 XDestroyRegion (region1);
1621 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1623 MDrawRegion region1 = XCreateRegion ();
1628 xrect.width = rect->width;
1629 xrect.height = rect->height;
1631 XUnionRegion (region, region, region1);
1632 XUnionRectWithRegion (&xrect, region1, region);
1633 XDestroyRegion (region1);
1637 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1639 MDrawRegion region = XCreateRegion ();
1641 XUnionRegion (region1, region1, region);
1642 XIntersectRegion (region, region2, region1);
1643 XDestroyRegion (region);
1647 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1649 MDrawRegion region1 = XCreateRegion ();
1654 xrect.width = rect->width;
1655 xrect.height = rect->height;
1656 XUnionRectWithRegion (&xrect, region1, region);
1657 XDestroyRegion (region1);
1661 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1665 XClipBox (region, &xrect);
1668 rect->width = xrect.width;
1669 rect->height = xrect.height;
1673 mwin__free_region (MDrawRegion region)
1675 XDestroyRegion (region);
1679 mwin__dump_region (MDrawRegion region)
1682 XClipBox (region, &rect);
1683 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1688 mwin__create_window (MFrame *frame, MDrawWindow parent)
1690 Display *display = FRAME_DISPLAY (frame);
1692 XWMHints wm_hints = { InputHint, False };
1693 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1694 XSetWindowAttributes set_attrs;
1697 GCInfo *info = frame->rface->info;
1700 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1701 mask = GCForeground;
1702 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1703 set_attrs.background_pixel = values.foreground;
1704 set_attrs.backing_store = Always;
1705 set_attrs.override_redirect = True;
1706 set_attrs.save_under = True;
1707 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1708 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1709 CopyFromParent, InputOutput, CopyFromParent,
1711 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1712 NULL, &wm_hints, &class_hints);
1713 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1714 return (MDrawWindow) win;
1718 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1721 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1723 if (XftDrawDrawable (xft_draw) == (Drawable) win)
1724 XftDrawChange (xft_draw, FRAME_DEVICE (frame)->drawable);
1725 #endif /* HAVE_XFT2 */
1726 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1731 mwin__event_window (void *event)
1733 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1737 mwin__print_event (void *arg, char *win_name)
1740 XEvent *event = (XEvent *) arg;
1742 switch (event->xany.type)
1744 case 2: event_name = "KeyPress"; break;
1745 case 3: event_name = "KeyRelease"; break;
1746 case 4: event_name = "ButtonPress"; break;
1747 case 5: event_name = "ButtonRelease"; break;
1748 case 6: event_name = "MotionNotify"; break;
1749 case 7: event_name = "EnterNotify"; break;
1750 case 8: event_name = "LeaveNotify"; break;
1751 case 9: event_name = "FocusIn"; break;
1752 case 10: event_name = "FocusOut"; break;
1753 case 11: event_name = "KeymapNotify"; break;
1754 case 12: event_name = "Expose"; break;
1755 case 13: event_name = "GraphicsExpose"; break;
1756 case 14: event_name = "NoExpose"; break;
1757 case 15: event_name = "VisibilityNotify"; break;
1758 case 16: event_name = "CreateNotify"; break;
1759 case 17: event_name = "DestroyNotify"; break;
1760 case 18: event_name = "UnmapNotify"; break;
1761 case 19: event_name = "MapNotify"; break;
1762 case 20: event_name = "MapRequest"; break;
1763 case 21: event_name = "ReparentNotify"; break;
1764 case 22: event_name = "ConfigureNotify"; break;
1765 case 23: event_name = "ConfigureRequest"; break;
1766 case 24: event_name = "GravityNotify"; break;
1767 case 25: event_name = "ResizeRequest"; break;
1768 case 26: event_name = "CirculateNotify"; break;
1769 case 27: event_name = "CirculateRequest"; break;
1770 case 28: event_name = "PropertyNotify"; break;
1771 case 29: event_name = "SelectionClear"; break;
1772 case 30: event_name = "SelectionRequest"; break;
1773 case 31: event_name = "SelectionNotify"; break;
1774 case 32: event_name = "ColormapNotify"; break;
1775 case 33: event_name = "ClientMessage"; break;
1776 case 34: event_name = "MappingNotify"; break;
1777 default: event_name = "unknown";
1780 fprintf (stderr, "%s: %s\n", win_name, event_name);
1785 mwin__map_window (MFrame *frame, MDrawWindow win)
1787 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1791 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1793 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1797 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1798 MDrawMetric *geometry)
1800 Display *display = FRAME_DISPLAY (frame);
1801 XWindowAttributes attr;
1802 Window parent = (Window) parent_win, root;
1804 XGetWindowAttributes (display, (Window) win, &attr);
1805 geometry->x = attr.x + attr.border_width;
1806 geometry->y = attr.y + attr.border_width;
1807 geometry->width = attr.width;
1808 geometry->height = attr.height;
1811 parent = RootWindow (display, FRAME_SCREEN (frame));
1814 Window this_parent, *children;
1817 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1820 if (this_parent == parent || this_parent == root)
1822 win = (MDrawWindow) this_parent;
1823 XGetWindowAttributes (display, (Window) win, &attr);
1824 geometry->x += attr.x + attr.border_width;
1825 geometry->y += attr.y + attr.border_width;
1830 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1831 MDrawMetric *current, MDrawMetric *new)
1833 Display *display = FRAME_DISPLAY (frame);
1834 unsigned int mask = 0;
1835 XWindowChanges values;
1837 if (current->width != new->width)
1840 if (new->width <= 0)
1842 values.width = current->width = new->width;
1844 if (current->height != new->height)
1847 if (new->height <= 0)
1849 values.height = current->height = new->height;
1851 if (current->x != new->x)
1854 values.x = current->x = new->x;
1856 if (current->y != new->y)
1859 current->y = new->y;
1860 values.y = current->y = new->y;
1863 XConfigureWindow (display, (Window) win, mask, &values);
1864 XClearWindow (display, (Window) win);
1868 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1870 XEvent *event = (XEvent *) arg;
1871 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
1878 if (event->xany.type != KeyPress
1879 /* && event->xany.type != KeyRelease */
1882 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
1889 if (c < XK_space || c > XK_asciitilde)
1891 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
1892 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1893 if (((XKeyEvent *) event)->state & ControlMask)
1895 if (c >= 'a' && c <= 'z')
1897 if (c >= ' ' && c < 127)
1898 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1900 key = minput__char_to_key (c);
1902 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
1906 char *str = XKeysymToString (keysym);
1910 key = msymbol (str);
1911 if (((XKeyEvent *) event)->state & ShiftMask)
1912 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1913 if (((XKeyEvent *) event)->state & ControlMask)
1914 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1916 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
1917 *modifiers |= MINPUT_KEY_META_MODIFIER;
1918 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
1919 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
1920 if (((XKeyEvent *) event)->state & disp_info->super_mask)
1921 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
1922 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
1923 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
1930 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
1932 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
1934 Display *display = FRAME_DISPLAY (frame);
1935 GCInfo *info = rface->info;
1938 for (i = 0; i <= GC_INVERSE; i++)
1940 XGetGCValues (display, info->gc[i], valuemask, &values);
1941 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
1942 values.foreground, values.background);
1943 fprintf (stderr, "\n");
1947 static MDeviceDriver x_driver =
1950 mwin__device_get_prop,
1952 mwin__free_realized_face,
1954 mwin__draw_empty_boxes,
1958 mwin__region_from_rect,
1959 mwin__union_rect_with_region,
1960 mwin__intersect_region,
1961 mwin__region_add_rect,
1962 mwin__region_to_rect,
1965 mwin__create_window,
1966 mwin__destroy_window,
1969 mwin__window_geometry,
1970 mwin__adjust_window,
1974 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
1979 M_iso8859_1 = msymbol ("iso8859-1");
1980 M_iso10646_1 = msymbol ("iso10646-1");
1982 display_info_list = mplist ();
1983 device_list = mplist ();
1986 xft_driver.select = mfont__ft_driver.select;
1987 xft_driver.list = mfont__ft_driver.list;
1990 Mxim = msymbol ("xim");
1991 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
1999 M17N_OBJECT_UNREF (display_info_list);
2000 M17N_OBJECT_UNREF (device_list);
2005 #ifdef X_SET_ERROR_HANDLER
2007 x_error_handler (Display *display, XErrorEvent *error)
2014 x_io_error_handler (Display *display)
2021 /** Return an MWDevice object corresponding to a display specified in
2024 It searches device_list for a device matching the display. If
2025 found, return the found object. Otherwise, return a newly created
2029 device_open (MFrame *frame, MPlist *param)
2031 Display *display = NULL;
2032 Screen *screen = NULL;
2034 Drawable drawable = 0;
2035 Widget widget = NULL;
2037 int auto_display = 0;
2038 MDisplayInfo *disp_info = NULL;
2039 MWDevice *device = NULL;
2041 XWindowAttributes attr;
2047 int use_xfont = 0, use_freetype = 0, use_xft = 0;
2049 for (plist = param; (key = mplist_key (plist)) != Mnil;
2050 plist = mplist_next (plist))
2052 if (key == Mdisplay)
2053 display = (Display *) mplist_value (plist);
2054 else if (key == Mscreen)
2055 screen = mplist_value (plist);
2056 else if (key == Mdrawable)
2057 drawable = (Drawable) mplist_value (plist);
2058 else if (key == Mdepth)
2059 depth = (unsigned) mplist_value (plist);
2060 else if (key == Mwidget)
2061 widget = (Widget) mplist_value (plist);
2062 else if (key == Mcolormap)
2063 cmap = (Colormap) mplist_value (plist);
2064 else if (key == Mfont)
2066 MSymbol val = MPLIST_SYMBOL (plist);
2070 #ifdef HAVE_FREETYPE
2071 else if (val == Mfreetype)
2074 else if (val == Mxft)
2081 /* If none of them is specified, use all of them. */
2082 if (! use_xfont && ! use_freetype && ! use_xft)
2083 use_xfont = use_freetype = use_xft = 1;
2087 display = XtDisplay (widget);
2088 screen_num = XScreenNumberOfScreen (XtScreen (widget));
2089 depth = DefaultDepth (display, screen_num);
2095 unsigned width, height, border_width;
2098 MERROR (MERROR_WIN, -1);
2099 XGetGeometry (display, drawable, &root_window,
2100 &x, &y, &width, &height, &border_width, &depth);
2101 XGetWindowAttributes (display, root_window, &attr);
2102 screen_num = XScreenNumberOfScreen (attr.screen);
2107 display = DisplayOfScreen (screen);
2112 display = XOpenDisplay (NULL);
2114 MERROR (MERROR_WIN, -1);
2117 screen = DefaultScreenOfDisplay (display);
2119 screen_num = XScreenNumberOfScreen (screen);
2121 depth = DefaultDepth (display, screen_num);
2125 cmap = DefaultColormap (display, screen_num);
2127 for (plist = display_info_list; mplist_key (plist) != Mnil;
2128 plist = mplist_next (plist))
2130 disp_info = (MDisplayInfo *) mplist_value (plist);
2131 if (disp_info->display == display)
2135 if (mplist_key (plist) != Mnil)
2136 M17N_OBJECT_REF (disp_info);
2139 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2140 disp_info->display = display;
2141 disp_info->auto_display = auto_display;
2142 disp_info->font_list = mplist ();
2143 find_modifier_bits (disp_info);
2144 disp_info->MULE_BASELINE_OFFSET
2145 = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
2146 disp_info->AVERAGE_WIDTH
2147 = XInternAtom (display, "AVERAGE_WIDTH", False);
2148 mplist_add (display_info_list, Mt, disp_info);
2151 for (plist = device_list; mplist_key (plist) != Mnil;
2152 plist = mplist_next (plist))
2154 device = (MWDevice *) mplist_value (plist);
2155 if (device->display_info == disp_info
2156 && device->depth == depth
2157 && device->cmap == cmap
2158 && device->screen_num == screen_num)
2162 if (mplist_key (plist) != Mnil)
2163 M17N_OBJECT_REF (device);
2166 unsigned long valuemask = GCForeground;
2170 M17N_OBJECT (device, free_device, MERROR_WIN);
2171 device->display_info = disp_info;
2172 device->screen_num = screen_num;
2173 /* A drawable on which to create GCs. */
2174 device->drawable = XCreatePixmap (display,
2175 RootWindow (display, screen_num),
2177 device->depth = depth;
2178 device->cmap = cmap;
2179 pixels = DisplayHeight (display, screen_num);
2180 mm = DisplayHeightMM (display, screen_num);
2181 device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
2182 device->realized_face_list = mplist ();
2183 device->realized_font_list = mplist ();
2184 mplist_add (device->realized_font_list, Mt, NULL);
2185 device->realized_fontset_list = mplist ();
2186 device->gc_list = mplist ();
2187 values.foreground = BlackPixel (display, screen_num);
2188 device->scratch_gc = XCreateGC (display, device->drawable,
2189 valuemask, &values);
2191 device->xft_draw = XftDrawCreate (display, device->drawable,
2192 DefaultVisual (display, screen_num),
2197 frame->device = device;
2198 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2199 frame->dpi = device->resy;
2200 frame->driver = &x_driver;
2201 frame->font_driver_list = mplist ();
2205 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2208 #endif /* HAVE_XFT2 */
2209 #ifdef HAVE_FREETYPE
2211 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2212 #endif /* HAVE_FREETYPE */
2213 if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
2214 mplist_push (frame->font_driver_list, Mx, &xfont_driver);
2216 frame->realized_font_list = device->realized_font_list;
2217 frame->realized_face_list = device->realized_face_list;
2218 frame->realized_fontset_list = device->realized_fontset_list;
2222 XtResource resources[] = {
2223 { XtNfont, XtCFont, XtRString, sizeof (String),
2224 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2225 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2226 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2227 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2228 XtOffset (AppDataPtr, background), XtRString, "white" },
2229 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2230 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2233 XtGetApplicationResources (widget, &app_data,
2234 resources, XtNumber (resources), NULL, 0);
2235 frame->foreground = msymbol (app_data.foreground);
2236 frame->background = msymbol (app_data.background);
2237 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2241 app_data.font = DEFAULT_FONT;
2242 frame->foreground = msymbol ("black");
2243 frame->background = msymbol ("white");
2244 frame->videomode = Mnormal;
2247 if (strcmp (app_data.font, DEFAULT_FONT) != 0)
2249 XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
2250 unsigned long value;
2255 font = mfont_parse_name (app_data.font, Mx);
2257 && XGetFontProperty (xfont, XA_FONT, &value)
2258 && (name = ((char *) XGetAtomName (display, (Atom) value))))
2259 font = mfont_parse_name (name, Mx);
2260 XFreeFont (display, xfont);
2264 font = mfont_parse_name (DEFAULT_FONT, Mx);
2265 else if (! font->size)
2267 face = mface_from_font (font);
2269 face->property[MFACE_FONTSET] = mfontset (NULL);
2270 face->property[MFACE_FOREGROUND] = frame->foreground;
2271 face->property[MFACE_BACKGROUND] = frame->background;
2272 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2273 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2274 face->property[MFACE_VIDEOMODE] = frame->videomode;
2275 mface_put_prop (face, Mhook_func,
2276 mface_get_prop (mface__default, Mhook_func));
2277 face->property[MFACE_RATIO] = (void *) 100;
2278 mplist_push (param, Mface, face);
2279 M17N_OBJECT_UNREF (face);
2281 #ifdef X_SET_ERROR_HANDLER
2282 XSetErrorHandler (x_error_handler);
2283 XSetIOErrorHandler (x_io_error_handler);
2290 /* XIM (X Input Method) handler */
2292 typedef struct MInputXIMMethodInfo
2298 } MInputXIMMethodInfo;
2300 typedef struct MInputXIMContextInfo
2304 MConverter *converter;
2305 } MInputXIMContextInfo;
2308 xim_open_im (MInputMethod *im)
2310 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
2311 MLocale *saved, *this;
2312 char *save_modifier_list;
2314 MInputXIMMethodInfo *im_info;
2316 saved = mlocale_set (LC_CTYPE, NULL);
2317 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
2319 /* The specified locale is not supported. */
2320 MERROR (MERROR_LOCALE, -1);
2321 if (mlocale_get_prop (this, Mcoding) == Mnil)
2323 /* Unable to decode the output of XIM. */
2324 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2325 MERROR (MERROR_LOCALE, -1);
2328 if (arg->modifier_list)
2329 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
2331 save_modifier_list = XSetLocaleModifiers ("");
2332 if (! save_modifier_list)
2334 /* The specified locale is not supported by X. */
2335 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2336 MERROR (MERROR_LOCALE, -1);
2339 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
2342 /* No input method is available in the current locale. */
2343 XSetLocaleModifiers (save_modifier_list);
2344 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2345 MERROR (MERROR_WIN, -1);
2348 MSTRUCT_MALLOC (im_info, MERROR_WIN);
2349 im_info->display = arg->display;
2351 im_info->language = mlocale_get_prop (this, Mlanguage);
2352 im_info->coding = mlocale_get_prop (this, Mcoding);
2355 XSetLocaleModifiers (save_modifier_list);
2356 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2362 xim_close_im (MInputMethod *im)
2364 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
2366 XCloseIM (im_info->xim);
2371 xim_create_ic (MInputContext *ic)
2373 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
2374 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2375 MInputXIMContextInfo *ic_info;
2378 if (! arg->input_style)
2380 /* By default, use Root style. */
2381 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
2382 arg->preedit_attrs = NULL;
2383 arg->status_attrs = NULL;
2386 if (! arg->preedit_attrs && ! arg->status_attrs)
2387 xic = XCreateIC (im_info->xim,
2388 XNInputStyle, arg->input_style,
2389 XNClientWindow, arg->client_win,
2390 XNFocusWindow, arg->focus_win,
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 XNPreeditAttributes, arg->preedit_attrs,
2399 else if (! arg->preedit_attrs && 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 XNStatusAttributes, arg->status_attrs,
2407 xic = XCreateIC (im_info->xim,
2408 XNInputStyle, arg->input_style,
2409 XNClientWindow, arg->client_win,
2410 XNFocusWindow, arg->focus_win,
2411 XNPreeditAttributes, arg->preedit_attrs,
2412 XNStatusAttributes, arg->status_attrs,
2415 MERROR (MERROR_WIN, -1);
2417 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
2419 ic_info->win = arg->focus_win;
2420 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
2426 xim_destroy_ic (MInputContext *ic)
2428 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2430 XDestroyIC (ic_info->xic);
2431 mconv_free_converter (ic_info->converter);
2437 xim_filter (MInputContext *ic, MSymbol key, void *event)
2439 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2441 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
2446 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2448 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2449 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2450 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
2456 buf = (char *) alloca (512);
2457 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
2458 if (status == XBufferOverflow)
2460 buf = (char *) alloca (len);
2461 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
2464 mtext_reset (ic->produced);
2468 mconv_reset_converter (ic_info->converter);
2469 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
2470 mconv_decode (ic_info->converter, ic->produced);
2471 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2472 Mlanguage, (void *) im_info->language);
2473 mtext_cpy (mt, ic->produced);
2474 mtext_reset (ic->produced);
2482 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2486 /*** @addtogroup m17nInputMethodWin */
2491 @brief Input method driver for XIM.
2493 The driver #minput_xim_driver is for the foreign input method of
2494 name #Mxim. It uses XIM (X Input Methods) as a background input
2497 As the symbol #Mxim has property #Minput_driver whose value is
2498 a pointer to this driver, the input method of language #Mnil
2499 and name #Mxim uses this driver.
2501 Therefore, for such input methods, the driver dependent arguments
2502 to the functions whose name begin with minput_ must be as follows.
2504 The argument $ARG of the function minput_open_im () must be a
2505 pointer to the structure #MInputXIMArgIM. See the documentation
2506 of #MInputXIMArgIM for more details.
2508 The argument $ARG of the function minput_create_ic () must be a
2509 pointer to the structure #MInputXIMArgIC. See the documentation
2510 of #MInputXIMArgIC for more details.
2512 The argument $ARG of the function minput_filter () must be a
2513 pointer to the structure @c XEvent. The argument $KEY is ignored.
2515 The argument $ARG of the function minput_lookup () must be the
2516 same one as that of the function minput_filter (). The argument
2520 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2522 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
2523 XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2525 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2526 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
2527 ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2529 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
2530 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2532 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
2533 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
2535 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
2536 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
2538 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
2539 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2541 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2542 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
2544 MInputDriver minput_xim_driver =
2545 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2546 xim_filter, xim_lookup, NULL };
2550 #else /* not HAVE_X11 */
2552 int device_open () { return -1; }
2554 #endif /* not HAVE_X11 */