1 /* m17n-X.c -- implementation of the GUI API on X Windows.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
28 /*** @addtogroup m17nInternal
38 #include <X11/keysym.h>
39 #include <X11/Xlocale.h>
40 #include <X11/Xutil.h>
41 #include <X11/Xresource.h>
42 #include <X11/Xatom.h>
43 #include <X11/StringDefs.h>
44 #include <X11/Intrinsic.h>
47 #include <X11/Xft/Xft.h>
48 #include <fontconfig/fcfreetype.h>
49 #endif /* HAVE_XFT2 */
53 #include "m17n-misc.h"
55 #include "internal-gui.h"
64 /* Common header for the m17n object. */
69 /* If nonzero, <display> is opened by this library. Thus it should
70 be closed on freeing this structure. */
73 /** List of available X-core fonts on the display. Keys are
74 registries and values are plists whose keys are families and
75 values are pointers to MFont. */
78 /** Nonzero means that <font_list> already contains all available
79 fonts on the display. */
82 /** Modifier bit masks of the display. */
89 Atom MULE_BASELINE_OFFSET;
93 /* Anchor of the chain of MDisplayInfo objects. */
94 static MPlist *display_info_list;
97 /* Color value and the corresponding GC. */
100 unsigned int rgb; /* (red << 16) | (green << 8) | blue */
107 GC_NORMAL = GC_INVERSE + 7,
120 /* The first 8 elements are indexed by an intensity for
121 anti-aliasing. The 2nd to 7th are created on demand. */
124 XftColor xft_color_fore, xft_color_back;
130 /* Common header for the m17n object. */
133 MDisplayInfo *display_info;
151 /** List of pointers to realized faces on the frame. */
152 MPlist *realized_face_list;
154 /* List of single element whose value is a root of chain of realized
156 MPlist *realized_font_list;
158 /** List of pointers to realized fontsets on the frame. */
159 MPlist *realized_fontset_list;
161 /** List of XColors vs GCs on the frame. */
165 static MPlist *device_list;
167 static MSymbol M_iso8859_1, M_iso10646_1;
169 #define FRAME_DEVICE(frame) ((MWDevice *) (frame)->device)
170 #define FRAME_DISPLAY(frame) (FRAME_DEVICE (frame)->display_info->display)
171 #define FRAME_SCREEN(frame) (FRAME_DEVICE (frame)->screen_num)
172 #define FRAME_CMAP(frame) (FRAME_DEVICE (frame)->cmap)
173 #define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
174 FRAME_SCREEN (frame))
176 #define DEFAULT_FONT "-*-*-medium-r-normal--13-*-*-*-c-*-iso8859-1"
183 Boolean reverse_video;
184 } AppData, *AppDataPtr;
187 free_display_info (void *object)
189 MDisplayInfo *disp_info = (MDisplayInfo *) object;
192 MPLIST_DO (plist, disp_info->font_list)
194 MPLIST_DO (pl, MPLIST_VAL (plist))
195 free (MPLIST_VAL (pl));
196 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
198 M17N_OBJECT_UNREF (disp_info->font_list);
200 if (disp_info->auto_display)
201 XCloseDisplay (disp_info->display);
207 free_device (void *object)
209 MWDevice *device = object;
212 for (plist = device->realized_fontset_list;
213 mplist_key (plist) != Mnil; plist = mplist_next (plist))
214 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
215 M17N_OBJECT_UNREF (device->realized_fontset_list);
217 if (MPLIST_VAL (device->realized_font_list))
218 mfont__free_realized (MPLIST_VAL (device->realized_font_list));
219 M17N_OBJECT_UNREF (device->realized_font_list);
221 MPLIST_DO (plist, device->realized_face_list)
223 MRealizedFace *rface = MPLIST_VAL (plist);
226 mface__free_realized (rface);
228 M17N_OBJECT_UNREF (device->realized_face_list);
230 MPLIST_DO (plist, device->gc_list)
232 XFreeGC (device->display_info->display,
233 ((RGB_GC *) MPLIST_VAL (plist))->gc);
234 free (MPLIST_VAL (plist));
236 M17N_OBJECT_UNREF (device->gc_list);
237 XFreeGC (device->display_info->display, device->scratch_gc);
240 XftDrawDestroy (device->xft_draw);
243 XFreePixmap (device->display_info->display, device->drawable);
244 M17N_OBJECT_UNREF (device->display_info);
250 find_modifier_bits (MDisplayInfo *disp_info)
252 Display *display = disp_info->display;
253 XModifierKeymap *mods;
254 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
255 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
256 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
257 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
258 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
259 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
260 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
261 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
263 KeyCode altgr = XKeysymToKeycode (display, XK_ISO_Level3_Shift);
267 mods = XGetModifierMapping (display);
268 /* We skip the first three sets for Shift, Lock, and Control. The
269 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
270 for (i = 3; i < 8; i++)
271 for (j = 0; j < mods->max_keypermod; j++)
273 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
277 if (code == meta_l || code == meta_r)
278 disp_info->meta_mask |= (1 << i);
279 else if (code == alt_l || code == alt_r)
280 disp_info->alt_mask |= (1 << i);
281 else if (code == super_l || code == super_r)
282 disp_info->super_mask |= (1 << i);
283 else if (code == hyper_l || code == hyper_r)
284 disp_info->hyper_mask |= (1 << i);
286 else if (code == altgr)
287 disp_info->altgr_mask |= (1 << i);
291 /* If meta keys are not in any modifier, use alt keys as meta
293 if (! disp_info->meta_mask)
295 disp_info->meta_mask = disp_info->alt_mask;
296 disp_info->alt_mask = 0;
298 /* If both meta and alt are assigned to the same modifier, give meta
300 if (disp_info->meta_mask & disp_info->alt_mask)
301 disp_info->alt_mask &= ~disp_info->meta_mask;
303 XFreeModifiermap (mods);
307 get_rgb_gc (MWDevice *device, XColor *xcolor)
309 int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
310 | (xcolor->blue >> 8));
313 unsigned long valuemask = GCForeground;
316 MPLIST_DO (plist, device->gc_list)
318 rgb_gc = MPLIST_VAL (plist);
320 if (rgb_gc->rgb == rgb)
322 if (rgb_gc->rgb > rgb)
326 if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
329 rgb_gc = malloc (sizeof (RGB_GC));
331 values.foreground = xcolor->pixel;
332 rgb_gc->gc = XCreateGC (device->display_info->display,
333 device->drawable, valuemask, &values);
334 mplist_push (plist, Mt, rgb_gc);
339 get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
341 MWDevice *device = FRAME_DEVICE (frame);
349 color = for_foreground ? frame->foreground : frame->background;
351 if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
352 msymbol_name (color), &xcolor))
354 rgb_gc = get_rgb_gc (device, &xcolor);
358 *rgb_ret = rgb_gc->rgb;
363 GCInfo *info = frame->rface->info;
368 rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
370 rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
378 get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
380 int rgb_fore, rgb_back;
385 if (info->gc[intensity])
386 return info->gc[intensity];
388 rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
389 xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
390 + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
391 xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
392 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
393 xcolor.blue = (((rgb_fore & 0xFF) * intensity
394 + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
395 rgb_gc = get_rgb_gc (device, &xcolor);
399 gc =get_gc_for_anti_alias (device, info,
400 intensity < 4 ? intensity - 1 : intensity + 1);
401 return (info->gc[intensity] = gc);
405 set_region (MFrame *frame, GC gc, MDrawRegion region)
407 unsigned long valuemask = GCForeground;
409 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
410 FRAME_DEVICE (frame)->scratch_gc);
411 XSetRegion (FRAME_DISPLAY (frame), FRAME_DEVICE (frame)->scratch_gc, region);
412 return FRAME_DEVICE (frame)->scratch_gc;
416 /** X font handler */
418 static MFont *xfont_select (MFrame *, MFont *, int);
419 static MRealizedFont *xfont_open (MFrame *, MFont *, MFont *, MRealizedFont *);
420 static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
421 static int xfont_has_char (MFrame *, MFont *, MFont *, int, unsigned);
422 static unsigned xfont_encode_char (MFrame *, MFont *, MFont *, unsigned);
423 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
424 MGlyph *, MGlyph *, int, MDrawRegion);
425 static int xfont_list (MFrame *, MPlist *, MFont *, int);
426 static void xfont_list_family_names (MFrame *, MPlist *);
427 static int xfont_check_capability (MRealizedFont *rfont, MSymbol capability);
429 static MFontDriver xfont_driver =
430 { xfont_select, xfont_open,
431 xfont_find_metric, xfont_has_char, xfont_encode_char,
432 xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability
436 font_compare (const void *p1, const void *p2)
438 return strcmp (*(char **) p1, *(char **) p2);
442 xfont_registry_list (MFrame *frame, MSymbol registry)
444 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
445 MPlist *font_list = disp_info->font_list;
448 char **font_names, **names;
454 plist = mplist_get (font_list, registry);
457 p = plist = mplist ();
458 mplist_add (font_list, registry, plist);
459 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", msymbol_name (registry));
460 font_names = XListFonts (disp_info->display, pattern, 0x8000, &nfonts);
464 char *reg_name = msymbol_name (registry);
466 for_full_width = (strncmp (reg_name, "jis", 3) == 0
467 || strncmp (reg_name, "gb", 2) == 0
468 || strncmp (reg_name, "big5", 4) == 0
469 || strncmp (reg_name, "ksc", 3) == 0);
471 names = alloca (sizeof (char *) * nfonts);
472 memcpy (names, font_names, sizeof (char *) * nfonts);
473 qsort (names, nfonts, sizeof (char *), font_compare);
475 for (i = 0; i < nfonts; i++)
476 if (mfont__parse_name_into_font (names[i], Mx, &font) == 0
477 && (font.size > 0 || font.property[MFONT_RESY] == 0))
479 MSymbol family = FONT_PROPERTY (&font, MFONT_FAMILY);
484 int size, normal_size;
489 /* Calculate how many bytes to compare to detect fonts of the
491 for (base_end = names[i], fields = 0; *base_end; base_end++)
493 && ++fields == 7 /* PIXEL_SIZE */)
495 base_len = base_end - names[i] + 1;
497 size = font.size / 10;
498 sizes[nsizes++] = size;
499 normal_size = (size >= 6 && size <= 29);
500 limit = (i + 256 < nfonts ? i + 256 : nfonts);
501 for (j = i + 1; j < limit && ! memcmp (names[i], names[j], base_len);
503 if (mfont__parse_name_into_font (names[j], Mx, &font) == 0
504 && (font.size > 0 || font.property[MFONT_RESY] == 0))
506 size = font.size / 10;
507 sizes[nsizes++] = size;
508 normal_size |= (size >= 6 && size <= 29);
511 font.for_full_width = for_full_width;
512 font.type = MFONT_TYPE_OBJECT;
513 font.source = MFONT_SOURCE_X;
516 MSTRUCT_CALLOC (fontx, MERROR_WIN);
518 fontx->multiple_sizes = 1;
520 for (j = 0; j < nsizes; j++)
521 if (sizes[j] >= 6 && sizes[j] <= 29)
522 fontx->size |= 1 << (sizes[j] - 6);
523 p = mplist_add (p, family, fontx);
525 for (j = 0; j < nsizes; j++)
526 if (sizes[j] < 6 || sizes[j] > 29)
528 MSTRUCT_CALLOC (fontx, MERROR_WIN);
530 fontx->multiple_sizes = 0;
531 fontx->size = sizes[j] * 10;
533 fontx->property[MFONT_RESY] = 0;
534 p = mplist_add (p, family, fontx);
537 XFreeFontNames (font_names);
542 xfont_list_all (MFrame *frame)
544 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
545 MPlist *font_encoding_list, *p;
547 if (disp_info->all_fonts_scaned)
549 disp_info->all_fonts_scaned = 1;
550 font_encoding_list = mfont__encoding_list ();
551 if (! font_encoding_list)
553 MPLIST_DO (p, font_encoding_list)
554 xfont_registry_list (frame, MPLIST_KEY (p));
564 /* The X font driver function SELECT. */
567 xfont_select (MFrame *frame, MFont *font, int limited_size)
569 MPlist *plist = mplist (), *pl;
570 int num = xfont_list (frame, plist, font, 0);
574 MPLIST_DO (pl, plist)
576 font = MPLIST_VAL (pl);
577 if (limited_size == 0
579 || font->size <= limited_size)
585 M17N_OBJECT_UNREF (plist);
589 /* The X font driver function CLOSE. */
592 close_xfont (void *object)
594 MRealizedFontX *x_rfont = object;
596 XFreeFont (x_rfont->display, x_rfont->xfont);
600 /* The X font driver function OPEN. */
602 static MRealizedFont *
603 xfont_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
606 MRealizedFontX *x_rfont;
608 Display *display = FRAME_DISPLAY (frame);
610 int mdebug_flag = MDEBUG_FONT;
616 int ratio = mfont_resize_ratio (font);
619 size = size * ratio / 100;
626 /* non-scalable font */
627 if (font->multiple_sizes)
635 for (i = size / 10 - 6; i >= 0; i--)
636 if (font->size & (1 << i))
639 for (i = size / 10 - 5; i < 24; i++)
640 if (font->size & (1 << i))
650 for (; rfont; rfont = rfont->next)
651 if (rfont->font == font && rfont->spec.size == size)
656 this.multiple_sizes = 0;
658 /* This never fail to generate a valid fontname. */
659 name = mfont_unparse_name (&this, Mx);
660 xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
663 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
665 font->type = MFONT_TYPE_FAILURE;
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);
672 rfont->id = msymbol (name);
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)
686 ? (int) (value << 6) : 0);
688 = (XGetFontProperty (xfont, disp_info->AVERAGE_WIDTH, &value)
689 ? (int) (value << 6) / 10 : 0);
691 rfont->ascent = (xfont->ascent << 6) + rfont->baseline_offset;
692 rfont->descent = (xfont->descent << 6) - rfont->baseline_offset;
693 rfont->max_advance = xfont->max_bounds.width << 6;
694 rfont->x_ppem = rfont->y_ppem = size / 10;
695 rfont->fontp = xfont;
696 rfont->next = MPLIST_VAL (frame->realized_font_list);
697 MPLIST_VAL (frame->realized_font_list) = rfont;
698 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
704 /* The X font driver function FIND_METRIC. */
707 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
710 XFontStruct *xfont = rfont->fontp;
711 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
713 for (; g != gend; g++)
716 if (g->g.code == MCHAR_INVALID_CODE)
718 g->g.lbearing = xfont->max_bounds.lbearing << 6;
719 g->g.rbearing = xfont->max_bounds.rbearing << 6;
720 g->g.xadv = xfont->max_bounds.width << 6;
721 g->g.ascent = xfont->ascent << 6;
722 g->g.descent = xfont->descent << 6;
726 int byte1 = g->g.code >> 8, byte2 = g->g.code & 0xFF;
727 XCharStruct *pcm = NULL;
729 if (xfont->per_char != NULL)
731 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
734 && byte2 >= xfont->min_char_or_byte2
735 && byte2 <= xfont->max_char_or_byte2)
736 pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
740 if (byte1 >= xfont->min_byte1
741 && byte1 <= xfont->max_byte1
742 && byte2 >= xfont->min_char_or_byte2
743 && byte2 <= xfont->max_char_or_byte2)
745 pcm = (xfont->per_char
746 + ((xfont->max_char_or_byte2
747 - xfont->min_char_or_byte2 + 1)
748 * (byte1 - xfont->min_byte1))
749 + (byte2 - xfont->min_char_or_byte2));
756 g->g.lbearing = pcm->lbearing << 6;
757 g->g.rbearing = pcm->rbearing << 6;
758 g->g.xadv = pcm->width << 6;
759 g->g.ascent = pcm->ascent << 6;
760 g->g.descent = pcm->descent << 6;
764 /* If the per_char pointer is null, all glyphs between
765 the first and last character indexes inclusive have
766 the same information, as given by both min_bounds and
769 g->g.rbearing = xfont->max_bounds.width << 6;
770 g->g.xadv = xfont->max_bounds.width << 6;
771 g->g.ascent = xfont->ascent << 6;
772 g->g.descent = xfont->descent << 6;
776 g->g.ascent += rfont->baseline_offset;
777 g->g.descent -= rfont->baseline_offset;
784 xfont_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
786 return (xfont_encode_char (frame, font, spec, code) != MCHAR_INVALID_CODE);
789 /* The X font driver function GET_GLYPH_ID. */
792 xfont_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
794 MRealizedFont *rfont;
796 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
799 if (font->type == MFONT_TYPE_REALIZED)
800 rfont = (MRealizedFont *) font;
801 else if (font->type == MFONT_TYPE_OBJECT)
803 for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
805 if (rfont->font == font)
809 rfont = xfont_open (frame, font, spec, NULL);
811 return MCHAR_INVALID_CODE;
815 MFATAL (MERROR_FONT_X);
816 xfont = rfont->fontp;
817 all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True);
818 min_byte1 = xfont->min_byte1;
819 max_byte1 = xfont->max_byte1;
820 min_byte2 = xfont->min_char_or_byte2;
821 max_byte2 = xfont->max_char_or_byte2;
823 if (min_byte1 == 0 && max_byte1 == 0)
827 if (code < min_byte2 || code > max_byte2)
828 return MCHAR_INVALID_CODE;
831 pcm = xfont->per_char + (code - min_byte2);
832 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
833 ? code : MCHAR_INVALID_CODE);
837 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
840 if (byte1 < min_byte1 || byte1 > max_byte1
841 || byte2 < min_byte2 || byte2 > max_byte2)
842 return MCHAR_INVALID_CODE;
846 pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
847 + (byte2 - min_byte2));
848 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
849 ? code : MCHAR_INVALID_CODE);
853 /* The X font driver function RENDER. */
856 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
857 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
859 MRealizedFace *rface = from->rface;
860 Display *display = FRAME_DISPLAY (rface->frame);
862 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
870 baseline_offset = rface->rfont->baseline_offset >> 6;
872 gc = set_region (rface->frame, gc, region);
873 XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
874 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
875 for (i = 0, g = from; g < to; i++, g++)
877 code[i].byte1 = g->g.code >> 8;
878 code[i].byte2 = g->g.code & 0xFF;
884 if (g->type == GLYPH_PAD)
886 else if (g->type == GLYPH_SPACE)
887 for (; g < to && g->type == GLYPH_SPACE; g++)
889 else if (! g->rface->rfont)
891 if ((g->g.c >= 0x200B && g->g.c <= 0x200F)
892 || (g->g.c >= 0x202A && g->g.c <= 0x202E))
896 /* As a font is not found for this character, draw an
898 int box_width = g->g.xadv;
899 int box_height = gstring->ascent + gstring->descent;
905 XDrawRectangle (display, (Window) win, gc,
906 x, y - gstring->ascent, box_width, box_height);
910 else if (g->g.xoff != 0 || g->g.yoff != 0 || g->right_padding)
912 XDrawString16 (display, (Window) win, gc,
913 x + g->g.xoff, y + g->g.yoff - baseline_offset,
914 code + (g - from), 1);
921 int code_idx = g - from;
924 g < to && g->type == GLYPH_CHAR && g->g.xoff == 0 && g->g.yoff == 0;
927 XDrawString16 (display, (Window) win, gc,
928 orig_x, y - baseline_offset, code + code_idx, i);
934 xfont_list (MFrame *frame, MPlist *plist, MFont *font, int maxnum)
936 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
937 MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil;
938 MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil;
939 int size = font ? font->size : 0;
942 int mdebug_flag = MDEBUG_FONT;
944 MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
945 family ? msymbol_name (family) : "*",
946 registry ? msymbol_name (registry) : "*");
948 if (registry == Mnil)
949 xfont_list_all (frame);
951 xfont_registry_list (frame, registry);
953 MPLIST_DO (pl, disp_info->font_list)
954 if (registry == Mnil || registry == MPLIST_KEY (pl))
956 MPLIST_DO (p, MPLIST_VAL (pl))
957 if (family == Mnil || family == MPLIST_KEY (p))
959 MFont *fontx = MPLIST_VAL (p);
961 if (! font || (mfont__match_p (fontx, font, MFONT_REGISTRY)))
963 if (fontx->size != 0 && size)
965 if (fontx->multiple_sizes)
967 if (size < 60 || size > 290
968 || ! (fontx->size & (1 << (size / 10 - 6))))
971 else if (fontx->size != size)
974 mplist_push (plist, MPLIST_KEY (p), fontx);
976 if (maxnum > 0 && maxnum == num)
983 MDEBUG_PRINT1 (" %d found\n", num);
988 xfont_list_family_names (MFrame *frame, MPlist *plist)
990 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
993 MSymbol last_family = Mnil;
995 font_names = XListFonts (disp_info->display,
996 "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", 0x8000, &nfonts);
997 for (i = 0; i < nfonts; i++)
1000 char foundry[256], fam[256];
1003 if (sscanf (font_names[i], "-%s-%s-", foundry, fam) < 2)
1005 family = msymbol (fam);
1006 if (family == last_family)
1008 last_family = family;
1010 MPLIST_DO (p, plist)
1012 MSymbol sym = MPLIST_SYMBOL (p);
1016 if (strcmp (MSYMBOL_NAME (sym), fam) > 0)
1018 mplist_push (p, Msymbol, family);
1022 if (MPLIST_TAIL_P (p))
1023 mplist_push (p, Msymbol, family);
1026 XFreeFontNames (font_names);
1030 xfont_check_capability (MRealizedFont *rfont, MSymbol capability)
1032 /* Currently X font driver doesn't support any capability. */
1044 FT_Face ft_face; /* This must be the 2nd member. */
1047 XftFont *font_no_aa;
1048 /* Pointer to MRealizedFontFT */
1052 static MRealizedFont *xft_open (MFrame *frame, MFont *font, MFont *spec,
1054 static int xft_has_char (MFrame *frame, MFont *font, MFont *spec,
1055 int c, unsigned code);
1056 static unsigned xft_encode_char (MFrame *frame, MFont *font, MFont *spec,
1058 static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
1059 static void xft_render (MDrawWindow, int, int, MGlyphString *,
1060 MGlyph *, MGlyph *, int, MDrawRegion);
1061 static int xft_check_capability (MRealizedFont *rfont, MSymbol capability);
1062 static int xft_check_otf (MFLTFont *font, MFLTOtfSpec *spec);
1063 static int xft_drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
1064 MFLTGlyphString *in, int from, int to,
1065 MFLTGlyphString *out,
1066 MFLTGlyphAdjustment *adjustment);
1067 static int xft_try_otf (MFLTFont *font, MFLTOtfSpec *spec,
1068 MFLTGlyphString *in, int from, int to);
1069 static int xft_iterate_otf_feature (struct _MFLTFont *font, MFLTOtfSpec *spec,
1070 int from, int to, unsigned char *table);
1073 static MFontDriver xft_driver =
1075 xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL, NULL,
1076 xft_check_capability, NULL, NULL, xft_check_otf, xft_drive_otf, xft_try_otf,
1078 xft_iterate_otf_feature
1079 #endif /* HAVE_OTF */
1083 close_xft (void *object)
1085 MRealizedFontXft *rfont_xft = object;
1087 if (rfont_xft->font_aa)
1088 XftFontClose (rfont_xft->display, rfont_xft->font_aa);
1089 if (rfont_xft->font_no_aa)
1090 XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
1091 M17N_OBJECT_UNREF (rfont_xft->info);
1097 xft_open_font (Display *display, MSymbol file, double size,
1103 pattern = FcPatternCreate ();
1104 FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
1105 FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
1106 FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
1107 font = XftFontOpenPattern (display, pattern);
1112 static MRealizedFont *
1113 xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
1115 Display *display = FRAME_DISPLAY (frame);
1116 int reg = spec->property[MFONT_REGISTRY];
1118 MRealizedFontXft *rfont_xft;
1119 FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
1122 int ascent, descent, max_advance, average_width, baseline_offset;
1125 /* non-scalable font */
1127 else if (spec->size)
1129 int ratio = mfont_resize_ratio (font);
1131 size = ratio == 100 ? spec->size : spec->size * ratio / 100;
1138 MRealizedFont *save = NULL;
1140 for (; rfont; rfont = rfont->next)
1141 if (rfont->font == font
1142 && (rfont->font->size ? rfont->font->size == size
1143 : rfont->spec.size == size)
1144 && rfont->spec.property[MFONT_REGISTRY] == reg)
1148 if (rfont->driver == &xft_driver)
1153 rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
1156 ascent = rfont->ascent;
1157 descent = rfont->descent;
1158 max_advance = rfont->max_advance;
1159 average_width = rfont->average_width;
1160 baseline_offset = rfont->baseline_offset;
1161 spec = &rfont->spec;
1162 ft_face = rfont->fontp;
1163 xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
1166 M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
1167 rfont_xft->display = display;
1168 if (anti_alias == FcTrue)
1169 rfont_xft->font_aa = xft_font;
1171 rfont_xft->font_no_aa = xft_font;
1172 rfont_xft->ft_face = ft_face;
1173 rfont_xft->info = rfont->info;
1174 M17N_OBJECT_REF (rfont->info);
1175 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
1176 rfont->id = font->file;
1177 rfont->spec = *spec;
1178 rfont->spec.size = size;
1179 rfont->frame = frame;
1181 rfont->driver = &xft_driver;
1182 rfont->info = rfont_xft;
1183 rfont->ascent = ascent;
1184 rfont->descent = descent;
1185 rfont->max_advance = max_advance;
1186 rfont->average_width = average_width;
1187 rfont->baseline_offset = baseline_offset;
1188 rfont->x_ppem = ft_face->size->metrics.x_ppem;
1189 rfont->y_ppem = ft_face->size->metrics.y_ppem;
1190 rfont->fontp = xft_font;
1191 rfont->next = MPLIST_VAL (frame->realized_font_list);
1192 MPLIST_VAL (frame->realized_font_list) = rfont;
1197 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1200 Display *display = FRAME_DISPLAY (rfont->frame);
1201 XftFont *xft_font = rfont->fontp;
1202 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1204 for (; g != gend; g++)
1205 if (! g->g.measured)
1207 if (g->g.code == MCHAR_INVALID_CODE)
1210 g->g.rbearing = xft_font->max_advance_width << 6;
1211 g->g.xadv = g->g.rbearing << 6;
1212 g->g.ascent = xft_font->ascent << 6;
1213 g->g.descent = xft_font->descent << 6;
1219 XftGlyphExtents (display, xft_font, &g->g.code, 1, &extents);
1220 g->g.lbearing = (- extents.x) << 6;
1221 g->g.rbearing = (extents.width - extents.x) << 6;
1222 g->g.xadv = extents.xOff << 6;
1223 g->g.ascent = extents.y << 6;
1224 g->g.descent = (extents.height - extents.y) << 6;
1232 xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
1236 if (font->type == MFONT_TYPE_REALIZED)
1238 MRealizedFont *rfont = (MRealizedFont *) font;
1239 MRealizedFontXft *rfont_xft = rfont->info;
1241 rfont->info = rfont_xft->info;
1242 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1243 rfont->info = rfont_xft;
1246 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1251 xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
1253 if (font->type == MFONT_TYPE_REALIZED)
1255 MRealizedFont *rfont = (MRealizedFont *) font;
1256 MRealizedFontXft *rfont_xft = rfont->info;
1258 rfont->info = rfont_xft->info;
1259 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1260 rfont->info = rfont_xft;
1263 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1268 xft_render (MDrawWindow win, int x, int y,
1269 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1270 int reverse, MDrawRegion region)
1272 MRealizedFace *rface = from->rface;
1273 MFrame *frame = rface->frame;
1274 Display *display = FRAME_DISPLAY (frame);
1275 MRealizedFont *rfont = rface->rfont;
1276 MRealizedFontXft *rfont_xft = rfont->info;
1277 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1278 XftColor *xft_color = (! reverse
1279 ? &((GCInfo *) rface->info)->xft_color_fore
1280 : &((GCInfo *) rface->info)->xft_color_back);
1281 int anti_alias = (gstring->control.anti_alias
1282 && FRAME_DEVICE (frame)->depth > 1);
1294 if (rfont_xft->font_aa)
1295 xft_font = rfont_xft->font_aa;
1298 double size = rfont->spec.size;
1300 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1303 rfont_xft->font_aa = xft_font;
1305 xft_font = rfont->fontp;
1310 if (rfont_xft->font_no_aa)
1311 xft_font = rfont_xft->font_no_aa;
1314 double size = rfont->spec.size;
1316 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1319 rfont_xft->font_no_aa = xft_font;
1321 xft_font = rfont->fontp;
1325 XftDrawChange (xft_draw, (Drawable) win);
1326 XftDrawSetClip (xft_draw, (Region) region);
1328 y -= rfont->baseline_offset >> 6;
1329 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1330 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->g.xadv)
1332 if (! g->g.adjusted && !g->left_padding && !g->right_padding)
1333 glyphs[nglyphs++] = g->g.code;
1337 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1338 last_x, y, glyphs, nglyphs);
1340 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1341 x + g->g.xoff, y + g->g.yoff, (FT_UInt *) &g->g.code, 1);
1342 last_x = x + g->g.xadv;
1346 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1350 xft_check_capability (MRealizedFont *rfont, MSymbol capability)
1352 MRealizedFontXft *rfont_xft = rfont->info;
1355 rfont->info = rfont_xft->info;
1356 result = mfont__ft_driver.check_capability (rfont, capability);
1357 rfont->info = rfont_xft;
1362 xft_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
1364 MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
1365 MRealizedFontXft *rfont_xft = rfont->info;
1368 rfont->info = rfont_xft->info;
1369 result = mfont__ft_driver.check_otf (font, spec);
1370 rfont->info = rfont_xft;
1375 xft_drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
1376 MFLTGlyphString *in, int from, int to,
1377 MFLTGlyphString *out,
1378 MFLTGlyphAdjustment *adjustment)
1380 MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
1381 MRealizedFontXft *rfont_xft = rfont->info;
1384 rfont->info = rfont_xft->info;
1385 result = mfont__ft_driver.drive_otf (font, spec, in, from, to, out,
1387 rfont->info = rfont_xft;
1392 xft_try_otf (MFLTFont *font, MFLTOtfSpec *spec,
1393 MFLTGlyphString *in, int from, int to)
1395 return xft_drive_otf (font, spec, in, from, to, NULL, NULL);
1401 xft_iterate_otf_feature (struct _MFLTFont *font, MFLTOtfSpec *spec,
1402 int from, int to, unsigned char *table)
1404 MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
1405 MRealizedFontXft *rfont_xft = rfont->info;
1408 rfont->info = rfont_xft->info;
1409 result = mfont__ft_driver.iterate_otf_feature (font, spec, from, to, table);
1410 rfont->info = rfont_xft;
1413 #endif /* HAVE_OTF */
1415 #endif /* HAVE_XFT2 */
1418 /* Functions for the device driver. */
1421 mwin__close_device (MFrame *frame)
1423 MWDevice *device = FRAME_DEVICE (frame);
1425 M17N_OBJECT_UNREF (device);
1429 mwin__device_get_prop (MFrame *frame, MSymbol key)
1431 MWDevice *device = FRAME_DEVICE (frame);
1433 if (key == Mdisplay)
1434 return (void *) device->display_info->display;
1436 return (void *) ScreenOfDisplay(device->display_info->display,
1437 device->screen_num);
1438 if (key == Mcolormap)
1439 return (void *) device->cmap;
1441 return (void *) device->depth;
1446 mwin__realize_face (MRealizedFace *rface)
1449 MSymbol foreground, background, videomode;
1450 MFaceHLineProp *hline;
1454 if (rface != rface->ascii_rface)
1456 rface->info = rface->ascii_rface->info;
1460 frame = rface->frame;
1461 MSTRUCT_CALLOC (info, MERROR_WIN);
1463 foreground = rface->face.property[MFACE_FOREGROUND];
1464 background = rface->face.property[MFACE_BACKGROUND];
1465 videomode = rface->face.property[MFACE_VIDEOMODE];
1467 videomode = frame->videomode;
1468 if (videomode != Mreverse)
1470 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1471 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1475 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1476 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1479 if (foreground == Mnil)
1480 foreground = frame->foreground;
1481 if (background == Mnil)
1482 background = frame->background;
1483 if (videomode == Mreverse)
1485 MSymbol temp = foreground;
1486 foreground = background;
1489 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1490 FRAME_VISUAL (frame),
1492 MSYMBOL_NAME (foreground),
1493 &info->xft_color_fore))
1495 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1496 FRAME_VISUAL (frame),
1498 MSYMBOL_NAME (background),
1499 &info->xft_color_back))
1501 #endif /* HAVE_XFT2 */
1503 hline = rface->hline;
1507 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1509 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1516 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1518 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1520 if (box->color_left && box->color_left != box->color_top)
1521 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1523 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1525 if (box->color_bottom && box->color_bottom != box->color_top)
1526 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1528 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1530 if (box->color_right && box->color_right != box->color_bottom)
1531 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1533 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1541 mwin__free_realized_face (MRealizedFace *rface)
1543 if (rface == rface->ascii_rface)
1549 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1551 int x, int y, int width, int height, MDrawRegion region)
1553 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1556 gc = set_region (frame, gc, region);
1558 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1559 x, y, width, height);
1564 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1565 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1566 int reverse, MDrawRegion region)
1568 MRealizedFace *rface = from->rface;
1569 Display *display = FRAME_DISPLAY (rface->frame);
1570 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1576 gc = set_region (rface->frame, gc, region);
1577 for (; from < to; from++)
1579 XDrawRectangle (display, (Window) win, gc,
1580 x, y - gstring->ascent + 1, from->g.xadv - 1,
1581 gstring->ascent + gstring->descent - 2);
1588 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1589 MRealizedFace *rface, int reverse,
1590 int x, int y, int width, MDrawRegion region)
1592 enum MFaceHLineType type = rface->hline->type;
1593 GCInfo *info = rface->info;
1594 GC gc = gc = info->gc[GC_HLINE];
1597 y = (type == MFACE_HLINE_BOTTOM
1598 ? y + gstring->text_descent - rface->hline->width
1599 : type == MFACE_HLINE_UNDER
1601 : type == MFACE_HLINE_STRIKE_THROUGH
1602 ? y - ((gstring->ascent + gstring->descent) / 2)
1603 : y - gstring->text_ascent);
1605 gc = set_region (frame, gc, region);
1607 for (i = 0; i < rface->hline->width; i++)
1608 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1609 x, y + i, x + width - 1, y + i);
1614 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1615 MGlyph *g, int x, int y, int width, MDrawRegion region)
1617 Display *display = FRAME_DISPLAY (frame);
1618 MRealizedFace *rface = g->rface;
1619 MFaceBoxProp *box = rface->box;
1620 GCInfo *info = rface->info;
1621 GC gc_top, gc_left, gc_right, gc_btm;
1625 y0 = y - (gstring->text_ascent
1626 + rface->box->inner_vmargin + rface->box->width);
1627 y1 = y + (gstring->text_descent
1628 + rface->box->inner_vmargin + rface->box->width - 1);
1630 gc_top = info->gc[GC_BOX_TOP];
1632 gc_top = set_region (frame, gc_top, region);
1633 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1636 gc_btm = info->gc[GC_BOX_BOTTOM];
1638 if (g->type == GLYPH_BOX)
1642 if (g->left_padding)
1643 x0 = x + box->outer_hmargin, x1 = x + g->g.xadv - 1;
1645 x0 = x, x1 = x + g->g.xadv - box->outer_hmargin - 1;
1647 /* Draw the top side. */
1648 for (i = 0; i < box->width; i++)
1649 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1651 /* Draw the bottom side. */
1652 if (region && gc_btm != gc_top)
1653 gc_btm = set_region (frame, gc_btm, region);
1654 for (i = 0; i < box->width; i++)
1655 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1657 if (g->left_padding > 0)
1659 /* Draw the left side. */
1660 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1664 gc_left = info->gc[GC_BOX_LEFT];
1666 gc_left = set_region (frame, gc_left, region);
1668 for (i = 0; i < rface->box->width; i++)
1669 XDrawLine (display, (Window) win, gc_left,
1670 x0 + i, y0 + i, x0 + i, y1 - i);
1674 /* Draw the right side. */
1675 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1679 gc_right = info->gc[GC_BOX_RIGHT];
1681 gc_right = set_region (frame, gc_right, region);
1683 for (i = 0; i < rface->box->width; i++)
1684 XDrawLine (display, (Window) win, gc_right,
1685 x1 - i, y0 + i, x1 - i, y1 - i);
1690 /* Draw the top side. */
1691 for (i = 0; i < box->width; i++)
1692 XDrawLine (display, (Window) win, gc_top,
1693 x, y0 + i, x + width - 1, y0 + i);
1695 /* Draw the bottom side. */
1696 if (region && gc_btm != gc_top)
1697 gc_btm = set_region (frame, gc_btm, region);
1698 for (i = 0; i < box->width; i++)
1699 XDrawLine (display, (Window) win, gc_btm,
1700 x, y1 - i, x + width - 1, y1 - i);
1707 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1708 int reverse, int x, int y,
1709 int width, int height, int row_bytes, unsigned char *bmp,
1712 Display *display = FRAME_DISPLAY (frame);
1714 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1717 gc = set_region (frame, gc, region);
1719 for (i = 0; i < height; i++, bmp += row_bytes)
1720 for (j = 0; j < width; j++)
1721 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1722 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1727 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1728 int intensity, MDrawPoint *points, int num,
1731 GCInfo *info = rface->info;
1734 if (! (gc = info->gc[intensity]))
1735 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1738 gc = set_region (frame, gc, region);
1740 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1741 (XPoint *) points, num, CoordModeOrigin);
1746 mwin__region_from_rect (MDrawMetric *rect)
1748 MDrawRegion region1 = XCreateRegion ();
1749 MDrawRegion region2 = XCreateRegion ();
1754 xrect.width = rect->width;
1755 xrect.height = rect->height;
1756 XUnionRectWithRegion (&xrect, region1, region2);
1757 XDestroyRegion (region1);
1762 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1764 MDrawRegion region1 = XCreateRegion ();
1769 xrect.width = rect->width;
1770 xrect.height = rect->height;
1772 XUnionRegion (region, region, region1);
1773 XUnionRectWithRegion (&xrect, region1, region);
1774 XDestroyRegion (region1);
1778 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1780 MDrawRegion region = XCreateRegion ();
1782 XUnionRegion (region1, region1, region);
1783 XIntersectRegion (region, region2, region1);
1784 XDestroyRegion (region);
1788 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1790 MDrawRegion region1 = XCreateRegion ();
1795 xrect.width = rect->width;
1796 xrect.height = rect->height;
1797 XUnionRectWithRegion (&xrect, region1, region);
1798 XDestroyRegion (region1);
1802 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1806 XClipBox (region, &xrect);
1809 rect->width = xrect.width;
1810 rect->height = xrect.height;
1814 mwin__free_region (MDrawRegion region)
1816 XDestroyRegion (region);
1820 mwin__dump_region (MDrawRegion region)
1823 XClipBox (region, &rect);
1824 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1829 mwin__create_window (MFrame *frame, MDrawWindow parent)
1831 Display *display = FRAME_DISPLAY (frame);
1833 XWMHints wm_hints = { InputHint, False };
1834 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1835 XSetWindowAttributes set_attrs;
1838 GCInfo *info = frame->rface->info;
1841 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1842 mask = GCForeground;
1843 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1844 set_attrs.background_pixel = values.foreground;
1845 set_attrs.backing_store = Always;
1846 set_attrs.override_redirect = True;
1847 set_attrs.save_under = True;
1848 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1849 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1850 CopyFromParent, InputOutput, CopyFromParent,
1852 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1853 NULL, &wm_hints, &class_hints);
1854 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1855 return (MDrawWindow) win;
1859 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1862 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1864 if (XftDrawDrawable (xft_draw) == (Drawable) win)
1865 XftDrawChange (xft_draw, FRAME_DEVICE (frame)->drawable);
1866 #endif /* HAVE_XFT2 */
1867 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1872 mwin__event_window (void *event)
1874 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1878 mwin__print_event (void *arg, char *win_name)
1881 XEvent *event = (XEvent *) arg;
1883 switch (event->xany.type)
1885 case 2: event_name = "KeyPress"; break;
1886 case 3: event_name = "KeyRelease"; break;
1887 case 4: event_name = "ButtonPress"; break;
1888 case 5: event_name = "ButtonRelease"; break;
1889 case 6: event_name = "MotionNotify"; break;
1890 case 7: event_name = "EnterNotify"; break;
1891 case 8: event_name = "LeaveNotify"; break;
1892 case 9: event_name = "FocusIn"; break;
1893 case 10: event_name = "FocusOut"; break;
1894 case 11: event_name = "KeymapNotify"; break;
1895 case 12: event_name = "Expose"; break;
1896 case 13: event_name = "GraphicsExpose"; break;
1897 case 14: event_name = "NoExpose"; break;
1898 case 15: event_name = "VisibilityNotify"; break;
1899 case 16: event_name = "CreateNotify"; break;
1900 case 17: event_name = "DestroyNotify"; break;
1901 case 18: event_name = "UnmapNotify"; break;
1902 case 19: event_name = "MapNotify"; break;
1903 case 20: event_name = "MapRequest"; break;
1904 case 21: event_name = "ReparentNotify"; break;
1905 case 22: event_name = "ConfigureNotify"; break;
1906 case 23: event_name = "ConfigureRequest"; break;
1907 case 24: event_name = "GravityNotify"; break;
1908 case 25: event_name = "ResizeRequest"; break;
1909 case 26: event_name = "CirculateNotify"; break;
1910 case 27: event_name = "CirculateRequest"; break;
1911 case 28: event_name = "PropertyNotify"; break;
1912 case 29: event_name = "SelectionClear"; break;
1913 case 30: event_name = "SelectionRequest"; break;
1914 case 31: event_name = "SelectionNotify"; break;
1915 case 32: event_name = "ColormapNotify"; break;
1916 case 33: event_name = "ClientMessage"; break;
1917 case 34: event_name = "MappingNotify"; break;
1918 default: event_name = "unknown";
1921 fprintf (stderr, "%s: %s\n", win_name, event_name);
1926 mwin__map_window (MFrame *frame, MDrawWindow win)
1928 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1932 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1934 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1938 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1939 MDrawMetric *geometry)
1941 Display *display = FRAME_DISPLAY (frame);
1942 XWindowAttributes attr;
1943 Window parent = (Window) parent_win, root;
1945 XGetWindowAttributes (display, (Window) win, &attr);
1946 geometry->x = attr.x + attr.border_width;
1947 geometry->y = attr.y + attr.border_width;
1948 geometry->width = attr.width;
1949 geometry->height = attr.height;
1952 parent = RootWindow (display, FRAME_SCREEN (frame));
1955 Window this_parent, *children;
1958 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1961 if (this_parent == parent || this_parent == root)
1963 win = (MDrawWindow) this_parent;
1964 XGetWindowAttributes (display, (Window) win, &attr);
1965 geometry->x += attr.x + attr.border_width;
1966 geometry->y += attr.y + attr.border_width;
1971 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1972 MDrawMetric *current, MDrawMetric *new)
1974 Display *display = FRAME_DISPLAY (frame);
1975 unsigned int mask = 0;
1976 XWindowChanges values;
1978 if (current->width != new->width)
1981 if (new->width <= 0)
1983 values.width = current->width = new->width;
1985 if (current->height != new->height)
1988 if (new->height <= 0)
1990 values.height = current->height = new->height;
1992 if (current->x != new->x)
1995 values.x = current->x = new->x;
1997 if (current->y != new->y)
2000 current->y = new->y;
2001 values.y = current->y = new->y;
2004 XConfigureWindow (display, (Window) win, mask, &values);
2005 XClearWindow (display, (Window) win);
2009 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
2011 XEvent *event = (XEvent *) arg;
2012 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
2019 if (event->xany.type != KeyPress
2020 /* && event->xany.type != KeyRelease */
2023 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
2026 if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
2029 if ((keysym & 0xff00) == 0xfe00)
2032 if (len == 1 && keysym >= XK_space && keysym <= XK_asciitilde)
2036 key = minput__char_to_key (c);
2037 if (c == ' ' && ((XKeyEvent *) event)->state & ShiftMask)
2038 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2042 char *str = XKeysymToString (keysym);
2046 key = msymbol (str);
2047 if (((XKeyEvent *) event)->state & ShiftMask)
2048 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2050 if (((XKeyEvent *) event)->state & ControlMask)
2051 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2052 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
2053 *modifiers |= MINPUT_KEY_META_MODIFIER;
2054 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
2055 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
2056 if (((XKeyEvent *) event)->state & disp_info->super_mask)
2057 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
2058 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
2059 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
2061 if (((XKeyEvent *) event)->state & disp_info->altgr_mask)
2062 *modifiers |= MINPUT_KEY_ALTGR_MODIFIER;
2069 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
2071 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
2073 Display *display = FRAME_DISPLAY (frame);
2074 GCInfo *info = rface->info;
2077 for (i = 0; i <= GC_INVERSE; i++)
2079 XGetGCValues (display, info->gc[i], valuemask, &values);
2080 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
2081 values.foreground, values.background);
2082 fprintf (stderr, "\n");
2086 static MDeviceDriver x_driver =
2089 mwin__device_get_prop,
2091 mwin__free_realized_face,
2093 mwin__draw_empty_boxes,
2097 mwin__region_from_rect,
2098 mwin__union_rect_with_region,
2099 mwin__intersect_region,
2100 mwin__region_add_rect,
2101 mwin__region_to_rect,
2104 mwin__create_window,
2105 mwin__destroy_window,
2108 mwin__window_geometry,
2109 mwin__adjust_window,
2113 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
2118 M_iso8859_1 = msymbol ("iso8859-1");
2119 M_iso10646_1 = msymbol ("iso10646-1");
2121 display_info_list = mplist ();
2122 device_list = mplist ();
2125 xft_driver.select = mfont__ft_driver.select;
2126 xft_driver.list = mfont__ft_driver.list;
2127 xft_driver.list_family_names = mfont__ft_driver.list_family_names;
2130 Mxim = msymbol ("xim");
2131 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
2139 M17N_OBJECT_UNREF (display_info_list);
2140 M17N_OBJECT_UNREF (device_list);
2145 #ifdef X_SET_ERROR_HANDLER
2147 x_error_handler (Display *display, XErrorEvent *error)
2154 x_io_error_handler (Display *display)
2161 /** Return an MWDevice object corresponding to a display specified in
2164 It searches device_list for a device matching the display. If
2165 found, return the found object. Otherwise, return a newly created
2169 device_open (MFrame *frame, MPlist *param)
2171 Display *display = NULL;
2172 Screen *screen = NULL;
2174 Drawable drawable = 0;
2175 Widget widget = NULL;
2177 int auto_display = 0;
2178 MDisplayInfo *disp_info = NULL;
2179 MWDevice *device = NULL;
2181 XWindowAttributes attr;
2187 int use_xfont = 0, use_freetype = 0, use_xft = 0;
2189 for (plist = param; (key = mplist_key (plist)) != Mnil;
2190 plist = mplist_next (plist))
2192 if (key == Mdisplay)
2193 display = (Display *) mplist_value (plist);
2194 else if (key == Mscreen)
2195 screen = mplist_value (plist);
2196 else if (key == Mdrawable)
2197 drawable = (Drawable) mplist_value (plist);
2198 else if (key == Mdepth)
2199 depth = (unsigned) mplist_value (plist);
2200 else if (key == Mwidget)
2201 widget = (Widget) mplist_value (plist);
2202 else if (key == Mcolormap)
2203 cmap = (Colormap) mplist_value (plist);
2204 else if (key == Mfont)
2206 MSymbol val = MPLIST_SYMBOL (plist);
2210 #ifdef HAVE_FREETYPE
2211 else if (val == Mfreetype)
2214 else if (val == Mxft)
2221 /* If none of them is specified, use all of them. */
2222 if (! use_xfont && ! use_freetype && ! use_xft)
2223 use_xfont = use_freetype = use_xft = 1;
2227 display = XtDisplay (widget);
2228 screen_num = XScreenNumberOfScreen (XtScreen (widget));
2229 depth = DefaultDepth (display, screen_num);
2235 unsigned width, height, border_width;
2238 MERROR (MERROR_WIN, -1);
2239 XGetGeometry (display, drawable, &root_window,
2240 &x, &y, &width, &height, &border_width, &depth);
2241 XGetWindowAttributes (display, root_window, &attr);
2242 screen_num = XScreenNumberOfScreen (attr.screen);
2247 display = DisplayOfScreen (screen);
2252 display = XOpenDisplay (NULL);
2254 MERROR (MERROR_WIN, -1);
2257 screen = DefaultScreenOfDisplay (display);
2259 screen_num = XScreenNumberOfScreen (screen);
2261 depth = DefaultDepth (display, screen_num);
2265 cmap = DefaultColormap (display, screen_num);
2267 for (plist = display_info_list; mplist_key (plist) != Mnil;
2268 plist = mplist_next (plist))
2270 disp_info = (MDisplayInfo *) mplist_value (plist);
2271 if (disp_info->display == display)
2275 if (mplist_key (plist) != Mnil)
2276 M17N_OBJECT_REF (disp_info);
2279 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2280 disp_info->display = display;
2281 disp_info->auto_display = auto_display;
2282 disp_info->font_list = mplist ();
2283 find_modifier_bits (disp_info);
2284 disp_info->MULE_BASELINE_OFFSET
2285 = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
2286 disp_info->AVERAGE_WIDTH
2287 = XInternAtom (display, "AVERAGE_WIDTH", False);
2288 mplist_add (display_info_list, Mt, disp_info);
2291 for (plist = device_list; mplist_key (plist) != Mnil;
2292 plist = mplist_next (plist))
2294 device = (MWDevice *) mplist_value (plist);
2295 if (device->display_info == disp_info
2296 && device->depth == depth
2297 && device->cmap == cmap
2298 && device->screen_num == screen_num)
2302 if (mplist_key (plist) != Mnil)
2303 M17N_OBJECT_REF (device);
2306 unsigned long valuemask = GCForeground;
2310 M17N_OBJECT (device, free_device, MERROR_WIN);
2311 device->display_info = disp_info;
2312 device->screen_num = screen_num;
2313 /* A drawable on which to create GCs. */
2314 device->drawable = XCreatePixmap (display,
2315 RootWindow (display, screen_num),
2317 device->depth = depth;
2318 device->cmap = cmap;
2319 pixels = DisplayHeight (display, screen_num);
2320 mm = DisplayHeightMM (display, screen_num);
2321 device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
2322 device->realized_face_list = mplist ();
2323 device->realized_font_list = mplist ();
2324 mplist_add (device->realized_font_list, Mt, NULL);
2325 device->realized_fontset_list = mplist ();
2326 device->gc_list = mplist ();
2327 values.foreground = BlackPixel (display, screen_num);
2328 device->scratch_gc = XCreateGC (display, device->drawable,
2329 valuemask, &values);
2331 device->xft_draw = XftDrawCreate (display, device->drawable,
2332 DefaultVisual (display, screen_num),
2337 frame->device = device;
2338 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2339 frame->dpi = device->resy;
2340 frame->driver = &x_driver;
2341 frame->font_driver_list = mplist ();
2345 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2348 #endif /* HAVE_XFT2 */
2349 #ifdef HAVE_FREETYPE
2351 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2352 #endif /* HAVE_FREETYPE */
2353 if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
2354 mplist_add (frame->font_driver_list, Mx, &xfont_driver);
2356 frame->realized_font_list = device->realized_font_list;
2357 frame->realized_face_list = device->realized_face_list;
2358 frame->realized_fontset_list = device->realized_fontset_list;
2362 XtResource resources[] = {
2363 { XtNfont, XtCFont, XtRString, sizeof (String),
2364 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2365 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2366 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2367 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2368 XtOffset (AppDataPtr, background), XtRString, "white" },
2369 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2370 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2373 XtGetApplicationResources (widget, &app_data,
2374 resources, XtNumber (resources), NULL, 0);
2375 frame->foreground = msymbol (app_data.foreground);
2376 frame->background = msymbol (app_data.background);
2377 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2381 app_data.font = DEFAULT_FONT;
2382 frame->foreground = msymbol ("black");
2383 frame->background = msymbol ("white");
2384 frame->videomode = Mnormal;
2387 if (strcmp (app_data.font, DEFAULT_FONT) != 0)
2389 XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
2390 unsigned long value;
2395 font = mfont_parse_name (app_data.font, Mx);
2397 && XGetFontProperty (xfont, XA_FONT, &value)
2398 && (name = ((char *) XGetAtomName (display, (Atom) value))))
2399 font = mfont_parse_name (name, Mx);
2400 XFreeFont (display, xfont);
2404 font = mfont_parse_name (DEFAULT_FONT, Mx);
2405 else if (! font->size)
2407 face = mface_from_font (font);
2409 face->property[MFACE_FONTSET] = mfontset (NULL);
2410 face->property[MFACE_FOREGROUND] = frame->foreground;
2411 face->property[MFACE_BACKGROUND] = frame->background;
2412 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2413 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2414 face->property[MFACE_VIDEOMODE] = frame->videomode;
2415 mface_put_prop (face, Mhook_func,
2416 mface_get_prop (mface__default, Mhook_func));
2417 face->property[MFACE_RATIO] = (void *) 100;
2418 mplist_push (param, Mface, face);
2419 M17N_OBJECT_UNREF (face);
2421 #ifdef X_SET_ERROR_HANDLER
2422 XSetErrorHandler (x_error_handler);
2423 XSetIOErrorHandler (x_io_error_handler);
2430 /* XIM (X Input Method) handler */
2432 typedef struct MInputXIMMethodInfo
2438 } MInputXIMMethodInfo;
2440 typedef struct MInputXIMContextInfo
2444 MConverter *converter;
2445 } MInputXIMContextInfo;
2448 xim_open_im (MInputMethod *im)
2450 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
2451 MLocale *saved, *this;
2452 char *save_modifier_list;
2454 MInputXIMMethodInfo *im_info;
2456 saved = mlocale_set (LC_CTYPE, NULL);
2457 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
2459 /* The specified locale is not supported. */
2460 MERROR (MERROR_LOCALE, -1);
2461 if (mlocale_get_prop (this, Mcoding) == Mnil)
2463 /* Unable to decode the output of XIM. */
2464 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2465 MERROR (MERROR_LOCALE, -1);
2468 if (arg->modifier_list)
2469 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
2471 save_modifier_list = XSetLocaleModifiers ("");
2472 if (! save_modifier_list)
2474 /* The specified locale is not supported by X. */
2475 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2476 MERROR (MERROR_LOCALE, -1);
2479 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
2482 /* No input method is available in the current locale. */
2483 XSetLocaleModifiers (save_modifier_list);
2484 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2485 MERROR (MERROR_WIN, -1);
2488 MSTRUCT_MALLOC (im_info, MERROR_WIN);
2489 im_info->display = arg->display;
2491 im_info->language = mlocale_get_prop (this, Mlanguage);
2492 im_info->coding = mlocale_get_prop (this, Mcoding);
2495 XSetLocaleModifiers (save_modifier_list);
2496 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2502 xim_close_im (MInputMethod *im)
2504 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
2506 XCloseIM (im_info->xim);
2511 xim_create_ic (MInputContext *ic)
2513 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
2514 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2515 MInputXIMContextInfo *ic_info;
2518 if (! arg->input_style)
2520 /* By default, use Root style. */
2521 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
2522 arg->preedit_attrs = NULL;
2523 arg->status_attrs = NULL;
2526 if (! arg->preedit_attrs && ! arg->status_attrs)
2527 xic = XCreateIC (im_info->xim,
2528 XNInputStyle, arg->input_style,
2529 XNClientWindow, arg->client_win,
2530 XNFocusWindow, arg->focus_win,
2532 else if (arg->preedit_attrs && ! arg->status_attrs)
2533 xic = XCreateIC (im_info->xim,
2534 XNInputStyle, arg->input_style,
2535 XNClientWindow, arg->client_win,
2536 XNFocusWindow, arg->focus_win,
2537 XNPreeditAttributes, arg->preedit_attrs,
2539 else if (! arg->preedit_attrs && arg->status_attrs)
2540 xic = XCreateIC (im_info->xim,
2541 XNInputStyle, arg->input_style,
2542 XNClientWindow, arg->client_win,
2543 XNFocusWindow, arg->focus_win,
2544 XNStatusAttributes, arg->status_attrs,
2547 xic = XCreateIC (im_info->xim,
2548 XNInputStyle, arg->input_style,
2549 XNClientWindow, arg->client_win,
2550 XNFocusWindow, arg->focus_win,
2551 XNPreeditAttributes, arg->preedit_attrs,
2552 XNStatusAttributes, arg->status_attrs,
2555 MERROR (MERROR_WIN, -1);
2557 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
2559 ic_info->win = arg->focus_win;
2560 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
2566 xim_destroy_ic (MInputContext *ic)
2568 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2570 XDestroyIC (ic_info->xic);
2571 mconv_free_converter (ic_info->converter);
2577 xim_filter (MInputContext *ic, MSymbol key, void *event)
2579 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2581 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
2586 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2588 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2589 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2590 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
2596 buf = (char *) alloca (512);
2597 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
2598 if (status == XBufferOverflow)
2600 buf = (char *) alloca (len);
2601 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
2604 mtext_reset (ic->produced);
2608 mconv_reset_converter (ic_info->converter);
2609 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
2610 mconv_decode (ic_info->converter, ic->produced);
2611 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2612 Mlanguage, (void *) im_info->language);
2613 mtext_cpy (mt, ic->produced);
2614 mtext_reset (ic->produced);
2622 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2626 /*** @addtogroup m17nInputMethodWin */
2631 @brief Input method driver for XIM.
2633 The driver #minput_xim_driver is for the foreign input method of
2634 name #Mxim. It uses XIM (X Input Methods) as a background input
2637 As the symbol #Mxim has property #Minput_driver whose value is
2638 a pointer to this driver, the input method of language #Mnil
2639 and name #Mxim uses this driver.
2641 Therefore, for such input methods, the driver dependent arguments
2642 to the functions whose name begin with minput_ must be as follows.
2644 The argument $ARG of the function minput_open_im () must be a
2645 pointer to the structure #MInputXIMArgIM. See the documentation
2646 of #MInputXIMArgIM for more details.
2648 The argument $ARG of the function minput_create_ic () must be a
2649 pointer to the structure #MInputXIMArgIC. See the documentation
2650 of #MInputXIMArgIC for more details.
2652 The argument $ARG of the function minput_filter () must be a
2653 pointer to the structure @c XEvent. The argument $KEY is ignored.
2655 The argument $ARG of the function minput_lookup () must be the
2656 same one as that of the function minput_filter (). The argument
2660 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2662 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
2663 XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2665 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2666 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
2667 ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2669 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
2670 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2672 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
2673 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
2675 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
2676 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
2678 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
2679 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2681 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2682 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
2684 MInputDriver minput_xim_driver =
2685 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2686 xim_filter, xim_lookup, NULL };
2690 #else /* not HAVE_X11 */
2692 int device_open () { return -1; }
2694 #endif /* not HAVE_X11 */