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);
446 static int xfont_check_capability (MRealizedFont *rfont, MSymbol capability);
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, xfont_check_capability };
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);
996 xfont_check_capability (MRealizedFont *rfont, MSymbol capability)
998 /* Currently X font driver doesn't support any capability. */
1012 XftFont *font_no_aa;
1014 /* Pointer to MRealizedFontFT */
1018 static MRealizedFont *xft_open (MFrame *frame, MFont *font, MFont *spec,
1020 static int xft_has_char (MFrame *frame, MFont *font, MFont *spec,
1021 int c, unsigned code);
1022 static unsigned xft_encode_char (MFrame *frame, MFont *font, MFont *spec,
1024 static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
1025 static void xft_render (MDrawWindow, int, int, MGlyphString *,
1026 MGlyph *, MGlyph *, int, MDrawRegion);
1027 static int xft_check_capability (MRealizedFont *rfont, MSymbol capability);
1029 MFontDriver xft_driver =
1031 xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL,
1032 xft_check_capability
1036 close_xft (void *object)
1038 MRealizedFontXft *rfont_xft = object;
1040 if (rfont_xft->font_aa)
1041 XftFontClose (rfont_xft->display, rfont_xft->font_aa);
1042 if (rfont_xft->font_no_aa)
1043 XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
1044 M17N_OBJECT_UNREF (rfont_xft->info);
1050 xft_open_font (Display *display, MSymbol file, double size,
1056 pattern = FcPatternCreate ();
1057 FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
1058 FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
1059 FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
1060 font = XftFontOpenPattern (display, pattern);
1065 static MRealizedFont *
1066 xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
1068 Display *display = FRAME_DISPLAY (frame);
1069 int reg = spec->property[MFONT_REGISTRY];
1071 MRealizedFontXft *rfont_xft;
1072 FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
1073 double size = font->size ? font->size : spec->size;
1075 int ascent, descent, max_advance, average_width, baseline_offset;
1079 MRealizedFont *save = NULL;
1081 for (; rfont; rfont = rfont->next)
1082 if (rfont->font == font
1083 && (rfont->font->size ? rfont->font->size == size
1084 : rfont->spec.size == size)
1085 && rfont->spec.property[MFONT_REGISTRY] == reg)
1089 if (rfont->driver == &xft_driver)
1094 rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
1097 ascent = rfont->ascent;
1098 descent = rfont->descent;
1099 max_advance = rfont->max_advance;
1100 average_width = rfont->average_width;
1101 baseline_offset = rfont->baseline_offset;
1102 spec = &rfont->spec;
1103 ft_face = rfont->fontp;
1104 xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
1107 M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
1108 rfont_xft->display = display;
1109 if (anti_alias == FcTrue)
1110 rfont_xft->font_aa = xft_font;
1112 rfont_xft->font_no_aa = xft_font;
1113 rfont_xft->ft_face = ft_face;
1114 rfont_xft->info = rfont->info;
1115 M17N_OBJECT_REF (rfont->info);
1116 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
1117 rfont->spec = *spec;
1118 rfont->frame = frame;
1120 rfont->driver = &xft_driver;
1121 rfont->info = rfont_xft;
1122 rfont->ascent = ascent;
1123 rfont->descent = descent;
1124 rfont->max_advance = max_advance;
1125 rfont->average_width = average_width;
1126 rfont->baseline_offset = baseline_offset;
1127 rfont->fontp = xft_font;
1128 rfont->next = MPLIST_VAL (frame->realized_font_list);
1129 MPLIST_VAL (frame->realized_font_list) = rfont;
1134 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1137 Display *display = FRAME_DISPLAY (rfont->frame);
1138 XftFont *xft_font = rfont->fontp;
1139 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1141 for (; g != gend; g++)
1143 if (g->code == MCHAR_INVALID_CODE)
1146 g->rbearing = xft_font->max_advance_width;
1147 g->width = g->rbearing;
1148 g->ascent = xft_font->ascent;
1149 g->descent = xft_font->descent;
1155 XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
1156 g->lbearing = - extents.x;
1157 g->rbearing = extents.width - extents.x;
1158 g->width = extents.xOff;
1159 g->ascent = extents.y;
1160 g->descent = extents.height - extents.y;
1166 xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
1170 if (font->type == MFONT_TYPE_REALIZED)
1172 MRealizedFont *rfont = (MRealizedFont *) font;
1173 MRealizedFontXft *rfont_xft = rfont->info;
1175 rfont->info = rfont_xft->info;
1176 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1177 rfont->info = rfont_xft;
1180 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1185 xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
1187 if (font->type == MFONT_TYPE_REALIZED)
1189 MRealizedFont *rfont = (MRealizedFont *) font;
1190 MRealizedFontXft *rfont_xft = rfont->info;
1192 rfont->info = rfont_xft->info;
1193 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1194 rfont->info = rfont_xft;
1197 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1202 xft_render (MDrawWindow win, int x, int y,
1203 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1204 int reverse, MDrawRegion region)
1206 MRealizedFace *rface = from->rface;
1207 MFrame *frame = rface->frame;
1208 Display *display = FRAME_DISPLAY (frame);
1209 MRealizedFont *rfont = rface->rfont;
1210 MRealizedFontXft *rfont_xft = rfont->info;
1211 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1212 XftColor *xft_color = (! reverse
1213 ? &((GCInfo *) rface->info)->xft_color_fore
1214 : &((GCInfo *) rface->info)->xft_color_back);
1215 int anti_alias = (gstring->control.anti_alias
1216 && FRAME_DEVICE (frame)->depth > 1);
1228 if (rfont_xft->font_aa)
1229 xft_font = rfont_xft->font_aa;
1232 double size = rfont->spec.size;
1234 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1237 rfont_xft->font_aa = xft_font;
1239 xft_font = rfont->fontp;
1244 if (rfont_xft->font_no_aa)
1245 xft_font = rfont_xft->font_no_aa;
1248 double size = rfont->spec.size;
1250 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1253 rfont_xft->font_no_aa = xft_font;
1255 xft_font = rfont->fontp;
1259 XftDrawChange (xft_draw, (Drawable) win);
1260 XftDrawSetClip (xft_draw, (Region) region);
1262 y -= rfont->baseline_offset;
1263 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1264 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
1266 if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
1267 glyphs[nglyphs++] = g->code;
1271 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1272 last_x, y, glyphs, nglyphs);
1274 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1275 x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
1276 last_x = x + g->width;
1280 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1284 xft_check_capability (MRealizedFont *rfont, MSymbol capability)
1286 MRealizedFontXft *rfont_xft = rfont->info;
1289 rfont->info = rfont_xft->info;
1290 result = mfont__ft_driver.check_capability (rfont, capability);
1291 rfont->info = rfont_xft;
1295 #endif /* HAVE_XFT2 */
1298 /* Functions for the device driver. */
1301 mwin__close_device (MFrame *frame)
1303 MWDevice *device = FRAME_DEVICE (frame);
1305 M17N_OBJECT_UNREF (device);
1309 mwin__device_get_prop (MFrame *frame, MSymbol key)
1311 MWDevice *device = FRAME_DEVICE (frame);
1313 if (key == Mdisplay)
1314 return (void *) device->display_info->display;
1316 return (void *) ScreenOfDisplay(device->display_info->display,
1317 device->screen_num);
1318 if (key == Mcolormap)
1319 return (void *) device->cmap;
1321 return (void *) device->depth;
1326 mwin__realize_face (MRealizedFace *rface)
1329 MSymbol foreground, background, videomode;
1330 MFaceHLineProp *hline;
1334 if (rface != rface->ascii_rface)
1336 rface->info = rface->ascii_rface->info;
1340 frame = rface->frame;
1341 MSTRUCT_CALLOC (info, MERROR_WIN);
1343 foreground = rface->face.property[MFACE_FOREGROUND];
1344 background = rface->face.property[MFACE_BACKGROUND];
1345 videomode = rface->face.property[MFACE_VIDEOMODE];
1347 videomode = frame->videomode;
1348 if (videomode != Mreverse)
1350 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1351 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1355 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1356 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1359 if (foreground == Mnil)
1360 foreground = frame->foreground;
1361 if (background == Mnil)
1362 background = frame->background;
1363 if (videomode == Mreverse)
1365 MSymbol temp = foreground;
1366 foreground = background;
1369 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1370 FRAME_VISUAL (frame),
1372 MSYMBOL_NAME (foreground),
1373 &info->xft_color_fore))
1375 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1376 FRAME_VISUAL (frame),
1378 MSYMBOL_NAME (background),
1379 &info->xft_color_back))
1381 #endif /* HAVE_XFT2 */
1383 hline = rface->hline;
1387 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1389 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1396 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1398 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1400 if (box->color_left && box->color_left != box->color_top)
1401 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1403 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1405 if (box->color_bottom && box->color_bottom != box->color_top)
1406 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1408 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1410 if (box->color_right && box->color_right != box->color_bottom)
1411 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1413 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1421 mwin__free_realized_face (MRealizedFace *rface)
1423 if (rface == rface->ascii_rface)
1429 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1431 int x, int y, int width, int height, MDrawRegion region)
1433 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1436 gc = set_region (frame, gc, region);
1438 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1439 x, y, width, height);
1444 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1445 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1446 int reverse, MDrawRegion region)
1448 MRealizedFace *rface = from->rface;
1449 Display *display = FRAME_DISPLAY (rface->frame);
1450 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1456 gc = set_region (rface->frame, gc, region);
1457 for (; from < to; from++)
1459 XDrawRectangle (display, (Window) win, gc,
1460 x, y - gstring->ascent + 1, from->width - 1,
1461 gstring->ascent + gstring->descent - 2);
1468 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1469 MRealizedFace *rface, int reverse,
1470 int x, int y, int width, MDrawRegion region)
1472 enum MFaceHLineType type = rface->hline->type;
1473 GCInfo *info = rface->info;
1474 GC gc = gc = info->gc[GC_HLINE];
1477 y = (type == MFACE_HLINE_BOTTOM
1478 ? y + gstring->text_descent - rface->hline->width
1479 : type == MFACE_HLINE_UNDER
1481 : type == MFACE_HLINE_STRIKE_THROUGH
1482 ? y - ((gstring->ascent + gstring->descent) / 2)
1483 : y - gstring->text_ascent);
1485 gc = set_region (frame, gc, region);
1487 for (i = 0; i < rface->hline->width; i++)
1488 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1489 x, y + i, x + width - 1, y + i);
1494 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1495 MGlyph *g, int x, int y, int width, MDrawRegion region)
1497 Display *display = FRAME_DISPLAY (frame);
1498 MRealizedFace *rface = g->rface;
1499 MFaceBoxProp *box = rface->box;
1500 GCInfo *info = rface->info;
1501 GC gc_top, gc_left, gc_right, gc_btm;
1505 y0 = y - (gstring->text_ascent
1506 + rface->box->inner_vmargin + rface->box->width);
1507 y1 = y + (gstring->text_descent
1508 + rface->box->inner_vmargin + rface->box->width - 1);
1510 gc_top = info->gc[GC_BOX_TOP];
1512 gc_top = set_region (frame, gc_top, region);
1513 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1516 gc_btm = info->gc[GC_BOX_BOTTOM];
1518 if (g->type == GLYPH_BOX)
1522 if (g->left_padding)
1523 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1525 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1527 /* Draw the top side. */
1528 for (i = 0; i < box->width; i++)
1529 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1531 /* Draw the bottom side. */
1532 if (region && gc_btm != gc_top)
1533 gc_btm = set_region (frame, gc_btm, region);
1534 for (i = 0; i < box->width; i++)
1535 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1537 if (g->left_padding > 0)
1539 /* Draw the left side. */
1540 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1544 gc_left = info->gc[GC_BOX_LEFT];
1546 gc_left = set_region (frame, gc_left, region);
1548 for (i = 0; i < rface->box->width; i++)
1549 XDrawLine (display, (Window) win, gc_left,
1550 x0 + i, y0 + i, x0 + i, y1 - i);
1554 /* Draw the right side. */
1555 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1559 gc_right = info->gc[GC_BOX_RIGHT];
1561 gc_right = set_region (frame, gc_right, region);
1563 for (i = 0; i < rface->box->width; i++)
1564 XDrawLine (display, (Window) win, gc_right,
1565 x1 - i, y0 + i, x1 - i, y1 - i);
1570 /* Draw the top side. */
1571 for (i = 0; i < box->width; i++)
1572 XDrawLine (display, (Window) win, gc_top,
1573 x, y0 + i, x + width - 1, y0 + i);
1575 /* Draw the bottom side. */
1576 if (region && gc_btm != gc_top)
1577 gc_btm = set_region (frame, gc_btm, region);
1578 for (i = 0; i < box->width; i++)
1579 XDrawLine (display, (Window) win, gc_btm,
1580 x, y1 - i, x + width - 1, y1 - i);
1587 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1588 int reverse, int x, int y,
1589 int width, int height, int row_bytes, unsigned char *bmp,
1592 Display *display = FRAME_DISPLAY (frame);
1594 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1597 gc = set_region (frame, gc, region);
1599 for (i = 0; i < height; i++, bmp += row_bytes)
1600 for (j = 0; j < width; j++)
1601 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1602 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1607 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1608 int intensity, MDrawPoint *points, int num,
1611 GCInfo *info = rface->info;
1614 if (! (gc = info->gc[intensity]))
1615 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1618 gc = set_region (frame, gc, region);
1620 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1621 (XPoint *) points, num, CoordModeOrigin);
1626 mwin__region_from_rect (MDrawMetric *rect)
1628 MDrawRegion region1 = XCreateRegion ();
1629 MDrawRegion region2 = XCreateRegion ();
1634 xrect.width = rect->width;
1635 xrect.height = rect->height;
1636 XUnionRectWithRegion (&xrect, region1, region2);
1637 XDestroyRegion (region1);
1642 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1644 MDrawRegion region1 = XCreateRegion ();
1649 xrect.width = rect->width;
1650 xrect.height = rect->height;
1652 XUnionRegion (region, region, region1);
1653 XUnionRectWithRegion (&xrect, region1, region);
1654 XDestroyRegion (region1);
1658 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1660 MDrawRegion region = XCreateRegion ();
1662 XUnionRegion (region1, region1, region);
1663 XIntersectRegion (region, region2, region1);
1664 XDestroyRegion (region);
1668 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1670 MDrawRegion region1 = XCreateRegion ();
1675 xrect.width = rect->width;
1676 xrect.height = rect->height;
1677 XUnionRectWithRegion (&xrect, region1, region);
1678 XDestroyRegion (region1);
1682 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1686 XClipBox (region, &xrect);
1689 rect->width = xrect.width;
1690 rect->height = xrect.height;
1694 mwin__free_region (MDrawRegion region)
1696 XDestroyRegion (region);
1700 mwin__dump_region (MDrawRegion region)
1703 XClipBox (region, &rect);
1704 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1709 mwin__create_window (MFrame *frame, MDrawWindow parent)
1711 Display *display = FRAME_DISPLAY (frame);
1713 XWMHints wm_hints = { InputHint, False };
1714 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1715 XSetWindowAttributes set_attrs;
1718 GCInfo *info = frame->rface->info;
1721 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1722 mask = GCForeground;
1723 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1724 set_attrs.background_pixel = values.foreground;
1725 set_attrs.backing_store = Always;
1726 set_attrs.override_redirect = True;
1727 set_attrs.save_under = True;
1728 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1729 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1730 CopyFromParent, InputOutput, CopyFromParent,
1732 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1733 NULL, &wm_hints, &class_hints);
1734 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1735 return (MDrawWindow) win;
1739 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1742 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1744 if (XftDrawDrawable (xft_draw) == (Drawable) win)
1745 XftDrawChange (xft_draw, FRAME_DEVICE (frame)->drawable);
1746 #endif /* HAVE_XFT2 */
1747 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1752 mwin__event_window (void *event)
1754 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1758 mwin__print_event (void *arg, char *win_name)
1761 XEvent *event = (XEvent *) arg;
1763 switch (event->xany.type)
1765 case 2: event_name = "KeyPress"; break;
1766 case 3: event_name = "KeyRelease"; break;
1767 case 4: event_name = "ButtonPress"; break;
1768 case 5: event_name = "ButtonRelease"; break;
1769 case 6: event_name = "MotionNotify"; break;
1770 case 7: event_name = "EnterNotify"; break;
1771 case 8: event_name = "LeaveNotify"; break;
1772 case 9: event_name = "FocusIn"; break;
1773 case 10: event_name = "FocusOut"; break;
1774 case 11: event_name = "KeymapNotify"; break;
1775 case 12: event_name = "Expose"; break;
1776 case 13: event_name = "GraphicsExpose"; break;
1777 case 14: event_name = "NoExpose"; break;
1778 case 15: event_name = "VisibilityNotify"; break;
1779 case 16: event_name = "CreateNotify"; break;
1780 case 17: event_name = "DestroyNotify"; break;
1781 case 18: event_name = "UnmapNotify"; break;
1782 case 19: event_name = "MapNotify"; break;
1783 case 20: event_name = "MapRequest"; break;
1784 case 21: event_name = "ReparentNotify"; break;
1785 case 22: event_name = "ConfigureNotify"; break;
1786 case 23: event_name = "ConfigureRequest"; break;
1787 case 24: event_name = "GravityNotify"; break;
1788 case 25: event_name = "ResizeRequest"; break;
1789 case 26: event_name = "CirculateNotify"; break;
1790 case 27: event_name = "CirculateRequest"; break;
1791 case 28: event_name = "PropertyNotify"; break;
1792 case 29: event_name = "SelectionClear"; break;
1793 case 30: event_name = "SelectionRequest"; break;
1794 case 31: event_name = "SelectionNotify"; break;
1795 case 32: event_name = "ColormapNotify"; break;
1796 case 33: event_name = "ClientMessage"; break;
1797 case 34: event_name = "MappingNotify"; break;
1798 default: event_name = "unknown";
1801 fprintf (stderr, "%s: %s\n", win_name, event_name);
1806 mwin__map_window (MFrame *frame, MDrawWindow win)
1808 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1812 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1814 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1818 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1819 MDrawMetric *geometry)
1821 Display *display = FRAME_DISPLAY (frame);
1822 XWindowAttributes attr;
1823 Window parent = (Window) parent_win, root;
1825 XGetWindowAttributes (display, (Window) win, &attr);
1826 geometry->x = attr.x + attr.border_width;
1827 geometry->y = attr.y + attr.border_width;
1828 geometry->width = attr.width;
1829 geometry->height = attr.height;
1832 parent = RootWindow (display, FRAME_SCREEN (frame));
1835 Window this_parent, *children;
1838 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1841 if (this_parent == parent || this_parent == root)
1843 win = (MDrawWindow) this_parent;
1844 XGetWindowAttributes (display, (Window) win, &attr);
1845 geometry->x += attr.x + attr.border_width;
1846 geometry->y += attr.y + attr.border_width;
1851 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1852 MDrawMetric *current, MDrawMetric *new)
1854 Display *display = FRAME_DISPLAY (frame);
1855 unsigned int mask = 0;
1856 XWindowChanges values;
1858 if (current->width != new->width)
1861 if (new->width <= 0)
1863 values.width = current->width = new->width;
1865 if (current->height != new->height)
1868 if (new->height <= 0)
1870 values.height = current->height = new->height;
1872 if (current->x != new->x)
1875 values.x = current->x = new->x;
1877 if (current->y != new->y)
1880 current->y = new->y;
1881 values.y = current->y = new->y;
1884 XConfigureWindow (display, (Window) win, mask, &values);
1885 XClearWindow (display, (Window) win);
1889 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1891 XEvent *event = (XEvent *) arg;
1892 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
1899 if (event->xany.type != KeyPress
1900 /* && event->xany.type != KeyRelease */
1903 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
1910 if (c < XK_space || c > XK_asciitilde)
1912 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
1913 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1914 if (((XKeyEvent *) event)->state & ControlMask)
1916 if (c >= 'a' && c <= 'z')
1918 if (c >= ' ' && c < 127)
1919 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1921 key = minput__char_to_key (c);
1923 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
1927 char *str = XKeysymToString (keysym);
1931 key = msymbol (str);
1932 if (((XKeyEvent *) event)->state & ShiftMask)
1933 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1934 if (((XKeyEvent *) event)->state & ControlMask)
1935 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1937 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
1938 *modifiers |= MINPUT_KEY_META_MODIFIER;
1939 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
1940 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
1941 if (((XKeyEvent *) event)->state & disp_info->super_mask)
1942 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
1943 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
1944 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
1951 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
1953 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
1955 Display *display = FRAME_DISPLAY (frame);
1956 GCInfo *info = rface->info;
1959 for (i = 0; i <= GC_INVERSE; i++)
1961 XGetGCValues (display, info->gc[i], valuemask, &values);
1962 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
1963 values.foreground, values.background);
1964 fprintf (stderr, "\n");
1968 static MDeviceDriver x_driver =
1971 mwin__device_get_prop,
1973 mwin__free_realized_face,
1975 mwin__draw_empty_boxes,
1979 mwin__region_from_rect,
1980 mwin__union_rect_with_region,
1981 mwin__intersect_region,
1982 mwin__region_add_rect,
1983 mwin__region_to_rect,
1986 mwin__create_window,
1987 mwin__destroy_window,
1990 mwin__window_geometry,
1991 mwin__adjust_window,
1995 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
2000 M_iso8859_1 = msymbol ("iso8859-1");
2001 M_iso10646_1 = msymbol ("iso10646-1");
2003 display_info_list = mplist ();
2004 device_list = mplist ();
2007 xft_driver.select = mfont__ft_driver.select;
2008 xft_driver.list = mfont__ft_driver.list;
2011 Mxim = msymbol ("xim");
2012 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
2020 M17N_OBJECT_UNREF (display_info_list);
2021 M17N_OBJECT_UNREF (device_list);
2026 #ifdef X_SET_ERROR_HANDLER
2028 x_error_handler (Display *display, XErrorEvent *error)
2035 x_io_error_handler (Display *display)
2042 /** Return an MWDevice object corresponding to a display specified in
2045 It searches device_list for a device matching the display. If
2046 found, return the found object. Otherwise, return a newly created
2050 device_open (MFrame *frame, MPlist *param)
2052 Display *display = NULL;
2053 Screen *screen = NULL;
2055 Drawable drawable = 0;
2056 Widget widget = NULL;
2058 int auto_display = 0;
2059 MDisplayInfo *disp_info = NULL;
2060 MWDevice *device = NULL;
2062 XWindowAttributes attr;
2068 int use_xfont = 0, use_freetype = 0, use_xft = 0;
2070 for (plist = param; (key = mplist_key (plist)) != Mnil;
2071 plist = mplist_next (plist))
2073 if (key == Mdisplay)
2074 display = (Display *) mplist_value (plist);
2075 else if (key == Mscreen)
2076 screen = mplist_value (plist);
2077 else if (key == Mdrawable)
2078 drawable = (Drawable) mplist_value (plist);
2079 else if (key == Mdepth)
2080 depth = (unsigned) mplist_value (plist);
2081 else if (key == Mwidget)
2082 widget = (Widget) mplist_value (plist);
2083 else if (key == Mcolormap)
2084 cmap = (Colormap) mplist_value (plist);
2085 else if (key == Mfont)
2087 MSymbol val = MPLIST_SYMBOL (plist);
2091 #ifdef HAVE_FREETYPE
2092 else if (val == Mfreetype)
2095 else if (val == Mxft)
2102 /* If none of them is specified, use all of them. */
2103 if (! use_xfont && ! use_freetype && ! use_xft)
2104 use_xfont = use_freetype = use_xft = 1;
2108 display = XtDisplay (widget);
2109 screen_num = XScreenNumberOfScreen (XtScreen (widget));
2110 depth = DefaultDepth (display, screen_num);
2116 unsigned width, height, border_width;
2119 MERROR (MERROR_WIN, -1);
2120 XGetGeometry (display, drawable, &root_window,
2121 &x, &y, &width, &height, &border_width, &depth);
2122 XGetWindowAttributes (display, root_window, &attr);
2123 screen_num = XScreenNumberOfScreen (attr.screen);
2128 display = DisplayOfScreen (screen);
2133 display = XOpenDisplay (NULL);
2135 MERROR (MERROR_WIN, -1);
2138 screen = DefaultScreenOfDisplay (display);
2140 screen_num = XScreenNumberOfScreen (screen);
2142 depth = DefaultDepth (display, screen_num);
2146 cmap = DefaultColormap (display, screen_num);
2148 for (plist = display_info_list; mplist_key (plist) != Mnil;
2149 plist = mplist_next (plist))
2151 disp_info = (MDisplayInfo *) mplist_value (plist);
2152 if (disp_info->display == display)
2156 if (mplist_key (plist) != Mnil)
2157 M17N_OBJECT_REF (disp_info);
2160 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2161 disp_info->display = display;
2162 disp_info->auto_display = auto_display;
2163 disp_info->font_list = mplist ();
2164 find_modifier_bits (disp_info);
2165 disp_info->MULE_BASELINE_OFFSET
2166 = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
2167 disp_info->AVERAGE_WIDTH
2168 = XInternAtom (display, "AVERAGE_WIDTH", False);
2169 mplist_add (display_info_list, Mt, disp_info);
2172 for (plist = device_list; mplist_key (plist) != Mnil;
2173 plist = mplist_next (plist))
2175 device = (MWDevice *) mplist_value (plist);
2176 if (device->display_info == disp_info
2177 && device->depth == depth
2178 && device->cmap == cmap
2179 && device->screen_num == screen_num)
2183 if (mplist_key (plist) != Mnil)
2184 M17N_OBJECT_REF (device);
2187 unsigned long valuemask = GCForeground;
2191 M17N_OBJECT (device, free_device, MERROR_WIN);
2192 device->display_info = disp_info;
2193 device->screen_num = screen_num;
2194 /* A drawable on which to create GCs. */
2195 device->drawable = XCreatePixmap (display,
2196 RootWindow (display, screen_num),
2198 device->depth = depth;
2199 device->cmap = cmap;
2200 pixels = DisplayHeight (display, screen_num);
2201 mm = DisplayHeightMM (display, screen_num);
2202 device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
2203 device->realized_face_list = mplist ();
2204 device->realized_font_list = mplist ();
2205 mplist_add (device->realized_font_list, Mt, NULL);
2206 device->realized_fontset_list = mplist ();
2207 device->gc_list = mplist ();
2208 values.foreground = BlackPixel (display, screen_num);
2209 device->scratch_gc = XCreateGC (display, device->drawable,
2210 valuemask, &values);
2212 device->xft_draw = XftDrawCreate (display, device->drawable,
2213 DefaultVisual (display, screen_num),
2218 frame->device = device;
2219 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2220 frame->dpi = device->resy;
2221 frame->driver = &x_driver;
2222 frame->font_driver_list = mplist ();
2226 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2229 #endif /* HAVE_XFT2 */
2230 #ifdef HAVE_FREETYPE
2232 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2233 #endif /* HAVE_FREETYPE */
2234 if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
2235 mplist_push (frame->font_driver_list, Mx, &xfont_driver);
2237 frame->realized_font_list = device->realized_font_list;
2238 frame->realized_face_list = device->realized_face_list;
2239 frame->realized_fontset_list = device->realized_fontset_list;
2243 XtResource resources[] = {
2244 { XtNfont, XtCFont, XtRString, sizeof (String),
2245 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2246 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2247 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2248 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2249 XtOffset (AppDataPtr, background), XtRString, "white" },
2250 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2251 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2254 XtGetApplicationResources (widget, &app_data,
2255 resources, XtNumber (resources), NULL, 0);
2256 frame->foreground = msymbol (app_data.foreground);
2257 frame->background = msymbol (app_data.background);
2258 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2262 app_data.font = DEFAULT_FONT;
2263 frame->foreground = msymbol ("black");
2264 frame->background = msymbol ("white");
2265 frame->videomode = Mnormal;
2268 if (strcmp (app_data.font, DEFAULT_FONT) != 0)
2270 XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
2271 unsigned long value;
2276 font = mfont_parse_name (app_data.font, Mx);
2278 && XGetFontProperty (xfont, XA_FONT, &value)
2279 && (name = ((char *) XGetAtomName (display, (Atom) value))))
2280 font = mfont_parse_name (name, Mx);
2281 XFreeFont (display, xfont);
2285 font = mfont_parse_name (DEFAULT_FONT, Mx);
2286 else if (! font->size)
2288 face = mface_from_font (font);
2290 face->property[MFACE_FONTSET] = mfontset (NULL);
2291 face->property[MFACE_FOREGROUND] = frame->foreground;
2292 face->property[MFACE_BACKGROUND] = frame->background;
2293 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2294 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2295 face->property[MFACE_VIDEOMODE] = frame->videomode;
2296 mface_put_prop (face, Mhook_func,
2297 mface_get_prop (mface__default, Mhook_func));
2298 face->property[MFACE_RATIO] = (void *) 100;
2299 mplist_push (param, Mface, face);
2300 M17N_OBJECT_UNREF (face);
2302 #ifdef X_SET_ERROR_HANDLER
2303 XSetErrorHandler (x_error_handler);
2304 XSetIOErrorHandler (x_io_error_handler);
2311 /* XIM (X Input Method) handler */
2313 typedef struct MInputXIMMethodInfo
2319 } MInputXIMMethodInfo;
2321 typedef struct MInputXIMContextInfo
2325 MConverter *converter;
2326 } MInputXIMContextInfo;
2329 xim_open_im (MInputMethod *im)
2331 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
2332 MLocale *saved, *this;
2333 char *save_modifier_list;
2335 MInputXIMMethodInfo *im_info;
2337 saved = mlocale_set (LC_CTYPE, NULL);
2338 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
2340 /* The specified locale is not supported. */
2341 MERROR (MERROR_LOCALE, -1);
2342 if (mlocale_get_prop (this, Mcoding) == Mnil)
2344 /* Unable to decode the output of XIM. */
2345 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2346 MERROR (MERROR_LOCALE, -1);
2349 if (arg->modifier_list)
2350 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
2352 save_modifier_list = XSetLocaleModifiers ("");
2353 if (! save_modifier_list)
2355 /* The specified locale is not supported by X. */
2356 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2357 MERROR (MERROR_LOCALE, -1);
2360 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
2363 /* No input method is available in the current locale. */
2364 XSetLocaleModifiers (save_modifier_list);
2365 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2366 MERROR (MERROR_WIN, -1);
2369 MSTRUCT_MALLOC (im_info, MERROR_WIN);
2370 im_info->display = arg->display;
2372 im_info->language = mlocale_get_prop (this, Mlanguage);
2373 im_info->coding = mlocale_get_prop (this, Mcoding);
2376 XSetLocaleModifiers (save_modifier_list);
2377 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2383 xim_close_im (MInputMethod *im)
2385 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
2387 XCloseIM (im_info->xim);
2392 xim_create_ic (MInputContext *ic)
2394 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
2395 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2396 MInputXIMContextInfo *ic_info;
2399 if (! arg->input_style)
2401 /* By default, use Root style. */
2402 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
2403 arg->preedit_attrs = NULL;
2404 arg->status_attrs = NULL;
2407 if (! arg->preedit_attrs && ! arg->status_attrs)
2408 xic = XCreateIC (im_info->xim,
2409 XNInputStyle, arg->input_style,
2410 XNClientWindow, arg->client_win,
2411 XNFocusWindow, arg->focus_win,
2413 else if (arg->preedit_attrs && ! arg->status_attrs)
2414 xic = XCreateIC (im_info->xim,
2415 XNInputStyle, arg->input_style,
2416 XNClientWindow, arg->client_win,
2417 XNFocusWindow, arg->focus_win,
2418 XNPreeditAttributes, arg->preedit_attrs,
2420 else if (! arg->preedit_attrs && arg->status_attrs)
2421 xic = XCreateIC (im_info->xim,
2422 XNInputStyle, arg->input_style,
2423 XNClientWindow, arg->client_win,
2424 XNFocusWindow, arg->focus_win,
2425 XNStatusAttributes, arg->status_attrs,
2428 xic = XCreateIC (im_info->xim,
2429 XNInputStyle, arg->input_style,
2430 XNClientWindow, arg->client_win,
2431 XNFocusWindow, arg->focus_win,
2432 XNPreeditAttributes, arg->preedit_attrs,
2433 XNStatusAttributes, arg->status_attrs,
2436 MERROR (MERROR_WIN, -1);
2438 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
2440 ic_info->win = arg->focus_win;
2441 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
2447 xim_destroy_ic (MInputContext *ic)
2449 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2451 XDestroyIC (ic_info->xic);
2452 mconv_free_converter (ic_info->converter);
2458 xim_filter (MInputContext *ic, MSymbol key, void *event)
2460 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2462 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
2467 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2469 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2470 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2471 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
2477 buf = (char *) alloca (512);
2478 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
2479 if (status == XBufferOverflow)
2481 buf = (char *) alloca (len);
2482 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
2485 mtext_reset (ic->produced);
2489 mconv_reset_converter (ic_info->converter);
2490 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
2491 mconv_decode (ic_info->converter, ic->produced);
2492 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2493 Mlanguage, (void *) im_info->language);
2494 mtext_cpy (mt, ic->produced);
2495 mtext_reset (ic->produced);
2503 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2507 /*** @addtogroup m17nInputMethodWin */
2512 @brief Input method driver for XIM.
2514 The driver #minput_xim_driver is for the foreign input method of
2515 name #Mxim. It uses XIM (X Input Methods) as a background input
2518 As the symbol #Mxim has property #Minput_driver whose value is
2519 a pointer to this driver, the input method of language #Mnil
2520 and name #Mxim uses this driver.
2522 Therefore, for such input methods, the driver dependent arguments
2523 to the functions whose name begin with minput_ must be as follows.
2525 The argument $ARG of the function minput_open_im () must be a
2526 pointer to the structure #MInputXIMArgIM. See the documentation
2527 of #MInputXIMArgIM for more details.
2529 The argument $ARG of the function minput_create_ic () must be a
2530 pointer to the structure #MInputXIMArgIC. See the documentation
2531 of #MInputXIMArgIC for more details.
2533 The argument $ARG of the function minput_filter () must be a
2534 pointer to the structure @c XEvent. The argument $KEY is ignored.
2536 The argument $ARG of the function minput_lookup () must be the
2537 same one as that of the function minput_filter (). The argument
2541 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2543 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
2544 XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2546 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2547 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
2548 ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2550 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
2551 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2553 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
2554 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
2556 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
2557 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
2559 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
2560 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2562 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2563 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
2565 MInputDriver minput_xim_driver =
2566 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2567 xim_filter, xim_lookup, NULL };
2571 #else /* not HAVE_X11 */
2573 int device_open () { return -1; }
2575 #endif /* not HAVE_X11 */