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 void xfont_list_family_names (MFrame *, MPlist *);
447 static int xfont_check_capability (MRealizedFont *rfont, MSymbol capability);
449 static MFontDriver xfont_driver =
450 { xfont_select, xfont_open,
451 xfont_find_metric, xfont_has_char, xfont_encode_char,
452 xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability };
455 font_compare (const void *p1, const void *p2)
457 return strcmp (*(char **) p1, *(char **) p2);
461 xfont_registry_list (MFrame *frame, MSymbol registry)
463 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
464 MPlist *font_list = disp_info->font_list;
467 char **font_names, **names;
473 plist = mplist_get (font_list, registry);
477 mplist_add (font_list, registry, plist);
478 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", msymbol_name (registry));
479 font_names = XListFonts (disp_info->display, pattern, 0x8000, &nfonts);
483 char *reg_name = msymbol_name (registry);
485 for_full_width = (strncmp (reg_name, "jis", 3) == 0
486 || strncmp (reg_name, "gb", 2) == 0
487 || strncmp (reg_name, "big5", 4) == 0
488 || strncmp (reg_name, "ksc", 3) == 0);
490 names = alloca (sizeof (char *) * nfonts);
491 memcpy (names, font_names, sizeof (char *) * nfonts);
492 qsort (names, nfonts, sizeof (char *), font_compare);
494 for (i = 0, p = NULL; i < nfonts; i++)
495 if (mfont__parse_name_into_font (names[i], Mx, &font) == 0
496 && (font.size >= 50 || font.property[MFONT_RESY] == 0))
498 MSymbol family = FONT_PROPERTY (&font, MFONT_FAMILY);
499 MFontX *fontx, *fontx2;
507 if (p && MPLIST_KEY (p) != family)
508 p = mplist_find_by_key (plist, family);
510 p = mplist_push (plist, family, NULL);
512 /* Calculate how many bytes to compare to detect fonts of the
514 for (base_end = names[i], fields = 0; *base_end; base_end++)
516 && ++fields == 7 /* PIXEL_SIZE */)
518 base_len = base_end - names[i] + 1;
520 size = smallest = font.size / 10;
521 sizes[nsizes++] = size;
522 for (j = i + 1; j < nfonts && ! strncmp (names[i], names[j], base_len);
524 if (mfont__parse_name_into_font (names[j], Mx, &font) == 0
525 && (font.size >= 50 || font.property[MFONT_RESY] == 0))
527 size = font.size / 10;
531 sizes[nsizes++] = size;
534 font.for_full_width = for_full_width;
535 font.type = MFONT_TYPE_OBJECT;
536 font.source = MFONT_SOURCE_X;
537 MSTRUCT_CALLOC (fontx, MERROR_WIN);
539 fontx->core.size = smallest * 10;
540 fontx->next = MPLIST_VAL (p);
541 MPLIST_VAL (p) = fontx;
543 for (j = 0; j < nsizes; j++)
547 if (sizes[j] != smallest)
548 SET_SIZE (fontx, sizes[j]);
552 MSTRUCT_CALLOC (fontx2, MERROR_WIN);
554 fontx2->core.size = sizes[j] * 10;
555 fontx2->next = MPLIST_VAL (p);
556 MPLIST_VAL (p) = fontx2;
560 XFreeFontNames (font_names);
565 xfont_list_all (MFrame *frame)
567 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
568 MPlist *font_encoding_list, *p;
570 if (disp_info->all_fonts_scaned)
572 disp_info->all_fonts_scaned = 1;
573 font_encoding_list = mfont__encoding_list ();
574 if (! font_encoding_list)
576 MPLIST_DO (p, font_encoding_list)
577 xfont_registry_list (frame, MPLIST_KEY (p));
587 /* The X font driver function SELECT. */
590 xfont_select (MFrame *frame, MFont *font, int limited_size)
592 MPlist *plist = mplist (), *pl;
593 int num = xfont_list (frame, plist, font, 0);
597 MPLIST_DO (pl, plist)
599 font = MPLIST_VAL (pl);
600 if (limited_size == 0
602 || font->size <= limited_size)
608 M17N_OBJECT_UNREF (plist);
612 /* The X font driver function CLOSE. */
615 close_xfont (void *object)
617 MRealizedFontX *x_rfont = object;
619 XFreeFont (x_rfont->display, x_rfont->xfont);
623 /* The X font driver function OPEN. */
625 static MRealizedFont *
626 xfont_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
629 MRealizedFontX *x_rfont;
631 Display *display = FRAME_DISPLAY (frame);
633 int mdebug_mask = MDEBUG_FONT;
637 /* non-scalable font */
641 int ratio = mfont_resize_ratio (font);
643 size = ratio == 100 ? spec->size : spec->size * ratio / 100;
650 for (; rfont; rfont = rfont->next)
651 if (rfont->font == font && rfont->spec.size == size)
657 /* This never fail to generate a valid fontname. */
658 name = mfont_unparse_name (&this, Mx);
659 xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
662 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
664 font->type = MFONT_TYPE_FAILURE;
667 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
669 M17N_OBJECT (x_rfont, close_xfont, MERROR_FONT_X);
670 x_rfont->display = display;
671 x_rfont->xfont = xfont;
672 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
674 rfont->spec.type = MFONT_TYPE_REALIZED;
675 rfont->spec.source = MFONT_SOURCE_X;
676 rfont->frame = frame;
678 rfont->driver = &xfont_driver;
679 rfont->info = x_rfont;
681 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
684 rfont->baseline_offset
685 = (XGetFontProperty (xfont, disp_info->MULE_BASELINE_OFFSET, &value)
688 = (XGetFontProperty (xfont, disp_info->AVERAGE_WIDTH, &value)
689 ? (int) value / 10 : 0);
691 rfont->ascent = xfont->ascent + rfont->baseline_offset;
692 rfont->descent = xfont->descent - rfont->baseline_offset;
693 rfont->max_advance = xfont->max_bounds.width;
694 rfont->fontp = xfont;
695 rfont->next = MPLIST_VAL (frame->realized_font_list);
696 MPLIST_VAL (frame->realized_font_list) = rfont;
701 /* The X font driver function FIND_METRIC. */
704 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
707 XFontStruct *xfont = rfont->fontp;
708 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
710 for (; g != gend; g++)
712 if (g->code == MCHAR_INVALID_CODE)
714 g->lbearing = xfont->max_bounds.lbearing;
715 g->rbearing = xfont->max_bounds.rbearing;
716 g->width = xfont->max_bounds.width;
717 g->ascent = xfont->ascent;
718 g->descent = xfont->descent;
722 int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
723 XCharStruct *pcm = NULL;
725 if (xfont->per_char != NULL)
727 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
730 && byte2 >= xfont->min_char_or_byte2
731 && byte2 <= xfont->max_char_or_byte2)
732 pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
736 if (byte1 >= xfont->min_byte1
737 && byte1 <= xfont->max_byte1
738 && byte2 >= xfont->min_char_or_byte2
739 && byte2 <= xfont->max_char_or_byte2)
741 pcm = (xfont->per_char
742 + ((xfont->max_char_or_byte2
743 - xfont->min_char_or_byte2 + 1)
744 * (byte1 - xfont->min_byte1))
745 + (byte2 - xfont->min_char_or_byte2));
752 g->lbearing = pcm->lbearing;
753 g->rbearing = pcm->rbearing;
754 g->width = pcm->width;
755 g->ascent = pcm->ascent;
756 g->descent = pcm->descent;
760 /* If the per_char pointer is null, all glyphs between
761 the first and last character indexes inclusive have
762 the same information, as given by both min_bounds and
765 g->rbearing = xfont->max_bounds.width;
766 g->width = xfont->max_bounds.width;
767 g->ascent = xfont->ascent;
768 g->descent = xfont->descent;
771 g->ascent += rfont->baseline_offset;
772 g->descent -= rfont->baseline_offset;
778 xfont_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
780 return (xfont_encode_char (frame, font, spec, code) != MCHAR_INVALID_CODE);
783 /* The X font driver function GET_GLYPH_ID. */
786 xfont_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
788 MRealizedFont *rfont;
790 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
793 if (font->type == MFONT_TYPE_REALIZED)
794 rfont = (MRealizedFont *) font;
795 else if (font->type == MFONT_TYPE_OBJECT)
797 int size = spec->size;
799 for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
801 if (rfont->font == font && rfont->spec.size == size)
805 rfont = xfont_open (frame, font, spec, NULL);
807 return MCHAR_INVALID_CODE;
811 MFATAL (MERROR_FONT_X);
812 xfont = rfont->fontp;
813 all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True);
814 min_byte1 = xfont->min_byte1;
815 max_byte1 = xfont->max_byte1;
816 min_byte2 = xfont->min_char_or_byte2;
817 max_byte2 = xfont->max_char_or_byte2;
819 if (min_byte1 == 0 && max_byte1 == 0)
823 if (code < min_byte2 || code > max_byte2)
824 return MCHAR_INVALID_CODE;
827 pcm = xfont->per_char + (code - min_byte2);
828 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
829 ? code : MCHAR_INVALID_CODE);
833 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
836 if (byte1 < min_byte1 || byte1 > max_byte1
837 || byte2 < min_byte2 || byte2 > max_byte2)
838 return MCHAR_INVALID_CODE;
842 pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
843 + (byte2 - min_byte2));
844 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
845 ? code : MCHAR_INVALID_CODE);
849 /* The X font driver function RENDER. */
852 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
853 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
855 MRealizedFace *rface = from->rface;
856 Display *display = FRAME_DISPLAY (rface->frame);
858 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
866 baseline_offset = rface->rfont->baseline_offset;
868 gc = set_region (rface->frame, gc, region);
869 XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
870 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
871 for (i = 0, g = from; g < to; i++, g++)
873 code[i].byte1 = g->code >> 8;
874 code[i].byte2 = g->code & 0xFF;
880 if (g->type == GLYPH_PAD)
882 else if (g->type == GLYPH_SPACE)
883 for (; g < to && g->type == GLYPH_SPACE; g++)
885 else if (! g->rface->rfont)
887 if ((g->c >= 0x200B && g->c <= 0x200F)
888 || (g->c >= 0x202A && g->c <= 0x202E))
892 /* As a font is not found for this character, draw an
894 int box_width = g->width;
895 int box_height = gstring->ascent + gstring->descent;
901 XDrawRectangle (display, (Window) win, gc,
902 x, y - gstring->ascent, box_width, box_height);
906 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
908 XDrawString16 (display, (Window) win, gc,
909 x + g->xoff, y + g->yoff - baseline_offset,
910 code + (g - from), 1);
917 int code_idx = g - from;
920 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
923 XDrawString16 (display, (Window) win, gc,
924 orig_x, y - baseline_offset, code + code_idx, i);
930 xfont_list (MFrame *frame, MPlist *plist, MFont *font, int maxnum)
932 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
933 MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil;
934 MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil;
935 int size = font ? font->size : 0;
938 int mdebug_mask = MDEBUG_FONT;
940 MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
941 family ? msymbol_name (family) : "*",
942 registry ? msymbol_name (registry) : "*");
944 if (registry == Mnil)
945 xfont_list_all (frame);
947 xfont_registry_list (frame, registry);
949 MPLIST_DO (pl, disp_info->font_list)
951 if (registry != Mnil && registry != MPLIST_KEY (pl))
953 MPLIST_DO (p, MPLIST_VAL (pl))
957 if (family != Mnil && family != MPLIST_KEY (p))
959 for (fontx = MPLIST_VAL (p); fontx; fontx = fontx->next)
961 || (mfont__match_p (&fontx->core, font, MFONT_REGISTRY)))
963 if (fontx->core.size == size
964 || fontx->core.size == 0)
966 mplist_push (plist, MPLIST_KEY (p), fontx);
970 || (size <= 360 && HAVE_SIZE (fontx, (size / 10))))
972 unsigned size5_36 = fontx->size5_36;
977 for (i = fontx->core.size / 10; i <= 36; i++)
978 if (size5_36 & (1 << (i - 5)))
980 MSTRUCT_CALLOC (fontx2, MERROR_WIN);
981 fontx2->core = fontx->core;
982 fontx2->core.size = i * 10;
983 fontx2->next = fontx->next;
984 fontx->next = fontx2;
986 if ((size == 0 || size == fontx->core.size)
987 && (maxnum == 0 || num < maxnum))
989 mplist_push (plist, MPLIST_KEY (p), fontx);
994 if (maxnum > 0 && maxnum == num)
997 if (maxnum > 0 && maxnum == num)
1000 if (maxnum > 0 && maxnum == num)
1004 MDEBUG_PRINT1 (" %d found\n", num);
1009 xfont_list_family_names (MFrame *frame, MPlist *plist)
1011 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
1014 MSymbol last_family = Mnil;
1016 font_names = XListFonts (disp_info->display,
1017 "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", 0x8000, &nfonts);
1018 for (i = 0; i < nfonts; i++)
1021 char foundry[256], fam[256];
1024 if (sscanf (font_names[i], "-%s-%s-", foundry, fam) < 2)
1026 family = msymbol (fam);
1027 if (family == last_family)
1029 last_family = family;
1031 MPLIST_DO (p, plist)
1033 MSymbol sym = MPLIST_SYMBOL (p);
1037 if (strcmp (MSYMBOL_NAME (sym), fam) > 0)
1039 mplist_push (p, Msymbol, family);
1043 if (MPLIST_TAIL_P (p))
1044 mplist_push (p, Msymbol, family);
1047 XFreeFontNames (font_names);
1051 xfont_check_capability (MRealizedFont *rfont, MSymbol capability)
1053 /* Currently X font driver doesn't support any capability. */
1067 XftFont *font_no_aa;
1069 /* Pointer to MRealizedFontFT */
1073 static MRealizedFont *xft_open (MFrame *frame, MFont *font, MFont *spec,
1075 static int xft_has_char (MFrame *frame, MFont *font, MFont *spec,
1076 int c, unsigned code);
1077 static unsigned xft_encode_char (MFrame *frame, MFont *font, MFont *spec,
1079 static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
1080 static void xft_render (MDrawWindow, int, int, MGlyphString *,
1081 MGlyph *, MGlyph *, int, MDrawRegion);
1082 static int xft_check_capability (MRealizedFont *rfont, MSymbol capability);
1084 static MFontDriver xft_driver =
1086 xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL, NULL,
1087 xft_check_capability
1091 close_xft (void *object)
1093 MRealizedFontXft *rfont_xft = object;
1095 if (rfont_xft->font_aa)
1096 XftFontClose (rfont_xft->display, rfont_xft->font_aa);
1097 if (rfont_xft->font_no_aa)
1098 XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
1099 M17N_OBJECT_UNREF (rfont_xft->info);
1105 xft_open_font (Display *display, MSymbol file, double size,
1111 pattern = FcPatternCreate ();
1112 FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
1113 FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
1114 FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
1115 font = XftFontOpenPattern (display, pattern);
1120 static MRealizedFont *
1121 xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
1123 Display *display = FRAME_DISPLAY (frame);
1124 int reg = spec->property[MFONT_REGISTRY];
1126 MRealizedFontXft *rfont_xft;
1127 FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
1130 int ascent, descent, max_advance, average_width, baseline_offset;
1133 /* non-scalable font */
1135 else if (spec->size)
1137 int ratio = mfont_resize_ratio (font);
1139 size = ratio == 100 ? spec->size : spec->size * ratio / 100;
1146 MRealizedFont *save = NULL;
1148 for (; rfont; rfont = rfont->next)
1149 if (rfont->font == font
1150 && (rfont->font->size ? rfont->font->size == size
1151 : rfont->spec.size == size)
1152 && rfont->spec.property[MFONT_REGISTRY] == reg)
1156 if (rfont->driver == &xft_driver)
1161 rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
1164 ascent = rfont->ascent;
1165 descent = rfont->descent;
1166 max_advance = rfont->max_advance;
1167 average_width = rfont->average_width;
1168 baseline_offset = rfont->baseline_offset;
1169 spec = &rfont->spec;
1170 ft_face = rfont->fontp;
1171 xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
1174 M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
1175 rfont_xft->display = display;
1176 if (anti_alias == FcTrue)
1177 rfont_xft->font_aa = xft_font;
1179 rfont_xft->font_no_aa = xft_font;
1180 rfont_xft->ft_face = ft_face;
1181 rfont_xft->info = rfont->info;
1182 M17N_OBJECT_REF (rfont->info);
1183 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
1184 rfont->spec = *spec;
1185 rfont->spec.size = size;
1186 rfont->frame = frame;
1188 rfont->driver = &xft_driver;
1189 rfont->info = rfont_xft;
1190 rfont->ascent = ascent;
1191 rfont->descent = descent;
1192 rfont->max_advance = max_advance;
1193 rfont->average_width = average_width;
1194 rfont->baseline_offset = baseline_offset;
1195 rfont->fontp = xft_font;
1196 rfont->next = MPLIST_VAL (frame->realized_font_list);
1197 MPLIST_VAL (frame->realized_font_list) = rfont;
1202 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1205 Display *display = FRAME_DISPLAY (rfont->frame);
1206 XftFont *xft_font = rfont->fontp;
1207 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1209 for (; g != gend; g++)
1211 if (g->code == MCHAR_INVALID_CODE)
1214 g->rbearing = xft_font->max_advance_width;
1215 g->width = g->rbearing;
1216 g->ascent = xft_font->ascent;
1217 g->descent = xft_font->descent;
1223 XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
1224 g->lbearing = - extents.x;
1225 g->rbearing = extents.width - extents.x;
1226 g->width = extents.xOff;
1227 g->ascent = extents.y;
1228 g->descent = extents.height - extents.y;
1234 xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
1238 if (font->type == MFONT_TYPE_REALIZED)
1240 MRealizedFont *rfont = (MRealizedFont *) font;
1241 MRealizedFontXft *rfont_xft = rfont->info;
1243 rfont->info = rfont_xft->info;
1244 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1245 rfont->info = rfont_xft;
1248 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1253 xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
1255 if (font->type == MFONT_TYPE_REALIZED)
1257 MRealizedFont *rfont = (MRealizedFont *) font;
1258 MRealizedFontXft *rfont_xft = rfont->info;
1260 rfont->info = rfont_xft->info;
1261 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1262 rfont->info = rfont_xft;
1265 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1270 xft_render (MDrawWindow win, int x, int y,
1271 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1272 int reverse, MDrawRegion region)
1274 MRealizedFace *rface = from->rface;
1275 MFrame *frame = rface->frame;
1276 Display *display = FRAME_DISPLAY (frame);
1277 MRealizedFont *rfont = rface->rfont;
1278 MRealizedFontXft *rfont_xft = rfont->info;
1279 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1280 XftColor *xft_color = (! reverse
1281 ? &((GCInfo *) rface->info)->xft_color_fore
1282 : &((GCInfo *) rface->info)->xft_color_back);
1283 int anti_alias = (gstring->control.anti_alias
1284 && FRAME_DEVICE (frame)->depth > 1);
1296 if (rfont_xft->font_aa)
1297 xft_font = rfont_xft->font_aa;
1300 double size = rfont->spec.size;
1302 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1305 rfont_xft->font_aa = xft_font;
1307 xft_font = rfont->fontp;
1312 if (rfont_xft->font_no_aa)
1313 xft_font = rfont_xft->font_no_aa;
1316 double size = rfont->spec.size;
1318 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1321 rfont_xft->font_no_aa = xft_font;
1323 xft_font = rfont->fontp;
1327 XftDrawChange (xft_draw, (Drawable) win);
1328 XftDrawSetClip (xft_draw, (Region) region);
1330 y -= rfont->baseline_offset;
1331 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1332 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
1334 if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
1335 glyphs[nglyphs++] = g->code;
1339 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1340 last_x, y, glyphs, nglyphs);
1342 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1343 x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
1344 last_x = x + g->width;
1348 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1352 xft_check_capability (MRealizedFont *rfont, MSymbol capability)
1354 MRealizedFontXft *rfont_xft = rfont->info;
1357 rfont->info = rfont_xft->info;
1358 result = mfont__ft_driver.check_capability (rfont, capability);
1359 rfont->info = rfont_xft;
1363 #endif /* HAVE_XFT2 */
1366 /* Functions for the device driver. */
1369 mwin__close_device (MFrame *frame)
1371 MWDevice *device = FRAME_DEVICE (frame);
1373 M17N_OBJECT_UNREF (device);
1377 mwin__device_get_prop (MFrame *frame, MSymbol key)
1379 MWDevice *device = FRAME_DEVICE (frame);
1381 if (key == Mdisplay)
1382 return (void *) device->display_info->display;
1384 return (void *) ScreenOfDisplay(device->display_info->display,
1385 device->screen_num);
1386 if (key == Mcolormap)
1387 return (void *) device->cmap;
1389 return (void *) device->depth;
1394 mwin__realize_face (MRealizedFace *rface)
1397 MSymbol foreground, background, videomode;
1398 MFaceHLineProp *hline;
1402 if (rface != rface->ascii_rface)
1404 rface->info = rface->ascii_rface->info;
1408 frame = rface->frame;
1409 MSTRUCT_CALLOC (info, MERROR_WIN);
1411 foreground = rface->face.property[MFACE_FOREGROUND];
1412 background = rface->face.property[MFACE_BACKGROUND];
1413 videomode = rface->face.property[MFACE_VIDEOMODE];
1415 videomode = frame->videomode;
1416 if (videomode != Mreverse)
1418 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1419 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1423 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1424 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1427 if (foreground == Mnil)
1428 foreground = frame->foreground;
1429 if (background == Mnil)
1430 background = frame->background;
1431 if (videomode == Mreverse)
1433 MSymbol temp = foreground;
1434 foreground = background;
1437 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1438 FRAME_VISUAL (frame),
1440 MSYMBOL_NAME (foreground),
1441 &info->xft_color_fore))
1443 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1444 FRAME_VISUAL (frame),
1446 MSYMBOL_NAME (background),
1447 &info->xft_color_back))
1449 #endif /* HAVE_XFT2 */
1451 hline = rface->hline;
1455 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1457 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1464 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1466 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1468 if (box->color_left && box->color_left != box->color_top)
1469 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1471 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1473 if (box->color_bottom && box->color_bottom != box->color_top)
1474 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1476 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1478 if (box->color_right && box->color_right != box->color_bottom)
1479 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1481 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1489 mwin__free_realized_face (MRealizedFace *rface)
1491 if (rface == rface->ascii_rface)
1497 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1499 int x, int y, int width, int height, MDrawRegion region)
1501 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1504 gc = set_region (frame, gc, region);
1506 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1507 x, y, width, height);
1512 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1513 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1514 int reverse, MDrawRegion region)
1516 MRealizedFace *rface = from->rface;
1517 Display *display = FRAME_DISPLAY (rface->frame);
1518 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1524 gc = set_region (rface->frame, gc, region);
1525 for (; from < to; from++)
1527 XDrawRectangle (display, (Window) win, gc,
1528 x, y - gstring->ascent + 1, from->width - 1,
1529 gstring->ascent + gstring->descent - 2);
1536 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1537 MRealizedFace *rface, int reverse,
1538 int x, int y, int width, MDrawRegion region)
1540 enum MFaceHLineType type = rface->hline->type;
1541 GCInfo *info = rface->info;
1542 GC gc = gc = info->gc[GC_HLINE];
1545 y = (type == MFACE_HLINE_BOTTOM
1546 ? y + gstring->text_descent - rface->hline->width
1547 : type == MFACE_HLINE_UNDER
1549 : type == MFACE_HLINE_STRIKE_THROUGH
1550 ? y - ((gstring->ascent + gstring->descent) / 2)
1551 : y - gstring->text_ascent);
1553 gc = set_region (frame, gc, region);
1555 for (i = 0; i < rface->hline->width; i++)
1556 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1557 x, y + i, x + width - 1, y + i);
1562 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1563 MGlyph *g, int x, int y, int width, MDrawRegion region)
1565 Display *display = FRAME_DISPLAY (frame);
1566 MRealizedFace *rface = g->rface;
1567 MFaceBoxProp *box = rface->box;
1568 GCInfo *info = rface->info;
1569 GC gc_top, gc_left, gc_right, gc_btm;
1573 y0 = y - (gstring->text_ascent
1574 + rface->box->inner_vmargin + rface->box->width);
1575 y1 = y + (gstring->text_descent
1576 + rface->box->inner_vmargin + rface->box->width - 1);
1578 gc_top = info->gc[GC_BOX_TOP];
1580 gc_top = set_region (frame, gc_top, region);
1581 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1584 gc_btm = info->gc[GC_BOX_BOTTOM];
1586 if (g->type == GLYPH_BOX)
1590 if (g->left_padding)
1591 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1593 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1595 /* Draw the top side. */
1596 for (i = 0; i < box->width; i++)
1597 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1599 /* Draw the bottom side. */
1600 if (region && gc_btm != gc_top)
1601 gc_btm = set_region (frame, gc_btm, region);
1602 for (i = 0; i < box->width; i++)
1603 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1605 if (g->left_padding > 0)
1607 /* Draw the left side. */
1608 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1612 gc_left = info->gc[GC_BOX_LEFT];
1614 gc_left = set_region (frame, gc_left, region);
1616 for (i = 0; i < rface->box->width; i++)
1617 XDrawLine (display, (Window) win, gc_left,
1618 x0 + i, y0 + i, x0 + i, y1 - i);
1622 /* Draw the right side. */
1623 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1627 gc_right = info->gc[GC_BOX_RIGHT];
1629 gc_right = set_region (frame, gc_right, region);
1631 for (i = 0; i < rface->box->width; i++)
1632 XDrawLine (display, (Window) win, gc_right,
1633 x1 - i, y0 + i, x1 - i, y1 - i);
1638 /* Draw the top side. */
1639 for (i = 0; i < box->width; i++)
1640 XDrawLine (display, (Window) win, gc_top,
1641 x, y0 + i, x + width - 1, y0 + i);
1643 /* Draw the bottom side. */
1644 if (region && gc_btm != gc_top)
1645 gc_btm = set_region (frame, gc_btm, region);
1646 for (i = 0; i < box->width; i++)
1647 XDrawLine (display, (Window) win, gc_btm,
1648 x, y1 - i, x + width - 1, y1 - i);
1655 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1656 int reverse, int x, int y,
1657 int width, int height, int row_bytes, unsigned char *bmp,
1660 Display *display = FRAME_DISPLAY (frame);
1662 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1665 gc = set_region (frame, gc, region);
1667 for (i = 0; i < height; i++, bmp += row_bytes)
1668 for (j = 0; j < width; j++)
1669 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1670 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1675 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1676 int intensity, MDrawPoint *points, int num,
1679 GCInfo *info = rface->info;
1682 if (! (gc = info->gc[intensity]))
1683 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1686 gc = set_region (frame, gc, region);
1688 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1689 (XPoint *) points, num, CoordModeOrigin);
1694 mwin__region_from_rect (MDrawMetric *rect)
1696 MDrawRegion region1 = XCreateRegion ();
1697 MDrawRegion region2 = XCreateRegion ();
1702 xrect.width = rect->width;
1703 xrect.height = rect->height;
1704 XUnionRectWithRegion (&xrect, region1, region2);
1705 XDestroyRegion (region1);
1710 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1712 MDrawRegion region1 = XCreateRegion ();
1717 xrect.width = rect->width;
1718 xrect.height = rect->height;
1720 XUnionRegion (region, region, region1);
1721 XUnionRectWithRegion (&xrect, region1, region);
1722 XDestroyRegion (region1);
1726 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1728 MDrawRegion region = XCreateRegion ();
1730 XUnionRegion (region1, region1, region);
1731 XIntersectRegion (region, region2, region1);
1732 XDestroyRegion (region);
1736 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1738 MDrawRegion region1 = XCreateRegion ();
1743 xrect.width = rect->width;
1744 xrect.height = rect->height;
1745 XUnionRectWithRegion (&xrect, region1, region);
1746 XDestroyRegion (region1);
1750 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1754 XClipBox (region, &xrect);
1757 rect->width = xrect.width;
1758 rect->height = xrect.height;
1762 mwin__free_region (MDrawRegion region)
1764 XDestroyRegion (region);
1768 mwin__dump_region (MDrawRegion region)
1771 XClipBox (region, &rect);
1772 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1777 mwin__create_window (MFrame *frame, MDrawWindow parent)
1779 Display *display = FRAME_DISPLAY (frame);
1781 XWMHints wm_hints = { InputHint, False };
1782 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1783 XSetWindowAttributes set_attrs;
1786 GCInfo *info = frame->rface->info;
1789 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1790 mask = GCForeground;
1791 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1792 set_attrs.background_pixel = values.foreground;
1793 set_attrs.backing_store = Always;
1794 set_attrs.override_redirect = True;
1795 set_attrs.save_under = True;
1796 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1797 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1798 CopyFromParent, InputOutput, CopyFromParent,
1800 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1801 NULL, &wm_hints, &class_hints);
1802 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1803 return (MDrawWindow) win;
1807 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1810 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1812 if (XftDrawDrawable (xft_draw) == (Drawable) win)
1813 XftDrawChange (xft_draw, FRAME_DEVICE (frame)->drawable);
1814 #endif /* HAVE_XFT2 */
1815 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1820 mwin__event_window (void *event)
1822 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1826 mwin__print_event (void *arg, char *win_name)
1829 XEvent *event = (XEvent *) arg;
1831 switch (event->xany.type)
1833 case 2: event_name = "KeyPress"; break;
1834 case 3: event_name = "KeyRelease"; break;
1835 case 4: event_name = "ButtonPress"; break;
1836 case 5: event_name = "ButtonRelease"; break;
1837 case 6: event_name = "MotionNotify"; break;
1838 case 7: event_name = "EnterNotify"; break;
1839 case 8: event_name = "LeaveNotify"; break;
1840 case 9: event_name = "FocusIn"; break;
1841 case 10: event_name = "FocusOut"; break;
1842 case 11: event_name = "KeymapNotify"; break;
1843 case 12: event_name = "Expose"; break;
1844 case 13: event_name = "GraphicsExpose"; break;
1845 case 14: event_name = "NoExpose"; break;
1846 case 15: event_name = "VisibilityNotify"; break;
1847 case 16: event_name = "CreateNotify"; break;
1848 case 17: event_name = "DestroyNotify"; break;
1849 case 18: event_name = "UnmapNotify"; break;
1850 case 19: event_name = "MapNotify"; break;
1851 case 20: event_name = "MapRequest"; break;
1852 case 21: event_name = "ReparentNotify"; break;
1853 case 22: event_name = "ConfigureNotify"; break;
1854 case 23: event_name = "ConfigureRequest"; break;
1855 case 24: event_name = "GravityNotify"; break;
1856 case 25: event_name = "ResizeRequest"; break;
1857 case 26: event_name = "CirculateNotify"; break;
1858 case 27: event_name = "CirculateRequest"; break;
1859 case 28: event_name = "PropertyNotify"; break;
1860 case 29: event_name = "SelectionClear"; break;
1861 case 30: event_name = "SelectionRequest"; break;
1862 case 31: event_name = "SelectionNotify"; break;
1863 case 32: event_name = "ColormapNotify"; break;
1864 case 33: event_name = "ClientMessage"; break;
1865 case 34: event_name = "MappingNotify"; break;
1866 default: event_name = "unknown";
1869 fprintf (stderr, "%s: %s\n", win_name, event_name);
1874 mwin__map_window (MFrame *frame, MDrawWindow win)
1876 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1880 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1882 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1886 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1887 MDrawMetric *geometry)
1889 Display *display = FRAME_DISPLAY (frame);
1890 XWindowAttributes attr;
1891 Window parent = (Window) parent_win, root;
1893 XGetWindowAttributes (display, (Window) win, &attr);
1894 geometry->x = attr.x + attr.border_width;
1895 geometry->y = attr.y + attr.border_width;
1896 geometry->width = attr.width;
1897 geometry->height = attr.height;
1900 parent = RootWindow (display, FRAME_SCREEN (frame));
1903 Window this_parent, *children;
1906 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1909 if (this_parent == parent || this_parent == root)
1911 win = (MDrawWindow) this_parent;
1912 XGetWindowAttributes (display, (Window) win, &attr);
1913 geometry->x += attr.x + attr.border_width;
1914 geometry->y += attr.y + attr.border_width;
1919 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1920 MDrawMetric *current, MDrawMetric *new)
1922 Display *display = FRAME_DISPLAY (frame);
1923 unsigned int mask = 0;
1924 XWindowChanges values;
1926 if (current->width != new->width)
1929 if (new->width <= 0)
1931 values.width = current->width = new->width;
1933 if (current->height != new->height)
1936 if (new->height <= 0)
1938 values.height = current->height = new->height;
1940 if (current->x != new->x)
1943 values.x = current->x = new->x;
1945 if (current->y != new->y)
1948 current->y = new->y;
1949 values.y = current->y = new->y;
1952 XConfigureWindow (display, (Window) win, mask, &values);
1953 XClearWindow (display, (Window) win);
1957 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1959 XEvent *event = (XEvent *) arg;
1960 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
1967 if (event->xany.type != KeyPress
1968 /* && event->xany.type != KeyRelease */
1971 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
1978 if (c < XK_space || c > XK_asciitilde)
1980 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
1981 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1982 if (((XKeyEvent *) event)->state & ControlMask)
1984 if (c >= 'a' && c <= 'z')
1986 if (c >= ' ' && c < 127)
1987 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1989 key = minput__char_to_key (c);
1991 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
1995 char *str = XKeysymToString (keysym);
1999 key = msymbol (str);
2000 if (((XKeyEvent *) event)->state & ShiftMask)
2001 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2002 if (((XKeyEvent *) event)->state & ControlMask)
2003 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2005 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
2006 *modifiers |= MINPUT_KEY_META_MODIFIER;
2007 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
2008 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
2009 if (((XKeyEvent *) event)->state & disp_info->super_mask)
2010 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
2011 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
2012 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
2019 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
2021 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
2023 Display *display = FRAME_DISPLAY (frame);
2024 GCInfo *info = rface->info;
2027 for (i = 0; i <= GC_INVERSE; i++)
2029 XGetGCValues (display, info->gc[i], valuemask, &values);
2030 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
2031 values.foreground, values.background);
2032 fprintf (stderr, "\n");
2036 static MDeviceDriver x_driver =
2039 mwin__device_get_prop,
2041 mwin__free_realized_face,
2043 mwin__draw_empty_boxes,
2047 mwin__region_from_rect,
2048 mwin__union_rect_with_region,
2049 mwin__intersect_region,
2050 mwin__region_add_rect,
2051 mwin__region_to_rect,
2054 mwin__create_window,
2055 mwin__destroy_window,
2058 mwin__window_geometry,
2059 mwin__adjust_window,
2063 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
2068 M_iso8859_1 = msymbol ("iso8859-1");
2069 M_iso10646_1 = msymbol ("iso10646-1");
2071 display_info_list = mplist ();
2072 device_list = mplist ();
2075 xft_driver.select = mfont__ft_driver.select;
2076 xft_driver.list = mfont__ft_driver.list;
2077 xft_driver.list_family_names = mfont__ft_driver.list_family_names;
2080 Mxim = msymbol ("xim");
2081 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
2089 M17N_OBJECT_UNREF (display_info_list);
2090 M17N_OBJECT_UNREF (device_list);
2095 #ifdef X_SET_ERROR_HANDLER
2097 x_error_handler (Display *display, XErrorEvent *error)
2104 x_io_error_handler (Display *display)
2111 /** Return an MWDevice object corresponding to a display specified in
2114 It searches device_list for a device matching the display. If
2115 found, return the found object. Otherwise, return a newly created
2119 device_open (MFrame *frame, MPlist *param)
2121 Display *display = NULL;
2122 Screen *screen = NULL;
2124 Drawable drawable = 0;
2125 Widget widget = NULL;
2127 int auto_display = 0;
2128 MDisplayInfo *disp_info = NULL;
2129 MWDevice *device = NULL;
2131 XWindowAttributes attr;
2137 int use_xfont = 0, use_freetype = 0, use_xft = 0;
2139 for (plist = param; (key = mplist_key (plist)) != Mnil;
2140 plist = mplist_next (plist))
2142 if (key == Mdisplay)
2143 display = (Display *) mplist_value (plist);
2144 else if (key == Mscreen)
2145 screen = mplist_value (plist);
2146 else if (key == Mdrawable)
2147 drawable = (Drawable) mplist_value (plist);
2148 else if (key == Mdepth)
2149 depth = (unsigned) mplist_value (plist);
2150 else if (key == Mwidget)
2151 widget = (Widget) mplist_value (plist);
2152 else if (key == Mcolormap)
2153 cmap = (Colormap) mplist_value (plist);
2154 else if (key == Mfont)
2156 MSymbol val = MPLIST_SYMBOL (plist);
2160 #ifdef HAVE_FREETYPE
2161 else if (val == Mfreetype)
2164 else if (val == Mxft)
2171 /* If none of them is specified, use all of them. */
2172 if (! use_xfont && ! use_freetype && ! use_xft)
2173 use_xfont = use_freetype = use_xft = 1;
2177 display = XtDisplay (widget);
2178 screen_num = XScreenNumberOfScreen (XtScreen (widget));
2179 depth = DefaultDepth (display, screen_num);
2185 unsigned width, height, border_width;
2188 MERROR (MERROR_WIN, -1);
2189 XGetGeometry (display, drawable, &root_window,
2190 &x, &y, &width, &height, &border_width, &depth);
2191 XGetWindowAttributes (display, root_window, &attr);
2192 screen_num = XScreenNumberOfScreen (attr.screen);
2197 display = DisplayOfScreen (screen);
2202 display = XOpenDisplay (NULL);
2204 MERROR (MERROR_WIN, -1);
2207 screen = DefaultScreenOfDisplay (display);
2209 screen_num = XScreenNumberOfScreen (screen);
2211 depth = DefaultDepth (display, screen_num);
2215 cmap = DefaultColormap (display, screen_num);
2217 for (plist = display_info_list; mplist_key (plist) != Mnil;
2218 plist = mplist_next (plist))
2220 disp_info = (MDisplayInfo *) mplist_value (plist);
2221 if (disp_info->display == display)
2225 if (mplist_key (plist) != Mnil)
2226 M17N_OBJECT_REF (disp_info);
2229 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2230 disp_info->display = display;
2231 disp_info->auto_display = auto_display;
2232 disp_info->font_list = mplist ();
2233 find_modifier_bits (disp_info);
2234 disp_info->MULE_BASELINE_OFFSET
2235 = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
2236 disp_info->AVERAGE_WIDTH
2237 = XInternAtom (display, "AVERAGE_WIDTH", False);
2238 mplist_add (display_info_list, Mt, disp_info);
2241 for (plist = device_list; mplist_key (plist) != Mnil;
2242 plist = mplist_next (plist))
2244 device = (MWDevice *) mplist_value (plist);
2245 if (device->display_info == disp_info
2246 && device->depth == depth
2247 && device->cmap == cmap
2248 && device->screen_num == screen_num)
2252 if (mplist_key (plist) != Mnil)
2253 M17N_OBJECT_REF (device);
2256 unsigned long valuemask = GCForeground;
2260 M17N_OBJECT (device, free_device, MERROR_WIN);
2261 device->display_info = disp_info;
2262 device->screen_num = screen_num;
2263 /* A drawable on which to create GCs. */
2264 device->drawable = XCreatePixmap (display,
2265 RootWindow (display, screen_num),
2267 device->depth = depth;
2268 device->cmap = cmap;
2269 pixels = DisplayHeight (display, screen_num);
2270 mm = DisplayHeightMM (display, screen_num);
2271 device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
2272 device->realized_face_list = mplist ();
2273 device->realized_font_list = mplist ();
2274 mplist_add (device->realized_font_list, Mt, NULL);
2275 device->realized_fontset_list = mplist ();
2276 device->gc_list = mplist ();
2277 values.foreground = BlackPixel (display, screen_num);
2278 device->scratch_gc = XCreateGC (display, device->drawable,
2279 valuemask, &values);
2281 device->xft_draw = XftDrawCreate (display, device->drawable,
2282 DefaultVisual (display, screen_num),
2287 frame->device = device;
2288 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2289 frame->dpi = device->resy;
2290 frame->driver = &x_driver;
2291 frame->font_driver_list = mplist ();
2295 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2298 #endif /* HAVE_XFT2 */
2299 #ifdef HAVE_FREETYPE
2301 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2302 #endif /* HAVE_FREETYPE */
2303 if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
2304 mplist_push (frame->font_driver_list, Mx, &xfont_driver);
2306 frame->realized_font_list = device->realized_font_list;
2307 frame->realized_face_list = device->realized_face_list;
2308 frame->realized_fontset_list = device->realized_fontset_list;
2312 XtResource resources[] = {
2313 { XtNfont, XtCFont, XtRString, sizeof (String),
2314 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2315 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2316 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2317 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2318 XtOffset (AppDataPtr, background), XtRString, "white" },
2319 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2320 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2323 XtGetApplicationResources (widget, &app_data,
2324 resources, XtNumber (resources), NULL, 0);
2325 frame->foreground = msymbol (app_data.foreground);
2326 frame->background = msymbol (app_data.background);
2327 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2331 app_data.font = DEFAULT_FONT;
2332 frame->foreground = msymbol ("black");
2333 frame->background = msymbol ("white");
2334 frame->videomode = Mnormal;
2337 if (strcmp (app_data.font, DEFAULT_FONT) != 0)
2339 XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
2340 unsigned long value;
2345 font = mfont_parse_name (app_data.font, Mx);
2347 && XGetFontProperty (xfont, XA_FONT, &value)
2348 && (name = ((char *) XGetAtomName (display, (Atom) value))))
2349 font = mfont_parse_name (name, Mx);
2350 XFreeFont (display, xfont);
2354 font = mfont_parse_name (DEFAULT_FONT, Mx);
2355 else if (! font->size)
2357 face = mface_from_font (font);
2359 face->property[MFACE_FONTSET] = mfontset (NULL);
2360 face->property[MFACE_FOREGROUND] = frame->foreground;
2361 face->property[MFACE_BACKGROUND] = frame->background;
2362 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2363 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2364 face->property[MFACE_VIDEOMODE] = frame->videomode;
2365 mface_put_prop (face, Mhook_func,
2366 mface_get_prop (mface__default, Mhook_func));
2367 face->property[MFACE_RATIO] = (void *) 100;
2368 mplist_push (param, Mface, face);
2369 M17N_OBJECT_UNREF (face);
2371 #ifdef X_SET_ERROR_HANDLER
2372 XSetErrorHandler (x_error_handler);
2373 XSetIOErrorHandler (x_io_error_handler);
2380 /* XIM (X Input Method) handler */
2382 typedef struct MInputXIMMethodInfo
2388 } MInputXIMMethodInfo;
2390 typedef struct MInputXIMContextInfo
2394 MConverter *converter;
2395 } MInputXIMContextInfo;
2398 xim_open_im (MInputMethod *im)
2400 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
2401 MLocale *saved, *this;
2402 char *save_modifier_list;
2404 MInputXIMMethodInfo *im_info;
2406 saved = mlocale_set (LC_CTYPE, NULL);
2407 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
2409 /* The specified locale is not supported. */
2410 MERROR (MERROR_LOCALE, -1);
2411 if (mlocale_get_prop (this, Mcoding) == Mnil)
2413 /* Unable to decode the output of XIM. */
2414 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2415 MERROR (MERROR_LOCALE, -1);
2418 if (arg->modifier_list)
2419 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
2421 save_modifier_list = XSetLocaleModifiers ("");
2422 if (! save_modifier_list)
2424 /* The specified locale is not supported by X. */
2425 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2426 MERROR (MERROR_LOCALE, -1);
2429 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
2432 /* No input method is available in the current locale. */
2433 XSetLocaleModifiers (save_modifier_list);
2434 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2435 MERROR (MERROR_WIN, -1);
2438 MSTRUCT_MALLOC (im_info, MERROR_WIN);
2439 im_info->display = arg->display;
2441 im_info->language = mlocale_get_prop (this, Mlanguage);
2442 im_info->coding = mlocale_get_prop (this, Mcoding);
2445 XSetLocaleModifiers (save_modifier_list);
2446 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2452 xim_close_im (MInputMethod *im)
2454 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
2456 XCloseIM (im_info->xim);
2461 xim_create_ic (MInputContext *ic)
2463 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
2464 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2465 MInputXIMContextInfo *ic_info;
2468 if (! arg->input_style)
2470 /* By default, use Root style. */
2471 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
2472 arg->preedit_attrs = NULL;
2473 arg->status_attrs = NULL;
2476 if (! arg->preedit_attrs && ! arg->status_attrs)
2477 xic = XCreateIC (im_info->xim,
2478 XNInputStyle, arg->input_style,
2479 XNClientWindow, arg->client_win,
2480 XNFocusWindow, arg->focus_win,
2482 else if (arg->preedit_attrs && ! arg->status_attrs)
2483 xic = XCreateIC (im_info->xim,
2484 XNInputStyle, arg->input_style,
2485 XNClientWindow, arg->client_win,
2486 XNFocusWindow, arg->focus_win,
2487 XNPreeditAttributes, arg->preedit_attrs,
2489 else if (! arg->preedit_attrs && arg->status_attrs)
2490 xic = XCreateIC (im_info->xim,
2491 XNInputStyle, arg->input_style,
2492 XNClientWindow, arg->client_win,
2493 XNFocusWindow, arg->focus_win,
2494 XNStatusAttributes, arg->status_attrs,
2497 xic = XCreateIC (im_info->xim,
2498 XNInputStyle, arg->input_style,
2499 XNClientWindow, arg->client_win,
2500 XNFocusWindow, arg->focus_win,
2501 XNPreeditAttributes, arg->preedit_attrs,
2502 XNStatusAttributes, arg->status_attrs,
2505 MERROR (MERROR_WIN, -1);
2507 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
2509 ic_info->win = arg->focus_win;
2510 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
2516 xim_destroy_ic (MInputContext *ic)
2518 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2520 XDestroyIC (ic_info->xic);
2521 mconv_free_converter (ic_info->converter);
2527 xim_filter (MInputContext *ic, MSymbol key, void *event)
2529 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2531 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
2536 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2538 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2539 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2540 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
2546 buf = (char *) alloca (512);
2547 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
2548 if (status == XBufferOverflow)
2550 buf = (char *) alloca (len);
2551 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
2554 mtext_reset (ic->produced);
2558 mconv_reset_converter (ic_info->converter);
2559 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
2560 mconv_decode (ic_info->converter, ic->produced);
2561 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2562 Mlanguage, (void *) im_info->language);
2563 mtext_cpy (mt, ic->produced);
2564 mtext_reset (ic->produced);
2572 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2576 /*** @addtogroup m17nInputMethodWin */
2581 @brief Input method driver for XIM.
2583 The driver #minput_xim_driver is for the foreign input method of
2584 name #Mxim. It uses XIM (X Input Methods) as a background input
2587 As the symbol #Mxim has property #Minput_driver whose value is
2588 a pointer to this driver, the input method of language #Mnil
2589 and name #Mxim uses this driver.
2591 Therefore, for such input methods, the driver dependent arguments
2592 to the functions whose name begin with minput_ must be as follows.
2594 The argument $ARG of the function minput_open_im () must be a
2595 pointer to the structure #MInputXIMArgIM. See the documentation
2596 of #MInputXIMArgIM for more details.
2598 The argument $ARG of the function minput_create_ic () must be a
2599 pointer to the structure #MInputXIMArgIC. See the documentation
2600 of #MInputXIMArgIC for more details.
2602 The argument $ARG of the function minput_filter () must be a
2603 pointer to the structure @c XEvent. The argument $KEY is ignored.
2605 The argument $ARG of the function minput_lookup () must be the
2606 same one as that of the function minput_filter (). The argument
2610 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2612 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
2613 XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2615 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2616 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
2617 ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2619 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
2620 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2622 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
2623 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
2625 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
2626 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
2628 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
2629 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2631 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2632 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
2634 MInputDriver minput_xim_driver =
2635 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2636 xim_filter, xim_lookup, NULL };
2640 #else /* not HAVE_X11 */
2642 int device_open () { return -1; }
2644 #endif /* not HAVE_X11 */