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., 51 Franklin Street, Fifth Floor,
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"
64 /* Common header for the m17n object. */
69 /* If nonzero, <display> is opened by this library. Thus it should
70 be closed on freeing this structure. */
73 /** List of available X-core fonts on the display. Keys are
74 registries and values are plists whose keys are families and
75 values are pointers to MFont. */
78 /** Nonzero means that <font_list> already contains all available
79 fonts on the display. */
82 /** Modifier bit masks of the display. */
88 Atom MULE_BASELINE_OFFSET;
92 /* Anchor of the chain of MDisplayInfo objects. */
93 static MPlist *display_info_list;
96 /* Color value and the corresponding GC. */
99 unsigned int rgb; /* (red << 16) | (green << 8) | blue */
106 GC_NORMAL = GC_INVERSE + 7,
119 /* The first 8 elements are indexed by an intensity for
120 anti-aliasing. The 2nd to 7th are created on demand. */
123 XftColor xft_color_fore, xft_color_back;
129 /* Common header for the m17n object. */
132 MDisplayInfo *display_info;
150 /** List of pointers to realized faces on the frame. */
151 MPlist *realized_face_list;
153 /* List of single element whose value is a root of chain of realized
155 MPlist *realized_font_list;
157 /** List of pointers to realized fontsets on the frame. */
158 MPlist *realized_fontset_list;
160 /** List of XColors vs GCs on the frame. */
164 static MPlist *device_list;
166 static MSymbol M_iso8859_1, M_iso10646_1;
168 #define FRAME_DEVICE(frame) ((MWDevice *) (frame)->device)
169 #define FRAME_DISPLAY(frame) (FRAME_DEVICE (frame)->display_info->display)
170 #define FRAME_SCREEN(frame) (FRAME_DEVICE (frame)->screen_num)
171 #define FRAME_CMAP(frame) (FRAME_DEVICE (frame)->cmap)
172 #define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
173 FRAME_SCREEN (frame))
175 #define DEFAULT_FONT "-*-*-medium-r-normal--13-*-*-*-c-*-iso8859-1"
182 Boolean reverse_video;
183 } AppData, *AppDataPtr;
186 free_display_info (void *object)
188 MDisplayInfo *disp_info = (MDisplayInfo *) object;
191 MPLIST_DO (plist, disp_info->font_list)
193 MPLIST_DO (pl, MPLIST_VAL (plist))
194 free (MPLIST_VAL (pl));
195 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
197 M17N_OBJECT_UNREF (disp_info->font_list);
199 if (disp_info->auto_display)
200 XCloseDisplay (disp_info->display);
206 free_device (void *object)
208 MWDevice *device = object;
211 for (plist = device->realized_fontset_list;
212 mplist_key (plist) != Mnil; plist = mplist_next (plist))
213 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
214 M17N_OBJECT_UNREF (device->realized_fontset_list);
216 if (MPLIST_VAL (device->realized_font_list))
217 mfont__free_realized (MPLIST_VAL (device->realized_font_list));
218 M17N_OBJECT_UNREF (device->realized_font_list);
220 MPLIST_DO (plist, device->realized_face_list)
222 MRealizedFace *rface = MPLIST_VAL (plist);
225 mface__free_realized (rface);
227 M17N_OBJECT_UNREF (device->realized_face_list);
229 MPLIST_DO (plist, device->gc_list)
231 XFreeGC (device->display_info->display,
232 ((RGB_GC *) MPLIST_VAL (plist))->gc);
233 free (MPLIST_VAL (plist));
235 M17N_OBJECT_UNREF (device->gc_list);
236 XFreeGC (device->display_info->display, device->scratch_gc);
239 XftDrawDestroy (device->xft_draw);
242 XFreePixmap (device->display_info->display, device->drawable);
243 M17N_OBJECT_UNREF (device->display_info);
249 find_modifier_bits (MDisplayInfo *disp_info)
251 Display *display = disp_info->display;
252 XModifierKeymap *mods;
253 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
254 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
255 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
256 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
257 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
258 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
259 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
260 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
263 mods = XGetModifierMapping (display);
264 /* We skip the first three sets for Shift, Lock, and Control. The
265 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
266 for (i = 3; i < 8; i++)
267 for (j = 0; j < mods->max_keypermod; j++)
269 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
273 if (code == meta_l || code == meta_r)
274 disp_info->meta_mask |= (1 << i);
275 else if (code == alt_l || code == alt_r)
276 disp_info->alt_mask |= (1 << i);
277 else if (code == super_l || code == super_r)
278 disp_info->super_mask |= (1 << i);
279 else if (code == hyper_l || code == hyper_r)
280 disp_info->hyper_mask |= (1 << i);
283 /* If meta keys are not in any modifier, use alt keys as meta
285 if (! disp_info->meta_mask)
287 disp_info->meta_mask = disp_info->alt_mask;
288 disp_info->alt_mask = 0;
290 /* If both meta and alt are assigned to the same modifier, give meta
292 if (disp_info->meta_mask & disp_info->alt_mask)
293 disp_info->alt_mask &= ~disp_info->meta_mask;
295 XFreeModifiermap (mods);
299 get_rgb_gc (MWDevice *device, XColor *xcolor)
301 int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
302 | (xcolor->blue >> 8));
305 unsigned long valuemask = GCForeground;
308 MPLIST_DO (plist, device->gc_list)
310 rgb_gc = MPLIST_VAL (plist);
312 if (rgb_gc->rgb == rgb)
314 if (rgb_gc->rgb > rgb)
318 if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
321 rgb_gc = malloc (sizeof (RGB_GC));
323 values.foreground = xcolor->pixel;
324 rgb_gc->gc = XCreateGC (device->display_info->display,
325 device->drawable, valuemask, &values);
326 mplist_push (plist, Mt, rgb_gc);
331 get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
333 MWDevice *device = FRAME_DEVICE (frame);
341 color = for_foreground ? frame->foreground : frame->background;
343 if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
344 msymbol_name (color), &xcolor))
346 rgb_gc = get_rgb_gc (device, &xcolor);
350 *rgb_ret = rgb_gc->rgb;
355 GCInfo *info = frame->rface->info;
360 rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
362 rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
370 get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
372 int rgb_fore, rgb_back;
377 if (info->gc[intensity])
378 return info->gc[intensity];
380 rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
381 xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
382 + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
383 xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
384 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
385 xcolor.blue = (((rgb_fore & 0xFF) * intensity
386 + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
387 rgb_gc = get_rgb_gc (device, &xcolor);
391 gc =get_gc_for_anti_alias (device, info,
392 intensity < 4 ? intensity - 1 : intensity + 1);
393 return (info->gc[intensity] = gc);
397 set_region (MFrame *frame, GC gc, MDrawRegion region)
399 unsigned long valuemask = GCForeground;
401 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
402 FRAME_DEVICE (frame)->scratch_gc);
403 XSetRegion (FRAME_DISPLAY (frame), FRAME_DEVICE (frame)->scratch_gc, region);
404 return FRAME_DEVICE (frame)->scratch_gc;
408 /** X font handler */
410 static MFont *xfont_select (MFrame *, MFont *, int);
411 static MRealizedFont *xfont_open (MFrame *, MFont *, MFont *, MRealizedFont *);
412 static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
413 static int xfont_has_char (MFrame *, MFont *, MFont *, int, unsigned);
414 static unsigned xfont_encode_char (MFrame *, MFont *, MFont *, unsigned);
415 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
416 MGlyph *, MGlyph *, int, MDrawRegion);
417 static int xfont_list (MFrame *, MPlist *, MFont *, int);
418 static void xfont_list_family_names (MFrame *, MPlist *);
419 static int xfont_check_capability (MRealizedFont *rfont, MSymbol capability);
421 static MFontDriver xfont_driver =
422 { xfont_select, xfont_open,
423 xfont_find_metric, xfont_has_char, xfont_encode_char,
424 xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability };
427 font_compare (const void *p1, const void *p2)
429 return strcmp (*(char **) p1, *(char **) p2);
433 xfont_registry_list (MFrame *frame, MSymbol registry)
435 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
436 MPlist *font_list = disp_info->font_list;
439 char **font_names, **names;
445 plist = mplist_get (font_list, registry);
448 p = plist = mplist ();
449 mplist_add (font_list, registry, plist);
450 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", msymbol_name (registry));
451 font_names = XListFonts (disp_info->display, pattern, 0x8000, &nfonts);
455 char *reg_name = msymbol_name (registry);
457 for_full_width = (strncmp (reg_name, "jis", 3) == 0
458 || strncmp (reg_name, "gb", 2) == 0
459 || strncmp (reg_name, "big5", 4) == 0
460 || strncmp (reg_name, "ksc", 3) == 0);
462 names = alloca (sizeof (char *) * nfonts);
463 memcpy (names, font_names, sizeof (char *) * nfonts);
464 qsort (names, nfonts, sizeof (char *), font_compare);
466 for (i = 0; i < nfonts; i++)
467 if (mfont__parse_name_into_font (names[i], Mx, &font) == 0
468 && (font.size > 0 || font.property[MFONT_RESY] == 0))
470 MSymbol family = FONT_PROPERTY (&font, MFONT_FAMILY);
475 int size, normal_size;
480 /* Calculate how many bytes to compare to detect fonts of the
482 for (base_end = names[i], fields = 0; *base_end; base_end++)
484 && ++fields == 7 /* PIXEL_SIZE */)
486 base_len = base_end - names[i] + 1;
488 size = font.size / 10;
489 sizes[nsizes++] = size;
490 normal_size = (size >= 6 && size <= 29);
491 limit = (i + 256 < nfonts ? i + 256 : nfonts);
492 for (j = i + 1; j < limit && ! memcmp (names[i], names[j], base_len);
494 if (mfont__parse_name_into_font (names[j], Mx, &font) == 0
495 && (font.size > 0 || font.property[MFONT_RESY] == 0))
497 size = font.size / 10;
498 sizes[nsizes++] = size;
499 normal_size |= (size >= 6 && size <= 29);
502 font.for_full_width = for_full_width;
503 font.type = MFONT_TYPE_OBJECT;
504 font.source = MFONT_SOURCE_X;
507 MSTRUCT_CALLOC (fontx, MERROR_WIN);
509 fontx->multiple_sizes = 1;
511 for (j = 0; j < nsizes; j++)
512 if (sizes[j] >= 6 && sizes[j] <= 29)
513 fontx->size |= 1 << (sizes[j] - 6);
514 p = mplist_add (p, family, fontx);
516 for (j = 0; j < nsizes; j++)
517 if (sizes[j] < 6 || sizes[j] > 29)
519 MSTRUCT_CALLOC (fontx, MERROR_WIN);
521 fontx->multiple_sizes = 0;
522 fontx->size = sizes[j] * 10;
524 fontx->property[MFONT_RESY] = 0;
525 p = mplist_add (p, family, fontx);
528 XFreeFontNames (font_names);
533 xfont_list_all (MFrame *frame)
535 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
536 MPlist *font_encoding_list, *p;
538 if (disp_info->all_fonts_scaned)
540 disp_info->all_fonts_scaned = 1;
541 font_encoding_list = mfont__encoding_list ();
542 if (! font_encoding_list)
544 MPLIST_DO (p, font_encoding_list)
545 xfont_registry_list (frame, MPLIST_KEY (p));
555 /* The X font driver function SELECT. */
558 xfont_select (MFrame *frame, MFont *font, int limited_size)
560 MPlist *plist = mplist (), *pl;
561 int num = xfont_list (frame, plist, font, 0);
565 MPLIST_DO (pl, plist)
567 font = MPLIST_VAL (pl);
568 if (limited_size == 0
570 || font->size <= limited_size)
576 M17N_OBJECT_UNREF (plist);
580 /* The X font driver function CLOSE. */
583 close_xfont (void *object)
585 MRealizedFontX *x_rfont = object;
587 XFreeFont (x_rfont->display, x_rfont->xfont);
591 /* The X font driver function OPEN. */
593 static MRealizedFont *
594 xfont_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
597 MRealizedFontX *x_rfont;
599 Display *display = FRAME_DISPLAY (frame);
601 int mdebug_mask = MDEBUG_FONT;
607 int ratio = mfont_resize_ratio (font);
610 size = size * ratio / 100;
617 /* non-scalable font */
618 if (font->multiple_sizes)
626 for (i = size / 10 - 6; i >= 0; i--)
627 if (font->size & (1 << i))
630 for (i = size / 10 - 5; i < 24; i++)
631 if (font->size & (1 << i))
641 for (; rfont; rfont = rfont->next)
642 if (rfont->font == font && rfont->spec.size == size)
647 this.multiple_sizes = 0;
649 /* This never fail to generate a valid fontname. */
650 name = mfont_unparse_name (&this, Mx);
651 xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
654 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
656 font->type = MFONT_TYPE_FAILURE;
659 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
661 M17N_OBJECT (x_rfont, close_xfont, MERROR_FONT_X);
662 x_rfont->display = display;
663 x_rfont->xfont = xfont;
664 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
666 rfont->spec.type = MFONT_TYPE_REALIZED;
667 rfont->spec.source = MFONT_SOURCE_X;
668 rfont->frame = frame;
670 rfont->driver = &xfont_driver;
671 rfont->info = x_rfont;
673 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
676 rfont->baseline_offset
677 = (XGetFontProperty (xfont, disp_info->MULE_BASELINE_OFFSET, &value)
680 = (XGetFontProperty (xfont, disp_info->AVERAGE_WIDTH, &value)
681 ? (int) value / 10 : 0);
683 rfont->ascent = xfont->ascent + rfont->baseline_offset;
684 rfont->descent = xfont->descent - rfont->baseline_offset;
685 rfont->max_advance = xfont->max_bounds.width;
686 rfont->fontp = xfont;
687 rfont->next = MPLIST_VAL (frame->realized_font_list);
688 MPLIST_VAL (frame->realized_font_list) = rfont;
693 /* The X font driver function FIND_METRIC. */
696 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
699 XFontStruct *xfont = rfont->fontp;
700 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
702 for (; g != gend; g++)
704 if (g->code == MCHAR_INVALID_CODE)
706 g->lbearing = xfont->max_bounds.lbearing;
707 g->rbearing = xfont->max_bounds.rbearing;
708 g->width = xfont->max_bounds.width;
709 g->ascent = xfont->ascent;
710 g->descent = xfont->descent;
714 int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
715 XCharStruct *pcm = NULL;
717 if (xfont->per_char != NULL)
719 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
722 && byte2 >= xfont->min_char_or_byte2
723 && byte2 <= xfont->max_char_or_byte2)
724 pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
728 if (byte1 >= xfont->min_byte1
729 && byte1 <= xfont->max_byte1
730 && byte2 >= xfont->min_char_or_byte2
731 && byte2 <= xfont->max_char_or_byte2)
733 pcm = (xfont->per_char
734 + ((xfont->max_char_or_byte2
735 - xfont->min_char_or_byte2 + 1)
736 * (byte1 - xfont->min_byte1))
737 + (byte2 - xfont->min_char_or_byte2));
744 g->lbearing = pcm->lbearing;
745 g->rbearing = pcm->rbearing;
746 g->width = pcm->width;
747 g->ascent = pcm->ascent;
748 g->descent = pcm->descent;
752 /* If the per_char pointer is null, all glyphs between
753 the first and last character indexes inclusive have
754 the same information, as given by both min_bounds and
757 g->rbearing = xfont->max_bounds.width;
758 g->width = xfont->max_bounds.width;
759 g->ascent = xfont->ascent;
760 g->descent = xfont->descent;
763 g->ascent += rfont->baseline_offset;
764 g->descent -= rfont->baseline_offset;
770 xfont_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
772 return (xfont_encode_char (frame, font, spec, code) != MCHAR_INVALID_CODE);
775 /* The X font driver function GET_GLYPH_ID. */
778 xfont_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
780 MRealizedFont *rfont;
782 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
785 if (font->type == MFONT_TYPE_REALIZED)
786 rfont = (MRealizedFont *) font;
787 else if (font->type == MFONT_TYPE_OBJECT)
789 for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
791 if (rfont->font == font)
795 rfont = xfont_open (frame, font, spec, NULL);
797 return MCHAR_INVALID_CODE;
801 MFATAL (MERROR_FONT_X);
802 xfont = rfont->fontp;
803 all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True);
804 min_byte1 = xfont->min_byte1;
805 max_byte1 = xfont->max_byte1;
806 min_byte2 = xfont->min_char_or_byte2;
807 max_byte2 = xfont->max_char_or_byte2;
809 if (min_byte1 == 0 && max_byte1 == 0)
813 if (code < min_byte2 || code > max_byte2)
814 return MCHAR_INVALID_CODE;
817 pcm = xfont->per_char + (code - min_byte2);
818 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
819 ? code : MCHAR_INVALID_CODE);
823 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
826 if (byte1 < min_byte1 || byte1 > max_byte1
827 || byte2 < min_byte2 || byte2 > max_byte2)
828 return MCHAR_INVALID_CODE;
832 pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
833 + (byte2 - min_byte2));
834 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
835 ? code : MCHAR_INVALID_CODE);
839 /* The X font driver function RENDER. */
842 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
843 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
845 MRealizedFace *rface = from->rface;
846 Display *display = FRAME_DISPLAY (rface->frame);
848 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
856 baseline_offset = rface->rfont->baseline_offset;
858 gc = set_region (rface->frame, gc, region);
859 XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
860 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
861 for (i = 0, g = from; g < to; i++, g++)
863 code[i].byte1 = g->code >> 8;
864 code[i].byte2 = g->code & 0xFF;
870 if (g->type == GLYPH_PAD)
872 else if (g->type == GLYPH_SPACE)
873 for (; g < to && g->type == GLYPH_SPACE; g++)
875 else if (! g->rface->rfont)
877 if ((g->c >= 0x200B && g->c <= 0x200F)
878 || (g->c >= 0x202A && g->c <= 0x202E))
882 /* As a font is not found for this character, draw an
884 int box_width = g->width;
885 int box_height = gstring->ascent + gstring->descent;
891 XDrawRectangle (display, (Window) win, gc,
892 x, y - gstring->ascent, box_width, box_height);
896 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
898 XDrawString16 (display, (Window) win, gc,
899 x + g->xoff, y + g->yoff - baseline_offset,
900 code + (g - from), 1);
907 int code_idx = g - from;
910 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
913 XDrawString16 (display, (Window) win, gc,
914 orig_x, y - baseline_offset, code + code_idx, i);
920 xfont_list (MFrame *frame, MPlist *plist, MFont *font, int maxnum)
922 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
923 MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil;
924 MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil;
925 int size = font ? font->size : 0;
928 int mdebug_mask = MDEBUG_FONT;
930 MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
931 family ? msymbol_name (family) : "*",
932 registry ? msymbol_name (registry) : "*");
934 if (registry == Mnil)
935 xfont_list_all (frame);
937 xfont_registry_list (frame, registry);
939 MPLIST_DO (pl, disp_info->font_list)
940 if (registry == Mnil || registry == MPLIST_KEY (pl))
942 MPLIST_DO (p, MPLIST_VAL (pl))
943 if (family == Mnil || family == MPLIST_KEY (p))
945 MFont *fontx = MPLIST_VAL (p);
947 if (! font || (mfont__match_p (fontx, font, MFONT_REGISTRY)))
949 if (fontx->size != 0 && size)
951 if (fontx->multiple_sizes)
953 if (size < 60 || size > 290
954 || ! (fontx->size & (1 << (size / 10 - 6))))
957 else if (fontx->size != size)
960 mplist_push (plist, MPLIST_KEY (p), fontx);
962 if (maxnum > 0 && maxnum == num)
969 MDEBUG_PRINT1 (" %d found\n", num);
974 xfont_list_family_names (MFrame *frame, MPlist *plist)
976 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
979 MSymbol last_family = Mnil;
981 font_names = XListFonts (disp_info->display,
982 "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", 0x8000, &nfonts);
983 for (i = 0; i < nfonts; i++)
986 char foundry[256], fam[256];
989 if (sscanf (font_names[i], "-%s-%s-", foundry, fam) < 2)
991 family = msymbol (fam);
992 if (family == last_family)
994 last_family = family;
998 MSymbol sym = MPLIST_SYMBOL (p);
1002 if (strcmp (MSYMBOL_NAME (sym), fam) > 0)
1004 mplist_push (p, Msymbol, family);
1008 if (MPLIST_TAIL_P (p))
1009 mplist_push (p, Msymbol, family);
1012 XFreeFontNames (font_names);
1016 xfont_check_capability (MRealizedFont *rfont, MSymbol capability)
1018 /* Currently X font driver doesn't support any capability. */
1030 FT_Face ft_face; /* This must be the 2nd member. */
1033 XftFont *font_no_aa;
1034 /* Pointer to MRealizedFontFT */
1038 static MRealizedFont *xft_open (MFrame *frame, MFont *font, MFont *spec,
1040 static int xft_has_char (MFrame *frame, MFont *font, MFont *spec,
1041 int c, unsigned code);
1042 static unsigned xft_encode_char (MFrame *frame, MFont *font, MFont *spec,
1044 static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
1045 static void xft_render (MDrawWindow, int, int, MGlyphString *,
1046 MGlyph *, MGlyph *, int, MDrawRegion);
1047 static int xft_check_capability (MRealizedFont *rfont, MSymbol capability);
1049 static MFontDriver xft_driver =
1051 xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL, NULL,
1052 xft_check_capability
1056 close_xft (void *object)
1058 MRealizedFontXft *rfont_xft = object;
1060 if (rfont_xft->font_aa)
1061 XftFontClose (rfont_xft->display, rfont_xft->font_aa);
1062 if (rfont_xft->font_no_aa)
1063 XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
1064 M17N_OBJECT_UNREF (rfont_xft->info);
1070 xft_open_font (Display *display, MSymbol file, double size,
1076 pattern = FcPatternCreate ();
1077 FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
1078 FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
1079 FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
1080 font = XftFontOpenPattern (display, pattern);
1085 static MRealizedFont *
1086 xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
1088 Display *display = FRAME_DISPLAY (frame);
1089 int reg = spec->property[MFONT_REGISTRY];
1091 MRealizedFontXft *rfont_xft;
1092 FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
1095 int ascent, descent, max_advance, average_width, baseline_offset;
1098 /* non-scalable font */
1100 else if (spec->size)
1102 int ratio = mfont_resize_ratio (font);
1104 size = ratio == 100 ? spec->size : spec->size * ratio / 100;
1111 MRealizedFont *save = NULL;
1113 for (; rfont; rfont = rfont->next)
1114 if (rfont->font == font
1115 && (rfont->font->size ? rfont->font->size == size
1116 : rfont->spec.size == size)
1117 && rfont->spec.property[MFONT_REGISTRY] == reg)
1121 if (rfont->driver == &xft_driver)
1126 rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
1129 ascent = rfont->ascent;
1130 descent = rfont->descent;
1131 max_advance = rfont->max_advance;
1132 average_width = rfont->average_width;
1133 baseline_offset = rfont->baseline_offset;
1134 spec = &rfont->spec;
1135 ft_face = rfont->fontp;
1136 xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
1139 M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
1140 rfont_xft->display = display;
1141 if (anti_alias == FcTrue)
1142 rfont_xft->font_aa = xft_font;
1144 rfont_xft->font_no_aa = xft_font;
1145 rfont_xft->ft_face = ft_face;
1146 rfont_xft->info = rfont->info;
1147 M17N_OBJECT_REF (rfont->info);
1148 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
1149 rfont->spec = *spec;
1150 rfont->spec.size = size;
1151 rfont->frame = frame;
1153 rfont->driver = &xft_driver;
1154 rfont->info = rfont_xft;
1155 rfont->ascent = ascent;
1156 rfont->descent = descent;
1157 rfont->max_advance = max_advance;
1158 rfont->average_width = average_width;
1159 rfont->baseline_offset = baseline_offset;
1160 rfont->fontp = xft_font;
1161 rfont->next = MPLIST_VAL (frame->realized_font_list);
1162 MPLIST_VAL (frame->realized_font_list) = rfont;
1167 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1170 Display *display = FRAME_DISPLAY (rfont->frame);
1171 XftFont *xft_font = rfont->fontp;
1172 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1174 for (; g != gend; g++)
1176 if (g->code == MCHAR_INVALID_CODE)
1179 g->rbearing = xft_font->max_advance_width;
1180 g->width = g->rbearing;
1181 g->ascent = xft_font->ascent;
1182 g->descent = xft_font->descent;
1188 XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
1189 g->lbearing = - extents.x;
1190 g->rbearing = extents.width - extents.x;
1191 g->width = extents.xOff;
1192 g->ascent = extents.y;
1193 g->descent = extents.height - extents.y;
1199 xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
1203 if (font->type == MFONT_TYPE_REALIZED)
1205 MRealizedFont *rfont = (MRealizedFont *) font;
1206 MRealizedFontXft *rfont_xft = rfont->info;
1208 rfont->info = rfont_xft->info;
1209 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1210 rfont->info = rfont_xft;
1213 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1218 xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
1220 if (font->type == MFONT_TYPE_REALIZED)
1222 MRealizedFont *rfont = (MRealizedFont *) font;
1223 MRealizedFontXft *rfont_xft = rfont->info;
1225 rfont->info = rfont_xft->info;
1226 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1227 rfont->info = rfont_xft;
1230 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1235 xft_render (MDrawWindow win, int x, int y,
1236 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1237 int reverse, MDrawRegion region)
1239 MRealizedFace *rface = from->rface;
1240 MFrame *frame = rface->frame;
1241 Display *display = FRAME_DISPLAY (frame);
1242 MRealizedFont *rfont = rface->rfont;
1243 MRealizedFontXft *rfont_xft = rfont->info;
1244 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1245 XftColor *xft_color = (! reverse
1246 ? &((GCInfo *) rface->info)->xft_color_fore
1247 : &((GCInfo *) rface->info)->xft_color_back);
1248 int anti_alias = (gstring->control.anti_alias
1249 && FRAME_DEVICE (frame)->depth > 1);
1261 if (rfont_xft->font_aa)
1262 xft_font = rfont_xft->font_aa;
1265 double size = rfont->spec.size;
1267 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1270 rfont_xft->font_aa = xft_font;
1272 xft_font = rfont->fontp;
1277 if (rfont_xft->font_no_aa)
1278 xft_font = rfont_xft->font_no_aa;
1281 double size = rfont->spec.size;
1283 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1286 rfont_xft->font_no_aa = xft_font;
1288 xft_font = rfont->fontp;
1292 XftDrawChange (xft_draw, (Drawable) win);
1293 XftDrawSetClip (xft_draw, (Region) region);
1295 y -= rfont->baseline_offset;
1296 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1297 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
1299 if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
1300 glyphs[nglyphs++] = g->code;
1304 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1305 last_x, y, glyphs, nglyphs);
1307 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1308 x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
1309 last_x = x + g->width;
1313 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1317 xft_check_capability (MRealizedFont *rfont, MSymbol capability)
1319 MRealizedFontXft *rfont_xft = rfont->info;
1322 rfont->info = rfont_xft->info;
1323 result = mfont__ft_driver.check_capability (rfont, capability);
1324 rfont->info = rfont_xft;
1328 #endif /* HAVE_XFT2 */
1331 /* Functions for the device driver. */
1334 mwin__close_device (MFrame *frame)
1336 MWDevice *device = FRAME_DEVICE (frame);
1338 M17N_OBJECT_UNREF (device);
1342 mwin__device_get_prop (MFrame *frame, MSymbol key)
1344 MWDevice *device = FRAME_DEVICE (frame);
1346 if (key == Mdisplay)
1347 return (void *) device->display_info->display;
1349 return (void *) ScreenOfDisplay(device->display_info->display,
1350 device->screen_num);
1351 if (key == Mcolormap)
1352 return (void *) device->cmap;
1354 return (void *) device->depth;
1359 mwin__realize_face (MRealizedFace *rface)
1362 MSymbol foreground, background, videomode;
1363 MFaceHLineProp *hline;
1367 if (rface != rface->ascii_rface)
1369 rface->info = rface->ascii_rface->info;
1373 frame = rface->frame;
1374 MSTRUCT_CALLOC (info, MERROR_WIN);
1376 foreground = rface->face.property[MFACE_FOREGROUND];
1377 background = rface->face.property[MFACE_BACKGROUND];
1378 videomode = rface->face.property[MFACE_VIDEOMODE];
1380 videomode = frame->videomode;
1381 if (videomode != Mreverse)
1383 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1384 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1388 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1389 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1392 if (foreground == Mnil)
1393 foreground = frame->foreground;
1394 if (background == Mnil)
1395 background = frame->background;
1396 if (videomode == Mreverse)
1398 MSymbol temp = foreground;
1399 foreground = background;
1402 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1403 FRAME_VISUAL (frame),
1405 MSYMBOL_NAME (foreground),
1406 &info->xft_color_fore))
1408 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1409 FRAME_VISUAL (frame),
1411 MSYMBOL_NAME (background),
1412 &info->xft_color_back))
1414 #endif /* HAVE_XFT2 */
1416 hline = rface->hline;
1420 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1422 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1429 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1431 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1433 if (box->color_left && box->color_left != box->color_top)
1434 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1436 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1438 if (box->color_bottom && box->color_bottom != box->color_top)
1439 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1441 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1443 if (box->color_right && box->color_right != box->color_bottom)
1444 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1446 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1454 mwin__free_realized_face (MRealizedFace *rface)
1456 if (rface == rface->ascii_rface)
1462 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1464 int x, int y, int width, int height, MDrawRegion region)
1466 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1469 gc = set_region (frame, gc, region);
1471 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1472 x, y, width, height);
1477 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1478 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1479 int reverse, MDrawRegion region)
1481 MRealizedFace *rface = from->rface;
1482 Display *display = FRAME_DISPLAY (rface->frame);
1483 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1489 gc = set_region (rface->frame, gc, region);
1490 for (; from < to; from++)
1492 XDrawRectangle (display, (Window) win, gc,
1493 x, y - gstring->ascent + 1, from->width - 1,
1494 gstring->ascent + gstring->descent - 2);
1501 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1502 MRealizedFace *rface, int reverse,
1503 int x, int y, int width, MDrawRegion region)
1505 enum MFaceHLineType type = rface->hline->type;
1506 GCInfo *info = rface->info;
1507 GC gc = gc = info->gc[GC_HLINE];
1510 y = (type == MFACE_HLINE_BOTTOM
1511 ? y + gstring->text_descent - rface->hline->width
1512 : type == MFACE_HLINE_UNDER
1514 : type == MFACE_HLINE_STRIKE_THROUGH
1515 ? y - ((gstring->ascent + gstring->descent) / 2)
1516 : y - gstring->text_ascent);
1518 gc = set_region (frame, gc, region);
1520 for (i = 0; i < rface->hline->width; i++)
1521 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1522 x, y + i, x + width - 1, y + i);
1527 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1528 MGlyph *g, int x, int y, int width, MDrawRegion region)
1530 Display *display = FRAME_DISPLAY (frame);
1531 MRealizedFace *rface = g->rface;
1532 MFaceBoxProp *box = rface->box;
1533 GCInfo *info = rface->info;
1534 GC gc_top, gc_left, gc_right, gc_btm;
1538 y0 = y - (gstring->text_ascent
1539 + rface->box->inner_vmargin + rface->box->width);
1540 y1 = y + (gstring->text_descent
1541 + rface->box->inner_vmargin + rface->box->width - 1);
1543 gc_top = info->gc[GC_BOX_TOP];
1545 gc_top = set_region (frame, gc_top, region);
1546 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1549 gc_btm = info->gc[GC_BOX_BOTTOM];
1551 if (g->type == GLYPH_BOX)
1555 if (g->left_padding)
1556 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1558 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1560 /* Draw the top side. */
1561 for (i = 0; i < box->width; i++)
1562 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1564 /* Draw the bottom side. */
1565 if (region && gc_btm != gc_top)
1566 gc_btm = set_region (frame, gc_btm, region);
1567 for (i = 0; i < box->width; i++)
1568 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1570 if (g->left_padding > 0)
1572 /* Draw the left side. */
1573 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1577 gc_left = info->gc[GC_BOX_LEFT];
1579 gc_left = set_region (frame, gc_left, region);
1581 for (i = 0; i < rface->box->width; i++)
1582 XDrawLine (display, (Window) win, gc_left,
1583 x0 + i, y0 + i, x0 + i, y1 - i);
1587 /* Draw the right side. */
1588 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1592 gc_right = info->gc[GC_BOX_RIGHT];
1594 gc_right = set_region (frame, gc_right, region);
1596 for (i = 0; i < rface->box->width; i++)
1597 XDrawLine (display, (Window) win, gc_right,
1598 x1 - i, y0 + i, x1 - i, y1 - i);
1603 /* Draw the top side. */
1604 for (i = 0; i < box->width; i++)
1605 XDrawLine (display, (Window) win, gc_top,
1606 x, y0 + i, x + width - 1, y0 + i);
1608 /* Draw the bottom side. */
1609 if (region && gc_btm != gc_top)
1610 gc_btm = set_region (frame, gc_btm, region);
1611 for (i = 0; i < box->width; i++)
1612 XDrawLine (display, (Window) win, gc_btm,
1613 x, y1 - i, x + width - 1, y1 - i);
1620 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1621 int reverse, int x, int y,
1622 int width, int height, int row_bytes, unsigned char *bmp,
1625 Display *display = FRAME_DISPLAY (frame);
1627 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1630 gc = set_region (frame, gc, region);
1632 for (i = 0; i < height; i++, bmp += row_bytes)
1633 for (j = 0; j < width; j++)
1634 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1635 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1640 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1641 int intensity, MDrawPoint *points, int num,
1644 GCInfo *info = rface->info;
1647 if (! (gc = info->gc[intensity]))
1648 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1651 gc = set_region (frame, gc, region);
1653 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1654 (XPoint *) points, num, CoordModeOrigin);
1659 mwin__region_from_rect (MDrawMetric *rect)
1661 MDrawRegion region1 = XCreateRegion ();
1662 MDrawRegion region2 = XCreateRegion ();
1667 xrect.width = rect->width;
1668 xrect.height = rect->height;
1669 XUnionRectWithRegion (&xrect, region1, region2);
1670 XDestroyRegion (region1);
1675 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1677 MDrawRegion region1 = XCreateRegion ();
1682 xrect.width = rect->width;
1683 xrect.height = rect->height;
1685 XUnionRegion (region, region, region1);
1686 XUnionRectWithRegion (&xrect, region1, region);
1687 XDestroyRegion (region1);
1691 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1693 MDrawRegion region = XCreateRegion ();
1695 XUnionRegion (region1, region1, region);
1696 XIntersectRegion (region, region2, region1);
1697 XDestroyRegion (region);
1701 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1703 MDrawRegion region1 = XCreateRegion ();
1708 xrect.width = rect->width;
1709 xrect.height = rect->height;
1710 XUnionRectWithRegion (&xrect, region1, region);
1711 XDestroyRegion (region1);
1715 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1719 XClipBox (region, &xrect);
1722 rect->width = xrect.width;
1723 rect->height = xrect.height;
1727 mwin__free_region (MDrawRegion region)
1729 XDestroyRegion (region);
1733 mwin__dump_region (MDrawRegion region)
1736 XClipBox (region, &rect);
1737 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1742 mwin__create_window (MFrame *frame, MDrawWindow parent)
1744 Display *display = FRAME_DISPLAY (frame);
1746 XWMHints wm_hints = { InputHint, False };
1747 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1748 XSetWindowAttributes set_attrs;
1751 GCInfo *info = frame->rface->info;
1754 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1755 mask = GCForeground;
1756 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1757 set_attrs.background_pixel = values.foreground;
1758 set_attrs.backing_store = Always;
1759 set_attrs.override_redirect = True;
1760 set_attrs.save_under = True;
1761 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1762 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1763 CopyFromParent, InputOutput, CopyFromParent,
1765 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1766 NULL, &wm_hints, &class_hints);
1767 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1768 return (MDrawWindow) win;
1772 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1775 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1777 if (XftDrawDrawable (xft_draw) == (Drawable) win)
1778 XftDrawChange (xft_draw, FRAME_DEVICE (frame)->drawable);
1779 #endif /* HAVE_XFT2 */
1780 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1785 mwin__event_window (void *event)
1787 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1791 mwin__print_event (void *arg, char *win_name)
1794 XEvent *event = (XEvent *) arg;
1796 switch (event->xany.type)
1798 case 2: event_name = "KeyPress"; break;
1799 case 3: event_name = "KeyRelease"; break;
1800 case 4: event_name = "ButtonPress"; break;
1801 case 5: event_name = "ButtonRelease"; break;
1802 case 6: event_name = "MotionNotify"; break;
1803 case 7: event_name = "EnterNotify"; break;
1804 case 8: event_name = "LeaveNotify"; break;
1805 case 9: event_name = "FocusIn"; break;
1806 case 10: event_name = "FocusOut"; break;
1807 case 11: event_name = "KeymapNotify"; break;
1808 case 12: event_name = "Expose"; break;
1809 case 13: event_name = "GraphicsExpose"; break;
1810 case 14: event_name = "NoExpose"; break;
1811 case 15: event_name = "VisibilityNotify"; break;
1812 case 16: event_name = "CreateNotify"; break;
1813 case 17: event_name = "DestroyNotify"; break;
1814 case 18: event_name = "UnmapNotify"; break;
1815 case 19: event_name = "MapNotify"; break;
1816 case 20: event_name = "MapRequest"; break;
1817 case 21: event_name = "ReparentNotify"; break;
1818 case 22: event_name = "ConfigureNotify"; break;
1819 case 23: event_name = "ConfigureRequest"; break;
1820 case 24: event_name = "GravityNotify"; break;
1821 case 25: event_name = "ResizeRequest"; break;
1822 case 26: event_name = "CirculateNotify"; break;
1823 case 27: event_name = "CirculateRequest"; break;
1824 case 28: event_name = "PropertyNotify"; break;
1825 case 29: event_name = "SelectionClear"; break;
1826 case 30: event_name = "SelectionRequest"; break;
1827 case 31: event_name = "SelectionNotify"; break;
1828 case 32: event_name = "ColormapNotify"; break;
1829 case 33: event_name = "ClientMessage"; break;
1830 case 34: event_name = "MappingNotify"; break;
1831 default: event_name = "unknown";
1834 fprintf (stderr, "%s: %s\n", win_name, event_name);
1839 mwin__map_window (MFrame *frame, MDrawWindow win)
1841 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1845 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1847 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1851 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1852 MDrawMetric *geometry)
1854 Display *display = FRAME_DISPLAY (frame);
1855 XWindowAttributes attr;
1856 Window parent = (Window) parent_win, root;
1858 XGetWindowAttributes (display, (Window) win, &attr);
1859 geometry->x = attr.x + attr.border_width;
1860 geometry->y = attr.y + attr.border_width;
1861 geometry->width = attr.width;
1862 geometry->height = attr.height;
1865 parent = RootWindow (display, FRAME_SCREEN (frame));
1868 Window this_parent, *children;
1871 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1874 if (this_parent == parent || this_parent == root)
1876 win = (MDrawWindow) this_parent;
1877 XGetWindowAttributes (display, (Window) win, &attr);
1878 geometry->x += attr.x + attr.border_width;
1879 geometry->y += attr.y + attr.border_width;
1884 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1885 MDrawMetric *current, MDrawMetric *new)
1887 Display *display = FRAME_DISPLAY (frame);
1888 unsigned int mask = 0;
1889 XWindowChanges values;
1891 if (current->width != new->width)
1894 if (new->width <= 0)
1896 values.width = current->width = new->width;
1898 if (current->height != new->height)
1901 if (new->height <= 0)
1903 values.height = current->height = new->height;
1905 if (current->x != new->x)
1908 values.x = current->x = new->x;
1910 if (current->y != new->y)
1913 current->y = new->y;
1914 values.y = current->y = new->y;
1917 XConfigureWindow (display, (Window) win, mask, &values);
1918 XClearWindow (display, (Window) win);
1922 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1924 XEvent *event = (XEvent *) arg;
1925 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
1932 if (event->xany.type != KeyPress
1933 /* && event->xany.type != KeyRelease */
1936 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
1939 if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
1941 if (len == 1 && keysym >= XK_space && keysym <= XK_asciitilde)
1945 key = minput__char_to_key (c);
1946 if (c == ' ' && ((XKeyEvent *) event)->state & ShiftMask)
1947 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1951 char *str = XKeysymToString (keysym);
1955 key = msymbol (str);
1956 if (((XKeyEvent *) event)->state & ShiftMask)
1957 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1959 if (((XKeyEvent *) event)->state & ControlMask)
1960 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1961 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
1962 *modifiers |= MINPUT_KEY_META_MODIFIER;
1963 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
1964 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
1965 if (((XKeyEvent *) event)->state & disp_info->super_mask)
1966 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
1967 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
1968 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
1975 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
1977 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
1979 Display *display = FRAME_DISPLAY (frame);
1980 GCInfo *info = rface->info;
1983 for (i = 0; i <= GC_INVERSE; i++)
1985 XGetGCValues (display, info->gc[i], valuemask, &values);
1986 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
1987 values.foreground, values.background);
1988 fprintf (stderr, "\n");
1992 static MDeviceDriver x_driver =
1995 mwin__device_get_prop,
1997 mwin__free_realized_face,
1999 mwin__draw_empty_boxes,
2003 mwin__region_from_rect,
2004 mwin__union_rect_with_region,
2005 mwin__intersect_region,
2006 mwin__region_add_rect,
2007 mwin__region_to_rect,
2010 mwin__create_window,
2011 mwin__destroy_window,
2014 mwin__window_geometry,
2015 mwin__adjust_window,
2019 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
2024 M_iso8859_1 = msymbol ("iso8859-1");
2025 M_iso10646_1 = msymbol ("iso10646-1");
2027 display_info_list = mplist ();
2028 device_list = mplist ();
2031 xft_driver.select = mfont__ft_driver.select;
2032 xft_driver.list = mfont__ft_driver.list;
2033 xft_driver.list_family_names = mfont__ft_driver.list_family_names;
2036 Mxim = msymbol ("xim");
2037 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
2045 M17N_OBJECT_UNREF (display_info_list);
2046 M17N_OBJECT_UNREF (device_list);
2051 #ifdef X_SET_ERROR_HANDLER
2053 x_error_handler (Display *display, XErrorEvent *error)
2060 x_io_error_handler (Display *display)
2067 /** Return an MWDevice object corresponding to a display specified in
2070 It searches device_list for a device matching the display. If
2071 found, return the found object. Otherwise, return a newly created
2075 device_open (MFrame *frame, MPlist *param)
2077 Display *display = NULL;
2078 Screen *screen = NULL;
2080 Drawable drawable = 0;
2081 Widget widget = NULL;
2083 int auto_display = 0;
2084 MDisplayInfo *disp_info = NULL;
2085 MWDevice *device = NULL;
2087 XWindowAttributes attr;
2093 int use_xfont = 0, use_freetype = 0, use_xft = 0;
2095 for (plist = param; (key = mplist_key (plist)) != Mnil;
2096 plist = mplist_next (plist))
2098 if (key == Mdisplay)
2099 display = (Display *) mplist_value (plist);
2100 else if (key == Mscreen)
2101 screen = mplist_value (plist);
2102 else if (key == Mdrawable)
2103 drawable = (Drawable) mplist_value (plist);
2104 else if (key == Mdepth)
2105 depth = (unsigned) mplist_value (plist);
2106 else if (key == Mwidget)
2107 widget = (Widget) mplist_value (plist);
2108 else if (key == Mcolormap)
2109 cmap = (Colormap) mplist_value (plist);
2110 else if (key == Mfont)
2112 MSymbol val = MPLIST_SYMBOL (plist);
2116 #ifdef HAVE_FREETYPE
2117 else if (val == Mfreetype)
2120 else if (val == Mxft)
2127 /* If none of them is specified, use all of them. */
2128 if (! use_xfont && ! use_freetype && ! use_xft)
2129 use_xfont = use_freetype = use_xft = 1;
2133 display = XtDisplay (widget);
2134 screen_num = XScreenNumberOfScreen (XtScreen (widget));
2135 depth = DefaultDepth (display, screen_num);
2141 unsigned width, height, border_width;
2144 MERROR (MERROR_WIN, -1);
2145 XGetGeometry (display, drawable, &root_window,
2146 &x, &y, &width, &height, &border_width, &depth);
2147 XGetWindowAttributes (display, root_window, &attr);
2148 screen_num = XScreenNumberOfScreen (attr.screen);
2153 display = DisplayOfScreen (screen);
2158 display = XOpenDisplay (NULL);
2160 MERROR (MERROR_WIN, -1);
2163 screen = DefaultScreenOfDisplay (display);
2165 screen_num = XScreenNumberOfScreen (screen);
2167 depth = DefaultDepth (display, screen_num);
2171 cmap = DefaultColormap (display, screen_num);
2173 for (plist = display_info_list; mplist_key (plist) != Mnil;
2174 plist = mplist_next (plist))
2176 disp_info = (MDisplayInfo *) mplist_value (plist);
2177 if (disp_info->display == display)
2181 if (mplist_key (plist) != Mnil)
2182 M17N_OBJECT_REF (disp_info);
2185 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2186 disp_info->display = display;
2187 disp_info->auto_display = auto_display;
2188 disp_info->font_list = mplist ();
2189 find_modifier_bits (disp_info);
2190 disp_info->MULE_BASELINE_OFFSET
2191 = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
2192 disp_info->AVERAGE_WIDTH
2193 = XInternAtom (display, "AVERAGE_WIDTH", False);
2194 mplist_add (display_info_list, Mt, disp_info);
2197 for (plist = device_list; mplist_key (plist) != Mnil;
2198 plist = mplist_next (plist))
2200 device = (MWDevice *) mplist_value (plist);
2201 if (device->display_info == disp_info
2202 && device->depth == depth
2203 && device->cmap == cmap
2204 && device->screen_num == screen_num)
2208 if (mplist_key (plist) != Mnil)
2209 M17N_OBJECT_REF (device);
2212 unsigned long valuemask = GCForeground;
2216 M17N_OBJECT (device, free_device, MERROR_WIN);
2217 device->display_info = disp_info;
2218 device->screen_num = screen_num;
2219 /* A drawable on which to create GCs. */
2220 device->drawable = XCreatePixmap (display,
2221 RootWindow (display, screen_num),
2223 device->depth = depth;
2224 device->cmap = cmap;
2225 pixels = DisplayHeight (display, screen_num);
2226 mm = DisplayHeightMM (display, screen_num);
2227 device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
2228 device->realized_face_list = mplist ();
2229 device->realized_font_list = mplist ();
2230 mplist_add (device->realized_font_list, Mt, NULL);
2231 device->realized_fontset_list = mplist ();
2232 device->gc_list = mplist ();
2233 values.foreground = BlackPixel (display, screen_num);
2234 device->scratch_gc = XCreateGC (display, device->drawable,
2235 valuemask, &values);
2237 device->xft_draw = XftDrawCreate (display, device->drawable,
2238 DefaultVisual (display, screen_num),
2243 frame->device = device;
2244 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2245 frame->dpi = device->resy;
2246 frame->driver = &x_driver;
2247 frame->font_driver_list = mplist ();
2251 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2254 #endif /* HAVE_XFT2 */
2255 #ifdef HAVE_FREETYPE
2257 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2258 #endif /* HAVE_FREETYPE */
2259 if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
2260 mplist_push (frame->font_driver_list, Mx, &xfont_driver);
2262 frame->realized_font_list = device->realized_font_list;
2263 frame->realized_face_list = device->realized_face_list;
2264 frame->realized_fontset_list = device->realized_fontset_list;
2268 XtResource resources[] = {
2269 { XtNfont, XtCFont, XtRString, sizeof (String),
2270 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2271 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2272 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2273 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2274 XtOffset (AppDataPtr, background), XtRString, "white" },
2275 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2276 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2279 XtGetApplicationResources (widget, &app_data,
2280 resources, XtNumber (resources), NULL, 0);
2281 frame->foreground = msymbol (app_data.foreground);
2282 frame->background = msymbol (app_data.background);
2283 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2287 app_data.font = DEFAULT_FONT;
2288 frame->foreground = msymbol ("black");
2289 frame->background = msymbol ("white");
2290 frame->videomode = Mnormal;
2293 if (strcmp (app_data.font, DEFAULT_FONT) != 0)
2295 XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
2296 unsigned long value;
2301 font = mfont_parse_name (app_data.font, Mx);
2303 && XGetFontProperty (xfont, XA_FONT, &value)
2304 && (name = ((char *) XGetAtomName (display, (Atom) value))))
2305 font = mfont_parse_name (name, Mx);
2306 XFreeFont (display, xfont);
2310 font = mfont_parse_name (DEFAULT_FONT, Mx);
2311 else if (! font->size)
2313 face = mface_from_font (font);
2315 face->property[MFACE_FONTSET] = mfontset (NULL);
2316 face->property[MFACE_FOREGROUND] = frame->foreground;
2317 face->property[MFACE_BACKGROUND] = frame->background;
2318 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2319 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2320 face->property[MFACE_VIDEOMODE] = frame->videomode;
2321 mface_put_prop (face, Mhook_func,
2322 mface_get_prop (mface__default, Mhook_func));
2323 face->property[MFACE_RATIO] = (void *) 100;
2324 mplist_push (param, Mface, face);
2325 M17N_OBJECT_UNREF (face);
2327 #ifdef X_SET_ERROR_HANDLER
2328 XSetErrorHandler (x_error_handler);
2329 XSetIOErrorHandler (x_io_error_handler);
2336 /* XIM (X Input Method) handler */
2338 typedef struct MInputXIMMethodInfo
2344 } MInputXIMMethodInfo;
2346 typedef struct MInputXIMContextInfo
2350 MConverter *converter;
2351 } MInputXIMContextInfo;
2354 xim_open_im (MInputMethod *im)
2356 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
2357 MLocale *saved, *this;
2358 char *save_modifier_list;
2360 MInputXIMMethodInfo *im_info;
2362 saved = mlocale_set (LC_CTYPE, NULL);
2363 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
2365 /* The specified locale is not supported. */
2366 MERROR (MERROR_LOCALE, -1);
2367 if (mlocale_get_prop (this, Mcoding) == Mnil)
2369 /* Unable to decode the output of XIM. */
2370 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2371 MERROR (MERROR_LOCALE, -1);
2374 if (arg->modifier_list)
2375 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
2377 save_modifier_list = XSetLocaleModifiers ("");
2378 if (! save_modifier_list)
2380 /* The specified locale is not supported by X. */
2381 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2382 MERROR (MERROR_LOCALE, -1);
2385 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
2388 /* No input method is available in the current locale. */
2389 XSetLocaleModifiers (save_modifier_list);
2390 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2391 MERROR (MERROR_WIN, -1);
2394 MSTRUCT_MALLOC (im_info, MERROR_WIN);
2395 im_info->display = arg->display;
2397 im_info->language = mlocale_get_prop (this, Mlanguage);
2398 im_info->coding = mlocale_get_prop (this, Mcoding);
2401 XSetLocaleModifiers (save_modifier_list);
2402 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2408 xim_close_im (MInputMethod *im)
2410 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
2412 XCloseIM (im_info->xim);
2417 xim_create_ic (MInputContext *ic)
2419 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
2420 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2421 MInputXIMContextInfo *ic_info;
2424 if (! arg->input_style)
2426 /* By default, use Root style. */
2427 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
2428 arg->preedit_attrs = NULL;
2429 arg->status_attrs = NULL;
2432 if (! arg->preedit_attrs && ! arg->status_attrs)
2433 xic = XCreateIC (im_info->xim,
2434 XNInputStyle, arg->input_style,
2435 XNClientWindow, arg->client_win,
2436 XNFocusWindow, arg->focus_win,
2438 else if (arg->preedit_attrs && ! arg->status_attrs)
2439 xic = XCreateIC (im_info->xim,
2440 XNInputStyle, arg->input_style,
2441 XNClientWindow, arg->client_win,
2442 XNFocusWindow, arg->focus_win,
2443 XNPreeditAttributes, arg->preedit_attrs,
2445 else if (! arg->preedit_attrs && arg->status_attrs)
2446 xic = XCreateIC (im_info->xim,
2447 XNInputStyle, arg->input_style,
2448 XNClientWindow, arg->client_win,
2449 XNFocusWindow, arg->focus_win,
2450 XNStatusAttributes, arg->status_attrs,
2453 xic = XCreateIC (im_info->xim,
2454 XNInputStyle, arg->input_style,
2455 XNClientWindow, arg->client_win,
2456 XNFocusWindow, arg->focus_win,
2457 XNPreeditAttributes, arg->preedit_attrs,
2458 XNStatusAttributes, arg->status_attrs,
2461 MERROR (MERROR_WIN, -1);
2463 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
2465 ic_info->win = arg->focus_win;
2466 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
2472 xim_destroy_ic (MInputContext *ic)
2474 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2476 XDestroyIC (ic_info->xic);
2477 mconv_free_converter (ic_info->converter);
2483 xim_filter (MInputContext *ic, MSymbol key, void *event)
2485 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2487 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
2492 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2494 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2495 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2496 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
2502 buf = (char *) alloca (512);
2503 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
2504 if (status == XBufferOverflow)
2506 buf = (char *) alloca (len);
2507 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
2510 mtext_reset (ic->produced);
2514 mconv_reset_converter (ic_info->converter);
2515 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
2516 mconv_decode (ic_info->converter, ic->produced);
2517 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2518 Mlanguage, (void *) im_info->language);
2519 mtext_cpy (mt, ic->produced);
2520 mtext_reset (ic->produced);
2528 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2532 /*** @addtogroup m17nInputMethodWin */
2537 @brief Input method driver for XIM.
2539 The driver #minput_xim_driver is for the foreign input method of
2540 name #Mxim. It uses XIM (X Input Methods) as a background input
2543 As the symbol #Mxim has property #Minput_driver whose value is
2544 a pointer to this driver, the input method of language #Mnil
2545 and name #Mxim uses this driver.
2547 Therefore, for such input methods, the driver dependent arguments
2548 to the functions whose name begin with minput_ must be as follows.
2550 The argument $ARG of the function minput_open_im () must be a
2551 pointer to the structure #MInputXIMArgIM. See the documentation
2552 of #MInputXIMArgIM for more details.
2554 The argument $ARG of the function minput_create_ic () must be a
2555 pointer to the structure #MInputXIMArgIC. See the documentation
2556 of #MInputXIMArgIC for more details.
2558 The argument $ARG of the function minput_filter () must be a
2559 pointer to the structure @c XEvent. The argument $KEY is ignored.
2561 The argument $ARG of the function minput_lookup () must be the
2562 same one as that of the function minput_filter (). The argument
2566 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2568 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
2569 XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2571 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2572 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
2573 ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2575 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
2576 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2578 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
2579 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
2581 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
2582 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
2584 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
2585 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2587 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2588 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
2590 MInputDriver minput_xim_driver =
2591 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2592 xim_filter, xim_lookup, NULL };
2596 #else /* not HAVE_X11 */
2598 int device_open () { return -1; }
2600 #endif /* not HAVE_X11 */