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