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)
628 MRealizedFontX *x_rfont;
630 Display *display = FRAME_DISPLAY (frame);
632 int mdebug_mask = MDEBUG_FONT;
636 /* non-scalable font */
640 int ratio = mfont_resize_ratio (font);
642 size = ratio == 100 ? spec->size : spec->size * ratio / 100;
649 for (; rfont; rfont = rfont->next)
650 if (rfont->font == font && rfont->spec.size == size)
656 /* This never fail to generate a valid fontname. */
657 name = mfont_unparse_name (&this, Mx);
658 xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
661 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
663 font->type = MFONT_TYPE_FAILURE;
666 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
668 M17N_OBJECT (x_rfont, close_xfont, MERROR_FONT_X);
669 x_rfont->display = display;
670 x_rfont->xfont = xfont;
671 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
673 rfont->spec.type = MFONT_TYPE_REALIZED;
674 rfont->spec.source = MFONT_SOURCE_X;
675 rfont->frame = frame;
677 rfont->driver = &xfont_driver;
678 rfont->info = x_rfont;
680 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
683 rfont->baseline_offset
684 = (XGetFontProperty (xfont, disp_info->MULE_BASELINE_OFFSET, &value)
687 = (XGetFontProperty (xfont, disp_info->AVERAGE_WIDTH, &value)
688 ? (int) value / 10 : 0);
690 rfont->ascent = xfont->ascent + rfont->baseline_offset;
691 rfont->descent = xfont->descent - rfont->baseline_offset;
692 rfont->max_advance = xfont->max_bounds.width;
693 rfont->fontp = xfont;
694 rfont->next = MPLIST_VAL (frame->realized_font_list);
695 MPLIST_VAL (frame->realized_font_list) = rfont;
700 /* The X font driver function FIND_METRIC. */
703 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
706 XFontStruct *xfont = rfont->fontp;
707 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
709 for (; g != gend; g++)
711 if (g->code == MCHAR_INVALID_CODE)
713 g->lbearing = xfont->max_bounds.lbearing;
714 g->rbearing = xfont->max_bounds.rbearing;
715 g->width = xfont->max_bounds.width;
716 g->ascent = xfont->ascent;
717 g->descent = xfont->descent;
721 int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
722 XCharStruct *pcm = NULL;
724 if (xfont->per_char != NULL)
726 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
729 && byte2 >= xfont->min_char_or_byte2
730 && byte2 <= xfont->max_char_or_byte2)
731 pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
735 if (byte1 >= xfont->min_byte1
736 && byte1 <= xfont->max_byte1
737 && byte2 >= xfont->min_char_or_byte2
738 && byte2 <= xfont->max_char_or_byte2)
740 pcm = (xfont->per_char
741 + ((xfont->max_char_or_byte2
742 - xfont->min_char_or_byte2 + 1)
743 * (byte1 - xfont->min_byte1))
744 + (byte2 - xfont->min_char_or_byte2));
751 g->lbearing = pcm->lbearing;
752 g->rbearing = pcm->rbearing;
753 g->width = pcm->width;
754 g->ascent = pcm->ascent;
755 g->descent = pcm->descent;
759 /* If the per_char pointer is null, all glyphs between
760 the first and last character indexes inclusive have
761 the same information, as given by both min_bounds and
764 g->rbearing = xfont->max_bounds.width;
765 g->width = xfont->max_bounds.width;
766 g->ascent = xfont->ascent;
767 g->descent = xfont->descent;
770 g->ascent += rfont->baseline_offset;
771 g->descent -= rfont->baseline_offset;
777 xfont_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
779 return (xfont_encode_char (frame, font, spec, code) != MCHAR_INVALID_CODE);
782 /* The X font driver function GET_GLYPH_ID. */
785 xfont_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
787 MRealizedFont *rfont;
789 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
792 if (font->type == MFONT_TYPE_REALIZED)
793 rfont = (MRealizedFont *) font;
794 else if (font->type == MFONT_TYPE_OBJECT)
796 int size = spec->size;
798 for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
800 if (rfont->font == font && rfont->spec.size == size)
804 rfont = xfont_open (frame, font, spec, NULL);
806 return MCHAR_INVALID_CODE;
810 MFATAL (MERROR_FONT_X);
811 xfont = rfont->fontp;
812 all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True);
813 min_byte1 = xfont->min_byte1;
814 max_byte1 = xfont->max_byte1;
815 min_byte2 = xfont->min_char_or_byte2;
816 max_byte2 = xfont->max_char_or_byte2;
818 if (min_byte1 == 0 && max_byte1 == 0)
822 if (code < min_byte2 || code > max_byte2)
823 return MCHAR_INVALID_CODE;
826 pcm = xfont->per_char + (code - min_byte2);
827 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
828 ? code : MCHAR_INVALID_CODE);
832 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
835 if (byte1 < min_byte1 || byte1 > max_byte1
836 || byte2 < min_byte2 || byte2 > max_byte2)
837 return MCHAR_INVALID_CODE;
841 pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
842 + (byte2 - min_byte2));
843 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
844 ? code : MCHAR_INVALID_CODE);
848 /* The X font driver function RENDER. */
851 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
852 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
854 MRealizedFace *rface = from->rface;
855 Display *display = FRAME_DISPLAY (rface->frame);
857 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
865 baseline_offset = rface->rfont->baseline_offset;
867 gc = set_region (rface->frame, gc, region);
868 XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
869 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
870 for (i = 0, g = from; g < to; i++, g++)
872 code[i].byte1 = g->code >> 8;
873 code[i].byte2 = g->code & 0xFF;
879 if (g->type == GLYPH_PAD)
881 else if (g->type == GLYPH_SPACE)
882 for (; g < to && g->type == GLYPH_SPACE; g++)
884 else if (! g->rface->rfont)
886 if ((g->c >= 0x200B && g->c <= 0x200F)
887 || (g->c >= 0x202A && g->c <= 0x202E))
891 /* As a font is not found for this character, draw an
893 int box_width = g->width;
894 int box_height = gstring->ascent + gstring->descent;
900 XDrawRectangle (display, (Window) win, gc,
901 x, y - gstring->ascent, box_width, box_height);
905 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
907 XDrawString16 (display, (Window) win, gc,
908 x + g->xoff, y + g->yoff - baseline_offset,
909 code + (g - from), 1);
916 int code_idx = g - from;
919 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
922 XDrawString16 (display, (Window) win, gc,
923 orig_x, y - baseline_offset, code + code_idx, i);
929 xfont_list (MFrame *frame, MPlist *plist, MFont *font, int maxnum)
931 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
932 MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil;
933 MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil;
934 int size = font ? font->size : 0;
937 int mdebug_mask = MDEBUG_FONT;
939 MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
940 family ? msymbol_name (family) : "*",
941 registry ? msymbol_name (registry) : "*");
943 if (registry == Mnil)
944 xfont_list_all (frame);
946 xfont_registry_list (frame, registry);
948 MPLIST_DO (pl, disp_info->font_list)
950 if (registry != Mnil && registry != MPLIST_KEY (pl))
952 MPLIST_DO (p, MPLIST_VAL (pl))
956 if (family != Mnil && family != MPLIST_KEY (p))
958 for (fontx = MPLIST_VAL (p); fontx; fontx = fontx->next)
960 || (mfont__match_p (&fontx->core, font, MFONT_REGISTRY)))
962 if (fontx->core.size == size
963 || fontx->core.size == 0)
965 mplist_push (plist, MPLIST_KEY (p), fontx);
969 || (size <= 360 && HAVE_SIZE (fontx, (size / 10))))
971 unsigned size5_36 = fontx->size5_36;
976 for (i = fontx->core.size / 10; i <= 36; i++)
977 if (size5_36 & (1 << (i - 5)))
979 MSTRUCT_CALLOC (fontx2, MERROR_WIN);
980 fontx2->core = fontx->core;
981 fontx2->core.size = i * 10;
982 fontx2->next = fontx->next;
983 fontx->next = fontx2;
985 if ((size == 0 || size == fontx->core.size)
986 && (maxnum == 0 || num < maxnum))
988 mplist_push (plist, MPLIST_KEY (p), fontx);
993 if (maxnum > 0 && maxnum == num)
996 if (maxnum > 0 && maxnum == num)
999 if (maxnum > 0 && maxnum == num)
1003 MDEBUG_PRINT1 (" %d found\n", num);
1008 xfont_check_capability (MRealizedFont *rfont, MSymbol capability)
1010 /* Currently X font driver doesn't support any capability. */
1024 XftFont *font_no_aa;
1026 /* Pointer to MRealizedFontFT */
1030 static MRealizedFont *xft_open (MFrame *frame, MFont *font, MFont *spec,
1032 static int xft_has_char (MFrame *frame, MFont *font, MFont *spec,
1033 int c, unsigned code);
1034 static unsigned xft_encode_char (MFrame *frame, MFont *font, MFont *spec,
1036 static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
1037 static void xft_render (MDrawWindow, int, int, MGlyphString *,
1038 MGlyph *, MGlyph *, int, MDrawRegion);
1039 static int xft_check_capability (MRealizedFont *rfont, MSymbol capability);
1041 MFontDriver xft_driver =
1043 xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL,
1044 xft_check_capability
1048 close_xft (void *object)
1050 MRealizedFontXft *rfont_xft = object;
1052 if (rfont_xft->font_aa)
1053 XftFontClose (rfont_xft->display, rfont_xft->font_aa);
1054 if (rfont_xft->font_no_aa)
1055 XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
1056 M17N_OBJECT_UNREF (rfont_xft->info);
1062 xft_open_font (Display *display, MSymbol file, double size,
1068 pattern = FcPatternCreate ();
1069 FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
1070 FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
1071 FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
1072 font = XftFontOpenPattern (display, pattern);
1077 static MRealizedFont *
1078 xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
1080 Display *display = FRAME_DISPLAY (frame);
1081 int reg = spec->property[MFONT_REGISTRY];
1083 MRealizedFontXft *rfont_xft;
1084 FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
1087 int ascent, descent, max_advance, average_width, baseline_offset;
1090 /* non-scalable font */
1092 else if (spec->size)
1094 int ratio = mfont_resize_ratio (font);
1096 size = ratio == 100 ? spec->size : spec->size * ratio / 100;
1103 MRealizedFont *save = NULL;
1105 for (; rfont; rfont = rfont->next)
1106 if (rfont->font == font
1107 && (rfont->font->size ? rfont->font->size == size
1108 : rfont->spec.size == size)
1109 && rfont->spec.property[MFONT_REGISTRY] == reg)
1113 if (rfont->driver == &xft_driver)
1118 rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
1121 ascent = rfont->ascent;
1122 descent = rfont->descent;
1123 max_advance = rfont->max_advance;
1124 average_width = rfont->average_width;
1125 baseline_offset = rfont->baseline_offset;
1126 spec = &rfont->spec;
1127 ft_face = rfont->fontp;
1128 xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
1131 M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
1132 rfont_xft->display = display;
1133 if (anti_alias == FcTrue)
1134 rfont_xft->font_aa = xft_font;
1136 rfont_xft->font_no_aa = xft_font;
1137 rfont_xft->ft_face = ft_face;
1138 rfont_xft->info = rfont->info;
1139 M17N_OBJECT_REF (rfont->info);
1140 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
1141 rfont->spec = *spec;
1142 rfont->spec.size = size;
1143 rfont->frame = frame;
1145 rfont->driver = &xft_driver;
1146 rfont->info = rfont_xft;
1147 rfont->ascent = ascent;
1148 rfont->descent = descent;
1149 rfont->max_advance = max_advance;
1150 rfont->average_width = average_width;
1151 rfont->baseline_offset = baseline_offset;
1152 rfont->fontp = xft_font;
1153 rfont->next = MPLIST_VAL (frame->realized_font_list);
1154 MPLIST_VAL (frame->realized_font_list) = rfont;
1159 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1162 Display *display = FRAME_DISPLAY (rfont->frame);
1163 XftFont *xft_font = rfont->fontp;
1164 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1166 for (; g != gend; g++)
1168 if (g->code == MCHAR_INVALID_CODE)
1171 g->rbearing = xft_font->max_advance_width;
1172 g->width = g->rbearing;
1173 g->ascent = xft_font->ascent;
1174 g->descent = xft_font->descent;
1180 XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
1181 g->lbearing = - extents.x;
1182 g->rbearing = extents.width - extents.x;
1183 g->width = extents.xOff;
1184 g->ascent = extents.y;
1185 g->descent = extents.height - extents.y;
1191 xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
1195 if (font->type == MFONT_TYPE_REALIZED)
1197 MRealizedFont *rfont = (MRealizedFont *) font;
1198 MRealizedFontXft *rfont_xft = rfont->info;
1200 rfont->info = rfont_xft->info;
1201 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1202 rfont->info = rfont_xft;
1205 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1210 xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
1212 if (font->type == MFONT_TYPE_REALIZED)
1214 MRealizedFont *rfont = (MRealizedFont *) font;
1215 MRealizedFontXft *rfont_xft = rfont->info;
1217 rfont->info = rfont_xft->info;
1218 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1219 rfont->info = rfont_xft;
1222 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1227 xft_render (MDrawWindow win, int x, int y,
1228 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1229 int reverse, MDrawRegion region)
1231 MRealizedFace *rface = from->rface;
1232 MFrame *frame = rface->frame;
1233 Display *display = FRAME_DISPLAY (frame);
1234 MRealizedFont *rfont = rface->rfont;
1235 MRealizedFontXft *rfont_xft = rfont->info;
1236 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1237 XftColor *xft_color = (! reverse
1238 ? &((GCInfo *) rface->info)->xft_color_fore
1239 : &((GCInfo *) rface->info)->xft_color_back);
1240 int anti_alias = (gstring->control.anti_alias
1241 && FRAME_DEVICE (frame)->depth > 1);
1253 if (rfont_xft->font_aa)
1254 xft_font = rfont_xft->font_aa;
1257 double size = rfont->spec.size;
1259 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1262 rfont_xft->font_aa = xft_font;
1264 xft_font = rfont->fontp;
1269 if (rfont_xft->font_no_aa)
1270 xft_font = rfont_xft->font_no_aa;
1273 double size = rfont->spec.size;
1275 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1278 rfont_xft->font_no_aa = xft_font;
1280 xft_font = rfont->fontp;
1284 XftDrawChange (xft_draw, (Drawable) win);
1285 XftDrawSetClip (xft_draw, (Region) region);
1287 y -= rfont->baseline_offset;
1288 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1289 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
1291 if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
1292 glyphs[nglyphs++] = g->code;
1296 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1297 last_x, y, glyphs, nglyphs);
1299 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1300 x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
1301 last_x = x + g->width;
1305 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1309 xft_check_capability (MRealizedFont *rfont, MSymbol capability)
1311 MRealizedFontXft *rfont_xft = rfont->info;
1314 rfont->info = rfont_xft->info;
1315 result = mfont__ft_driver.check_capability (rfont, capability);
1316 rfont->info = rfont_xft;
1320 #endif /* HAVE_XFT2 */
1323 /* Functions for the device driver. */
1326 mwin__close_device (MFrame *frame)
1328 MWDevice *device = FRAME_DEVICE (frame);
1330 M17N_OBJECT_UNREF (device);
1334 mwin__device_get_prop (MFrame *frame, MSymbol key)
1336 MWDevice *device = FRAME_DEVICE (frame);
1338 if (key == Mdisplay)
1339 return (void *) device->display_info->display;
1341 return (void *) ScreenOfDisplay(device->display_info->display,
1342 device->screen_num);
1343 if (key == Mcolormap)
1344 return (void *) device->cmap;
1346 return (void *) device->depth;
1351 mwin__realize_face (MRealizedFace *rface)
1354 MSymbol foreground, background, videomode;
1355 MFaceHLineProp *hline;
1359 if (rface != rface->ascii_rface)
1361 rface->info = rface->ascii_rface->info;
1365 frame = rface->frame;
1366 MSTRUCT_CALLOC (info, MERROR_WIN);
1368 foreground = rface->face.property[MFACE_FOREGROUND];
1369 background = rface->face.property[MFACE_BACKGROUND];
1370 videomode = rface->face.property[MFACE_VIDEOMODE];
1372 videomode = frame->videomode;
1373 if (videomode != Mreverse)
1375 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1376 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1380 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1381 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1384 if (foreground == Mnil)
1385 foreground = frame->foreground;
1386 if (background == Mnil)
1387 background = frame->background;
1388 if (videomode == Mreverse)
1390 MSymbol temp = foreground;
1391 foreground = background;
1394 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1395 FRAME_VISUAL (frame),
1397 MSYMBOL_NAME (foreground),
1398 &info->xft_color_fore))
1400 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1401 FRAME_VISUAL (frame),
1403 MSYMBOL_NAME (background),
1404 &info->xft_color_back))
1406 #endif /* HAVE_XFT2 */
1408 hline = rface->hline;
1412 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1414 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1421 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1423 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1425 if (box->color_left && box->color_left != box->color_top)
1426 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1428 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1430 if (box->color_bottom && box->color_bottom != box->color_top)
1431 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1433 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1435 if (box->color_right && box->color_right != box->color_bottom)
1436 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1438 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1446 mwin__free_realized_face (MRealizedFace *rface)
1448 if (rface == rface->ascii_rface)
1454 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1456 int x, int y, int width, int height, MDrawRegion region)
1458 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1461 gc = set_region (frame, gc, region);
1463 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1464 x, y, width, height);
1469 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1470 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1471 int reverse, MDrawRegion region)
1473 MRealizedFace *rface = from->rface;
1474 Display *display = FRAME_DISPLAY (rface->frame);
1475 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1481 gc = set_region (rface->frame, gc, region);
1482 for (; from < to; from++)
1484 XDrawRectangle (display, (Window) win, gc,
1485 x, y - gstring->ascent + 1, from->width - 1,
1486 gstring->ascent + gstring->descent - 2);
1493 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1494 MRealizedFace *rface, int reverse,
1495 int x, int y, int width, MDrawRegion region)
1497 enum MFaceHLineType type = rface->hline->type;
1498 GCInfo *info = rface->info;
1499 GC gc = gc = info->gc[GC_HLINE];
1502 y = (type == MFACE_HLINE_BOTTOM
1503 ? y + gstring->text_descent - rface->hline->width
1504 : type == MFACE_HLINE_UNDER
1506 : type == MFACE_HLINE_STRIKE_THROUGH
1507 ? y - ((gstring->ascent + gstring->descent) / 2)
1508 : y - gstring->text_ascent);
1510 gc = set_region (frame, gc, region);
1512 for (i = 0; i < rface->hline->width; i++)
1513 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1514 x, y + i, x + width - 1, y + i);
1519 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1520 MGlyph *g, int x, int y, int width, MDrawRegion region)
1522 Display *display = FRAME_DISPLAY (frame);
1523 MRealizedFace *rface = g->rface;
1524 MFaceBoxProp *box = rface->box;
1525 GCInfo *info = rface->info;
1526 GC gc_top, gc_left, gc_right, gc_btm;
1530 y0 = y - (gstring->text_ascent
1531 + rface->box->inner_vmargin + rface->box->width);
1532 y1 = y + (gstring->text_descent
1533 + rface->box->inner_vmargin + rface->box->width - 1);
1535 gc_top = info->gc[GC_BOX_TOP];
1537 gc_top = set_region (frame, gc_top, region);
1538 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1541 gc_btm = info->gc[GC_BOX_BOTTOM];
1543 if (g->type == GLYPH_BOX)
1547 if (g->left_padding)
1548 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1550 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1552 /* Draw the top side. */
1553 for (i = 0; i < box->width; i++)
1554 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1556 /* Draw the bottom side. */
1557 if (region && gc_btm != gc_top)
1558 gc_btm = set_region (frame, gc_btm, region);
1559 for (i = 0; i < box->width; i++)
1560 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1562 if (g->left_padding > 0)
1564 /* Draw the left side. */
1565 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1569 gc_left = info->gc[GC_BOX_LEFT];
1571 gc_left = set_region (frame, gc_left, region);
1573 for (i = 0; i < rface->box->width; i++)
1574 XDrawLine (display, (Window) win, gc_left,
1575 x0 + i, y0 + i, x0 + i, y1 - i);
1579 /* Draw the right side. */
1580 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1584 gc_right = info->gc[GC_BOX_RIGHT];
1586 gc_right = set_region (frame, gc_right, region);
1588 for (i = 0; i < rface->box->width; i++)
1589 XDrawLine (display, (Window) win, gc_right,
1590 x1 - i, y0 + i, x1 - i, y1 - i);
1595 /* Draw the top side. */
1596 for (i = 0; i < box->width; i++)
1597 XDrawLine (display, (Window) win, gc_top,
1598 x, y0 + i, x + width - 1, y0 + i);
1600 /* Draw the bottom side. */
1601 if (region && gc_btm != gc_top)
1602 gc_btm = set_region (frame, gc_btm, region);
1603 for (i = 0; i < box->width; i++)
1604 XDrawLine (display, (Window) win, gc_btm,
1605 x, y1 - i, x + width - 1, y1 - i);
1612 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1613 int reverse, int x, int y,
1614 int width, int height, int row_bytes, unsigned char *bmp,
1617 Display *display = FRAME_DISPLAY (frame);
1619 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1622 gc = set_region (frame, gc, region);
1624 for (i = 0; i < height; i++, bmp += row_bytes)
1625 for (j = 0; j < width; j++)
1626 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1627 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1632 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1633 int intensity, MDrawPoint *points, int num,
1636 GCInfo *info = rface->info;
1639 if (! (gc = info->gc[intensity]))
1640 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1643 gc = set_region (frame, gc, region);
1645 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1646 (XPoint *) points, num, CoordModeOrigin);
1651 mwin__region_from_rect (MDrawMetric *rect)
1653 MDrawRegion region1 = XCreateRegion ();
1654 MDrawRegion region2 = XCreateRegion ();
1659 xrect.width = rect->width;
1660 xrect.height = rect->height;
1661 XUnionRectWithRegion (&xrect, region1, region2);
1662 XDestroyRegion (region1);
1667 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1669 MDrawRegion region1 = XCreateRegion ();
1674 xrect.width = rect->width;
1675 xrect.height = rect->height;
1677 XUnionRegion (region, region, region1);
1678 XUnionRectWithRegion (&xrect, region1, region);
1679 XDestroyRegion (region1);
1683 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1685 MDrawRegion region = XCreateRegion ();
1687 XUnionRegion (region1, region1, region);
1688 XIntersectRegion (region, region2, region1);
1689 XDestroyRegion (region);
1693 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1695 MDrawRegion region1 = XCreateRegion ();
1700 xrect.width = rect->width;
1701 xrect.height = rect->height;
1702 XUnionRectWithRegion (&xrect, region1, region);
1703 XDestroyRegion (region1);
1707 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1711 XClipBox (region, &xrect);
1714 rect->width = xrect.width;
1715 rect->height = xrect.height;
1719 mwin__free_region (MDrawRegion region)
1721 XDestroyRegion (region);
1725 mwin__dump_region (MDrawRegion region)
1728 XClipBox (region, &rect);
1729 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1734 mwin__create_window (MFrame *frame, MDrawWindow parent)
1736 Display *display = FRAME_DISPLAY (frame);
1738 XWMHints wm_hints = { InputHint, False };
1739 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1740 XSetWindowAttributes set_attrs;
1743 GCInfo *info = frame->rface->info;
1746 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1747 mask = GCForeground;
1748 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1749 set_attrs.background_pixel = values.foreground;
1750 set_attrs.backing_store = Always;
1751 set_attrs.override_redirect = True;
1752 set_attrs.save_under = True;
1753 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1754 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1755 CopyFromParent, InputOutput, CopyFromParent,
1757 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1758 NULL, &wm_hints, &class_hints);
1759 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1760 return (MDrawWindow) win;
1764 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1767 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1769 if (XftDrawDrawable (xft_draw) == (Drawable) win)
1770 XftDrawChange (xft_draw, FRAME_DEVICE (frame)->drawable);
1771 #endif /* HAVE_XFT2 */
1772 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1777 mwin__event_window (void *event)
1779 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1783 mwin__print_event (void *arg, char *win_name)
1786 XEvent *event = (XEvent *) arg;
1788 switch (event->xany.type)
1790 case 2: event_name = "KeyPress"; break;
1791 case 3: event_name = "KeyRelease"; break;
1792 case 4: event_name = "ButtonPress"; break;
1793 case 5: event_name = "ButtonRelease"; break;
1794 case 6: event_name = "MotionNotify"; break;
1795 case 7: event_name = "EnterNotify"; break;
1796 case 8: event_name = "LeaveNotify"; break;
1797 case 9: event_name = "FocusIn"; break;
1798 case 10: event_name = "FocusOut"; break;
1799 case 11: event_name = "KeymapNotify"; break;
1800 case 12: event_name = "Expose"; break;
1801 case 13: event_name = "GraphicsExpose"; break;
1802 case 14: event_name = "NoExpose"; break;
1803 case 15: event_name = "VisibilityNotify"; break;
1804 case 16: event_name = "CreateNotify"; break;
1805 case 17: event_name = "DestroyNotify"; break;
1806 case 18: event_name = "UnmapNotify"; break;
1807 case 19: event_name = "MapNotify"; break;
1808 case 20: event_name = "MapRequest"; break;
1809 case 21: event_name = "ReparentNotify"; break;
1810 case 22: event_name = "ConfigureNotify"; break;
1811 case 23: event_name = "ConfigureRequest"; break;
1812 case 24: event_name = "GravityNotify"; break;
1813 case 25: event_name = "ResizeRequest"; break;
1814 case 26: event_name = "CirculateNotify"; break;
1815 case 27: event_name = "CirculateRequest"; break;
1816 case 28: event_name = "PropertyNotify"; break;
1817 case 29: event_name = "SelectionClear"; break;
1818 case 30: event_name = "SelectionRequest"; break;
1819 case 31: event_name = "SelectionNotify"; break;
1820 case 32: event_name = "ColormapNotify"; break;
1821 case 33: event_name = "ClientMessage"; break;
1822 case 34: event_name = "MappingNotify"; break;
1823 default: event_name = "unknown";
1826 fprintf (stderr, "%s: %s\n", win_name, event_name);
1831 mwin__map_window (MFrame *frame, MDrawWindow win)
1833 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1837 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1839 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1843 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1844 MDrawMetric *geometry)
1846 Display *display = FRAME_DISPLAY (frame);
1847 XWindowAttributes attr;
1848 Window parent = (Window) parent_win, root;
1850 XGetWindowAttributes (display, (Window) win, &attr);
1851 geometry->x = attr.x + attr.border_width;
1852 geometry->y = attr.y + attr.border_width;
1853 geometry->width = attr.width;
1854 geometry->height = attr.height;
1857 parent = RootWindow (display, FRAME_SCREEN (frame));
1860 Window this_parent, *children;
1863 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1866 if (this_parent == parent || this_parent == root)
1868 win = (MDrawWindow) this_parent;
1869 XGetWindowAttributes (display, (Window) win, &attr);
1870 geometry->x += attr.x + attr.border_width;
1871 geometry->y += attr.y + attr.border_width;
1876 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1877 MDrawMetric *current, MDrawMetric *new)
1879 Display *display = FRAME_DISPLAY (frame);
1880 unsigned int mask = 0;
1881 XWindowChanges values;
1883 if (current->width != new->width)
1886 if (new->width <= 0)
1888 values.width = current->width = new->width;
1890 if (current->height != new->height)
1893 if (new->height <= 0)
1895 values.height = current->height = new->height;
1897 if (current->x != new->x)
1900 values.x = current->x = new->x;
1902 if (current->y != new->y)
1905 current->y = new->y;
1906 values.y = current->y = new->y;
1909 XConfigureWindow (display, (Window) win, mask, &values);
1910 XClearWindow (display, (Window) win);
1914 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1916 XEvent *event = (XEvent *) arg;
1917 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
1924 if (event->xany.type != KeyPress
1925 /* && event->xany.type != KeyRelease */
1928 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
1935 if (c < XK_space || c > XK_asciitilde)
1937 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
1938 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1939 if (((XKeyEvent *) event)->state & ControlMask)
1941 if (c >= 'a' && c <= 'z')
1943 if (c >= ' ' && c < 127)
1944 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1946 key = minput__char_to_key (c);
1948 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
1952 char *str = XKeysymToString (keysym);
1956 key = msymbol (str);
1957 if (((XKeyEvent *) event)->state & ShiftMask)
1958 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1959 if (((XKeyEvent *) event)->state & ControlMask)
1960 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1962 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
1963 *modifiers |= MINPUT_KEY_META_MODIFIER;
1964 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
1965 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
1966 if (((XKeyEvent *) event)->state & disp_info->super_mask)
1967 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
1968 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
1969 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
1976 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
1978 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
1980 Display *display = FRAME_DISPLAY (frame);
1981 GCInfo *info = rface->info;
1984 for (i = 0; i <= GC_INVERSE; i++)
1986 XGetGCValues (display, info->gc[i], valuemask, &values);
1987 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
1988 values.foreground, values.background);
1989 fprintf (stderr, "\n");
1993 static MDeviceDriver x_driver =
1996 mwin__device_get_prop,
1998 mwin__free_realized_face,
2000 mwin__draw_empty_boxes,
2004 mwin__region_from_rect,
2005 mwin__union_rect_with_region,
2006 mwin__intersect_region,
2007 mwin__region_add_rect,
2008 mwin__region_to_rect,
2011 mwin__create_window,
2012 mwin__destroy_window,
2015 mwin__window_geometry,
2016 mwin__adjust_window,
2020 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
2025 M_iso8859_1 = msymbol ("iso8859-1");
2026 M_iso10646_1 = msymbol ("iso10646-1");
2028 display_info_list = mplist ();
2029 device_list = mplist ();
2032 xft_driver.select = mfont__ft_driver.select;
2033 xft_driver.list = mfont__ft_driver.list;
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 */