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. */
88 Atom MULE_BASELINE_OFFSET;
92 /* Anchor of the chain of MDisplayInfo objects. */
93 static MPlist *display_info_list;
96 /* Color value and the corresponding GC. */
99 unsigned int rgb; /* (red << 16) | (green << 8) | blue */
106 GC_NORMAL = GC_INVERSE + 7,
119 /* The first 8 elements are indexed by an intensity for
120 anti-aliasing. The 2nd to 7th are created on demand. */
123 XftColor xft_color_fore, xft_color_back;
129 /* Common header for the m17n object. */
132 MDisplayInfo *display_info;
150 /** List of pointers to realized faces on the frame. */
151 MPlist *realized_face_list;
153 /* List of single element whose value is a root of chain of realized
155 MPlist *realized_font_list;
157 /** List of pointers to realized fontsets on the frame. */
158 MPlist *realized_fontset_list;
160 /** List of XColors vs GCs on the frame. */
164 static MPlist *device_list;
166 static MSymbol M_iso8859_1, M_iso10646_1;
168 #define FRAME_DEVICE(frame) ((MWDevice *) (frame)->device)
169 #define FRAME_DISPLAY(frame) (FRAME_DEVICE (frame)->display_info->display)
170 #define FRAME_SCREEN(frame) (FRAME_DEVICE (frame)->screen_num)
171 #define FRAME_CMAP(frame) (FRAME_DEVICE (frame)->cmap)
172 #define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
173 FRAME_SCREEN (frame))
175 #define DEFAULT_FONT "-*-*-medium-r-normal--13-*-*-*-c-*-iso8859-1"
182 Boolean reverse_video;
183 } AppData, *AppDataPtr;
186 free_display_info (void *object)
188 MDisplayInfo *disp_info = (MDisplayInfo *) object;
191 MPLIST_DO (plist, disp_info->font_list)
193 MPLIST_DO (pl, MPLIST_VAL (plist))
194 free (MPLIST_VAL (pl));
195 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
197 M17N_OBJECT_UNREF (disp_info->font_list);
199 if (disp_info->auto_display)
200 XCloseDisplay (disp_info->display);
206 free_device (void *object)
208 MWDevice *device = object;
211 for (plist = device->realized_fontset_list;
212 mplist_key (plist) != Mnil; plist = mplist_next (plist))
213 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
214 M17N_OBJECT_UNREF (device->realized_fontset_list);
216 if (MPLIST_VAL (device->realized_font_list))
217 mfont__free_realized (MPLIST_VAL (device->realized_font_list));
218 M17N_OBJECT_UNREF (device->realized_font_list);
220 MPLIST_DO (plist, device->realized_face_list)
222 MRealizedFace *rface = MPLIST_VAL (plist);
225 mface__free_realized (rface);
227 M17N_OBJECT_UNREF (device->realized_face_list);
229 MPLIST_DO (plist, device->gc_list)
231 XFreeGC (device->display_info->display,
232 ((RGB_GC *) MPLIST_VAL (plist))->gc);
233 free (MPLIST_VAL (plist));
235 M17N_OBJECT_UNREF (device->gc_list);
236 XFreeGC (device->display_info->display, device->scratch_gc);
239 XftDrawDestroy (device->xft_draw);
242 XFreePixmap (device->display_info->display, device->drawable);
243 M17N_OBJECT_UNREF (device->display_info);
249 find_modifier_bits (MDisplayInfo *disp_info)
251 Display *display = disp_info->display;
252 XModifierKeymap *mods;
253 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
254 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
255 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
256 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
257 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
258 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
259 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
260 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
263 mods = XGetModifierMapping (display);
264 /* We skip the first three sets for Shift, Lock, and Control. The
265 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
266 for (i = 3; i < 8; i++)
267 for (j = 0; j < mods->max_keypermod; j++)
269 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
273 if (code == meta_l || code == meta_r)
274 disp_info->meta_mask |= (1 << i);
275 else if (code == alt_l || code == alt_r)
276 disp_info->alt_mask |= (1 << i);
277 else if (code == super_l || code == super_r)
278 disp_info->super_mask |= (1 << i);
279 else if (code == hyper_l || code == hyper_r)
280 disp_info->hyper_mask |= (1 << i);
283 /* If meta keys are not in any modifier, use alt keys as meta
285 if (! disp_info->meta_mask)
287 disp_info->meta_mask = disp_info->alt_mask;
288 disp_info->alt_mask = 0;
290 /* If both meta and alt are assigned to the same modifier, give meta
292 if (disp_info->meta_mask & disp_info->alt_mask)
293 disp_info->alt_mask &= ~disp_info->meta_mask;
295 XFreeModifiermap (mods);
299 get_rgb_gc (MWDevice *device, XColor *xcolor)
301 int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
302 | (xcolor->blue >> 8));
305 unsigned long valuemask = GCForeground;
308 MPLIST_DO (plist, device->gc_list)
310 rgb_gc = MPLIST_VAL (plist);
312 if (rgb_gc->rgb == rgb)
314 if (rgb_gc->rgb > rgb)
318 if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
321 rgb_gc = malloc (sizeof (RGB_GC));
323 values.foreground = xcolor->pixel;
324 rgb_gc->gc = XCreateGC (device->display_info->display,
325 device->drawable, valuemask, &values);
326 mplist_push (plist, Mt, rgb_gc);
331 get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
333 MWDevice *device = FRAME_DEVICE (frame);
341 color = for_foreground ? frame->foreground : frame->background;
343 if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
344 msymbol_name (color), &xcolor))
346 rgb_gc = get_rgb_gc (device, &xcolor);
350 *rgb_ret = rgb_gc->rgb;
355 GCInfo *info = frame->rface->info;
360 rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
362 rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
370 get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
372 int rgb_fore, rgb_back;
377 if (info->gc[intensity])
378 return info->gc[intensity];
380 rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
381 xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
382 + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
383 xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
384 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
385 xcolor.blue = (((rgb_fore & 0xFF) * intensity
386 + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
387 rgb_gc = get_rgb_gc (device, &xcolor);
391 gc =get_gc_for_anti_alias (device, info,
392 intensity < 4 ? intensity - 1 : intensity + 1);
393 return (info->gc[intensity] = gc);
397 set_region (MFrame *frame, GC gc, MDrawRegion region)
399 unsigned long valuemask = GCForeground;
401 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
402 FRAME_DEVICE (frame)->scratch_gc);
403 XSetRegion (FRAME_DISPLAY (frame), FRAME_DEVICE (frame)->scratch_gc, region);
404 return FRAME_DEVICE (frame)->scratch_gc;
408 /** X font handler */
410 static MFont *xfont_select (MFrame *, MFont *, int);
411 static MRealizedFont *xfont_open (MFrame *, MFont *, MFont *, MRealizedFont *);
412 static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
413 static int xfont_has_char (MFrame *, MFont *, MFont *, int, unsigned);
414 static unsigned xfont_encode_char (MFrame *, MFont *, MFont *, unsigned);
415 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
416 MGlyph *, MGlyph *, int, MDrawRegion);
417 static int xfont_list (MFrame *, MPlist *, MFont *, int);
418 static void xfont_list_family_names (MFrame *, MPlist *);
419 static int xfont_check_capability (MRealizedFont *rfont, MSymbol capability);
421 static MFontDriver xfont_driver =
422 { xfont_select, xfont_open,
423 xfont_find_metric, xfont_has_char, xfont_encode_char,
424 xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability
428 font_compare (const void *p1, const void *p2)
430 return strcmp (*(char **) p1, *(char **) p2);
434 xfont_registry_list (MFrame *frame, MSymbol registry)
436 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
437 MPlist *font_list = disp_info->font_list;
440 char **font_names, **names;
446 plist = mplist_get (font_list, registry);
449 p = plist = mplist ();
450 mplist_add (font_list, registry, plist);
451 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", msymbol_name (registry));
452 font_names = XListFonts (disp_info->display, pattern, 0x8000, &nfonts);
456 char *reg_name = msymbol_name (registry);
458 for_full_width = (strncmp (reg_name, "jis", 3) == 0
459 || strncmp (reg_name, "gb", 2) == 0
460 || strncmp (reg_name, "big5", 4) == 0
461 || strncmp (reg_name, "ksc", 3) == 0);
463 names = alloca (sizeof (char *) * nfonts);
464 memcpy (names, font_names, sizeof (char *) * nfonts);
465 qsort (names, nfonts, sizeof (char *), font_compare);
467 for (i = 0; i < nfonts; i++)
468 if (mfont__parse_name_into_font (names[i], Mx, &font) == 0
469 && (font.size > 0 || font.property[MFONT_RESY] == 0))
471 MSymbol family = FONT_PROPERTY (&font, MFONT_FAMILY);
476 int size, normal_size;
481 /* Calculate how many bytes to compare to detect fonts of the
483 for (base_end = names[i], fields = 0; *base_end; base_end++)
485 && ++fields == 7 /* PIXEL_SIZE */)
487 base_len = base_end - names[i] + 1;
489 size = font.size / 10;
490 sizes[nsizes++] = size;
491 normal_size = (size >= 6 && size <= 29);
492 limit = (i + 256 < nfonts ? i + 256 : nfonts);
493 for (j = i + 1; j < limit && ! memcmp (names[i], names[j], base_len);
495 if (mfont__parse_name_into_font (names[j], Mx, &font) == 0
496 && (font.size > 0 || font.property[MFONT_RESY] == 0))
498 size = font.size / 10;
499 sizes[nsizes++] = size;
500 normal_size |= (size >= 6 && size <= 29);
503 font.for_full_width = for_full_width;
504 font.type = MFONT_TYPE_OBJECT;
505 font.source = MFONT_SOURCE_X;
508 MSTRUCT_CALLOC (fontx, MERROR_WIN);
510 fontx->multiple_sizes = 1;
512 for (j = 0; j < nsizes; j++)
513 if (sizes[j] >= 6 && sizes[j] <= 29)
514 fontx->size |= 1 << (sizes[j] - 6);
515 p = mplist_add (p, family, fontx);
517 for (j = 0; j < nsizes; j++)
518 if (sizes[j] < 6 || sizes[j] > 29)
520 MSTRUCT_CALLOC (fontx, MERROR_WIN);
522 fontx->multiple_sizes = 0;
523 fontx->size = sizes[j] * 10;
525 fontx->property[MFONT_RESY] = 0;
526 p = mplist_add (p, family, fontx);
529 XFreeFontNames (font_names);
534 xfont_list_all (MFrame *frame)
536 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
537 MPlist *font_encoding_list, *p;
539 if (disp_info->all_fonts_scaned)
541 disp_info->all_fonts_scaned = 1;
542 font_encoding_list = mfont__encoding_list ();
543 if (! font_encoding_list)
545 MPLIST_DO (p, font_encoding_list)
546 xfont_registry_list (frame, MPLIST_KEY (p));
556 /* The X font driver function SELECT. */
559 xfont_select (MFrame *frame, MFont *font, int limited_size)
561 MPlist *plist = mplist (), *pl;
562 int num = xfont_list (frame, plist, font, 0);
566 MPLIST_DO (pl, plist)
568 font = MPLIST_VAL (pl);
569 if (limited_size == 0
571 || font->size <= limited_size)
577 M17N_OBJECT_UNREF (plist);
581 /* The X font driver function CLOSE. */
584 close_xfont (void *object)
586 MRealizedFontX *x_rfont = object;
588 XFreeFont (x_rfont->display, x_rfont->xfont);
592 /* The X font driver function OPEN. */
594 static MRealizedFont *
595 xfont_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
598 MRealizedFontX *x_rfont;
600 Display *display = FRAME_DISPLAY (frame);
602 int mdebug_flag = MDEBUG_FONT;
608 int ratio = mfont_resize_ratio (font);
611 size = size * ratio / 100;
618 /* non-scalable font */
619 if (font->multiple_sizes)
627 for (i = size / 10 - 6; i >= 0; i--)
628 if (font->size & (1 << i))
631 for (i = size / 10 - 5; i < 24; i++)
632 if (font->size & (1 << i))
642 for (; rfont; rfont = rfont->next)
643 if (rfont->font == font && rfont->spec.size == size)
648 this.multiple_sizes = 0;
650 /* This never fail to generate a valid fontname. */
651 name = mfont_unparse_name (&this, Mx);
652 xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
655 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
657 font->type = MFONT_TYPE_FAILURE;
660 M17N_OBJECT (x_rfont, close_xfont, MERROR_FONT_X);
661 x_rfont->display = display;
662 x_rfont->xfont = xfont;
663 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
664 rfont->id = msymbol (name);
666 rfont->spec.type = MFONT_TYPE_REALIZED;
667 rfont->spec.source = MFONT_SOURCE_X;
668 rfont->frame = frame;
670 rfont->driver = &xfont_driver;
671 rfont->info = x_rfont;
673 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
676 rfont->baseline_offset
677 = (XGetFontProperty (xfont, disp_info->MULE_BASELINE_OFFSET, &value)
678 ? (int) (value << 6) : 0);
680 = (XGetFontProperty (xfont, disp_info->AVERAGE_WIDTH, &value)
681 ? (int) (value << 6) / 10 : 0);
683 rfont->ascent = (xfont->ascent << 6) + rfont->baseline_offset;
684 rfont->descent = (xfont->descent << 6) - rfont->baseline_offset;
685 rfont->max_advance = xfont->max_bounds.width << 6;
686 rfont->x_ppem = rfont->y_ppem = size / 10;
687 rfont->fontp = xfont;
688 rfont->next = MPLIST_VAL (frame->realized_font_list);
689 MPLIST_VAL (frame->realized_font_list) = rfont;
690 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
696 /* The X font driver function FIND_METRIC. */
699 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
702 XFontStruct *xfont = rfont->fontp;
703 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
705 for (; g != gend; g++)
708 if (g->g.code == MCHAR_INVALID_CODE)
710 g->g.lbearing = xfont->max_bounds.lbearing << 6;
711 g->g.rbearing = xfont->max_bounds.rbearing << 6;
712 g->g.xadv = xfont->max_bounds.width << 6;
713 g->g.ascent = xfont->ascent << 6;
714 g->g.descent = xfont->descent << 6;
718 int byte1 = g->g.code >> 8, byte2 = g->g.code & 0xFF;
719 XCharStruct *pcm = NULL;
721 if (xfont->per_char != NULL)
723 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
726 && byte2 >= xfont->min_char_or_byte2
727 && byte2 <= xfont->max_char_or_byte2)
728 pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
732 if (byte1 >= xfont->min_byte1
733 && byte1 <= xfont->max_byte1
734 && byte2 >= xfont->min_char_or_byte2
735 && byte2 <= xfont->max_char_or_byte2)
737 pcm = (xfont->per_char
738 + ((xfont->max_char_or_byte2
739 - xfont->min_char_or_byte2 + 1)
740 * (byte1 - xfont->min_byte1))
741 + (byte2 - xfont->min_char_or_byte2));
748 g->g.lbearing = pcm->lbearing << 6;
749 g->g.rbearing = pcm->rbearing << 6;
750 g->g.xadv = pcm->width << 6;
751 g->g.ascent = pcm->ascent << 6;
752 g->g.descent = pcm->descent << 6;
756 /* If the per_char pointer is null, all glyphs between
757 the first and last character indexes inclusive have
758 the same information, as given by both min_bounds and
761 g->g.rbearing = xfont->max_bounds.width << 6;
762 g->g.xadv = xfont->max_bounds.width << 6;
763 g->g.ascent = xfont->ascent << 6;
764 g->g.descent = xfont->descent << 6;
768 g->g.ascent += rfont->baseline_offset;
769 g->g.descent -= rfont->baseline_offset;
776 xfont_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
778 return (xfont_encode_char (frame, font, spec, code) != MCHAR_INVALID_CODE);
781 /* The X font driver function GET_GLYPH_ID. */
784 xfont_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
786 MRealizedFont *rfont;
788 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
791 if (font->type == MFONT_TYPE_REALIZED)
792 rfont = (MRealizedFont *) font;
793 else if (font->type == MFONT_TYPE_OBJECT)
795 for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
797 if (rfont->font == font)
801 rfont = xfont_open (frame, font, spec, NULL);
803 return MCHAR_INVALID_CODE;
807 MFATAL (MERROR_FONT_X);
808 xfont = rfont->fontp;
809 all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True);
810 min_byte1 = xfont->min_byte1;
811 max_byte1 = xfont->max_byte1;
812 min_byte2 = xfont->min_char_or_byte2;
813 max_byte2 = xfont->max_char_or_byte2;
815 if (min_byte1 == 0 && max_byte1 == 0)
819 if (code < min_byte2 || code > max_byte2)
820 return MCHAR_INVALID_CODE;
823 pcm = xfont->per_char + (code - min_byte2);
824 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
825 ? code : MCHAR_INVALID_CODE);
829 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
832 if (byte1 < min_byte1 || byte1 > max_byte1
833 || byte2 < min_byte2 || byte2 > max_byte2)
834 return MCHAR_INVALID_CODE;
838 pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
839 + (byte2 - min_byte2));
840 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
841 ? code : MCHAR_INVALID_CODE);
845 /* The X font driver function RENDER. */
848 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
849 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
851 MRealizedFace *rface = from->rface;
852 Display *display = FRAME_DISPLAY (rface->frame);
854 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
862 baseline_offset = rface->rfont->baseline_offset >> 6;
864 gc = set_region (rface->frame, gc, region);
865 XSetFont (display, gc, ((XFontStruct *) rface->rfont->fontp)->fid);
866 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
867 for (i = 0, g = from; g < to; i++, g++)
869 code[i].byte1 = g->g.code >> 8;
870 code[i].byte2 = g->g.code & 0xFF;
876 if (g->type == GLYPH_PAD)
878 else if (g->type == GLYPH_SPACE)
879 for (; g < to && g->type == GLYPH_SPACE; g++)
881 else if (! g->rface->rfont)
883 if ((g->g.c >= 0x200B && g->g.c <= 0x200F)
884 || (g->g.c >= 0x202A && g->g.c <= 0x202E))
888 /* As a font is not found for this character, draw an
890 int box_width = g->g.xadv;
891 int box_height = gstring->ascent + gstring->descent;
897 XDrawRectangle (display, (Window) win, gc,
898 x, y - gstring->ascent, box_width, box_height);
902 else if (g->g.xoff != 0 || g->g.yoff != 0 || g->right_padding)
904 XDrawString16 (display, (Window) win, gc,
905 x + g->g.xoff, y + g->g.yoff - baseline_offset,
906 code + (g - from), 1);
913 int code_idx = g - from;
916 g < to && g->type == GLYPH_CHAR && g->g.xoff == 0 && g->g.yoff == 0;
919 XDrawString16 (display, (Window) win, gc,
920 orig_x, y - baseline_offset, code + code_idx, i);
926 xfont_list (MFrame *frame, MPlist *plist, MFont *font, int maxnum)
928 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
929 MSymbol registry = font ? FONT_PROPERTY (font, MFONT_REGISTRY) : Mnil;
930 MSymbol family = font ? FONT_PROPERTY (font, MFONT_FAMILY) : Mnil;
931 int size = font ? font->size : 0;
934 int mdebug_flag = MDEBUG_FONT;
936 MDEBUG_PRINT2 (" [X-FONT] listing %s-%s...",
937 family ? msymbol_name (family) : "*",
938 registry ? msymbol_name (registry) : "*");
940 if (registry == Mnil)
941 xfont_list_all (frame);
943 xfont_registry_list (frame, registry);
945 MPLIST_DO (pl, disp_info->font_list)
946 if (registry == Mnil || registry == MPLIST_KEY (pl))
948 MPLIST_DO (p, MPLIST_VAL (pl))
949 if (family == Mnil || family == MPLIST_KEY (p))
951 MFont *fontx = MPLIST_VAL (p);
953 if (! font || (mfont__match_p (fontx, font, MFONT_REGISTRY)))
955 if (fontx->size != 0 && size)
957 if (fontx->multiple_sizes)
959 if (size < 60 || size > 290
960 || ! (fontx->size & (1 << (size / 10 - 6))))
963 else if (fontx->size != size)
966 mplist_push (plist, MPLIST_KEY (p), fontx);
968 if (maxnum > 0 && maxnum == num)
975 MDEBUG_PRINT1 (" %d found\n", num);
980 xfont_list_family_names (MFrame *frame, MPlist *plist)
982 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
985 MSymbol last_family = Mnil;
987 font_names = XListFonts (disp_info->display,
988 "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", 0x8000, &nfonts);
989 for (i = 0; i < nfonts; i++)
992 char foundry[256], fam[256];
995 if (sscanf (font_names[i], "-%s-%s-", foundry, fam) < 2)
997 family = msymbol (fam);
998 if (family == last_family)
1000 last_family = family;
1002 MPLIST_DO (p, plist)
1004 MSymbol sym = MPLIST_SYMBOL (p);
1008 if (strcmp (MSYMBOL_NAME (sym), fam) > 0)
1010 mplist_push (p, Msymbol, family);
1014 if (MPLIST_TAIL_P (p))
1015 mplist_push (p, Msymbol, family);
1018 XFreeFontNames (font_names);
1022 xfont_check_capability (MRealizedFont *rfont, MSymbol capability)
1024 /* Currently X font driver doesn't support any capability. */
1036 FT_Face ft_face; /* This must be the 2nd member. */
1039 XftFont *font_no_aa;
1040 /* Pointer to MRealizedFontFT */
1044 static MRealizedFont *xft_open (MFrame *frame, MFont *font, MFont *spec,
1046 static int xft_has_char (MFrame *frame, MFont *font, MFont *spec,
1047 int c, unsigned code);
1048 static unsigned xft_encode_char (MFrame *frame, MFont *font, MFont *spec,
1050 static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
1051 static void xft_render (MDrawWindow, int, int, MGlyphString *,
1052 MGlyph *, MGlyph *, int, MDrawRegion);
1053 static int xft_check_capability (MRealizedFont *rfont, MSymbol capability);
1054 static int xft_check_otf (MFLTFont *font, MFLTOtfSpec *spec);
1055 static int xft_drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
1056 MFLTGlyphString *in, int from, int to,
1057 MFLTGlyphString *out,
1058 MFLTGlyphAdjustment *adjustment);
1059 static int xft_try_otf (MFLTFont *font, MFLTOtfSpec *spec,
1060 MFLTGlyphString *in, int from, int to);
1061 static int xft_iterate_otf_feature (struct _MFLTFont *font, MFLTOtfSpec *spec,
1062 int from, int to, unsigned char *table);
1065 static MFontDriver xft_driver =
1067 xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL, NULL,
1068 xft_check_capability, NULL, NULL, xft_check_otf, xft_drive_otf, xft_try_otf,
1070 xft_iterate_otf_feature
1071 #endif /* HAVE_OTF */
1075 close_xft (void *object)
1077 MRealizedFontXft *rfont_xft = object;
1079 if (rfont_xft->font_aa)
1080 XftFontClose (rfont_xft->display, rfont_xft->font_aa);
1081 if (rfont_xft->font_no_aa)
1082 XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
1083 M17N_OBJECT_UNREF (rfont_xft->info);
1089 xft_open_font (Display *display, MSymbol file, double size,
1095 pattern = FcPatternCreate ();
1096 FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
1097 FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
1098 FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
1099 font = XftFontOpenPattern (display, pattern);
1104 static MRealizedFont *
1105 xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
1107 Display *display = FRAME_DISPLAY (frame);
1108 int reg = spec->property[MFONT_REGISTRY];
1110 MRealizedFontXft *rfont_xft;
1111 FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
1114 int ascent, descent, max_advance, average_width, baseline_offset;
1117 /* non-scalable font */
1119 else if (spec->size)
1121 int ratio = mfont_resize_ratio (font);
1123 size = ratio == 100 ? spec->size : spec->size * ratio / 100;
1130 MRealizedFont *save = NULL;
1132 for (; rfont; rfont = rfont->next)
1133 if (rfont->font == font
1134 && (rfont->font->size ? rfont->font->size == size
1135 : rfont->spec.size == size)
1136 && rfont->spec.property[MFONT_REGISTRY] == reg)
1140 if (rfont->driver == &xft_driver)
1145 rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
1148 ascent = rfont->ascent;
1149 descent = rfont->descent;
1150 max_advance = rfont->max_advance;
1151 average_width = rfont->average_width;
1152 baseline_offset = rfont->baseline_offset;
1153 spec = &rfont->spec;
1154 ft_face = rfont->fontp;
1155 xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
1158 M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
1159 rfont_xft->display = display;
1160 if (anti_alias == FcTrue)
1161 rfont_xft->font_aa = xft_font;
1163 rfont_xft->font_no_aa = xft_font;
1164 rfont_xft->ft_face = ft_face;
1165 rfont_xft->info = rfont->info;
1166 M17N_OBJECT_REF (rfont->info);
1167 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
1168 rfont->id = font->file;
1169 rfont->spec = *spec;
1170 rfont->spec.size = size;
1171 rfont->frame = frame;
1173 rfont->driver = &xft_driver;
1174 rfont->info = rfont_xft;
1175 rfont->ascent = ascent;
1176 rfont->descent = descent;
1177 rfont->max_advance = max_advance;
1178 rfont->average_width = average_width;
1179 rfont->baseline_offset = baseline_offset;
1180 rfont->x_ppem = ft_face->size->metrics.x_ppem;
1181 rfont->y_ppem = ft_face->size->metrics.y_ppem;
1182 rfont->fontp = xft_font;
1183 rfont->next = MPLIST_VAL (frame->realized_font_list);
1184 MPLIST_VAL (frame->realized_font_list) = rfont;
1189 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1192 Display *display = FRAME_DISPLAY (rfont->frame);
1193 XftFont *xft_font = rfont->fontp;
1194 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1196 for (; g != gend; g++)
1197 if (! g->g.measured)
1199 if (g->g.code == MCHAR_INVALID_CODE)
1202 g->g.rbearing = xft_font->max_advance_width << 6;
1203 g->g.xadv = g->g.rbearing << 6;
1204 g->g.ascent = xft_font->ascent << 6;
1205 g->g.descent = xft_font->descent << 6;
1211 XftGlyphExtents (display, xft_font, &g->g.code, 1, &extents);
1212 g->g.lbearing = (- extents.x) << 6;
1213 g->g.rbearing = (extents.width - extents.x) << 6;
1214 g->g.xadv = extents.xOff << 6;
1215 g->g.ascent = extents.y << 6;
1216 g->g.descent = (extents.height - extents.y) << 6;
1224 xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
1228 if (font->type == MFONT_TYPE_REALIZED)
1230 MRealizedFont *rfont = (MRealizedFont *) font;
1231 MRealizedFontXft *rfont_xft = rfont->info;
1233 rfont->info = rfont_xft->info;
1234 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1235 rfont->info = rfont_xft;
1238 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1243 xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
1245 if (font->type == MFONT_TYPE_REALIZED)
1247 MRealizedFont *rfont = (MRealizedFont *) font;
1248 MRealizedFontXft *rfont_xft = rfont->info;
1250 rfont->info = rfont_xft->info;
1251 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1252 rfont->info = rfont_xft;
1255 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1260 xft_render (MDrawWindow win, int x, int y,
1261 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1262 int reverse, MDrawRegion region)
1264 MRealizedFace *rface = from->rface;
1265 MFrame *frame = rface->frame;
1266 Display *display = FRAME_DISPLAY (frame);
1267 MRealizedFont *rfont = rface->rfont;
1268 MRealizedFontXft *rfont_xft = rfont->info;
1269 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1270 XftColor *xft_color = (! reverse
1271 ? &((GCInfo *) rface->info)->xft_color_fore
1272 : &((GCInfo *) rface->info)->xft_color_back);
1273 int anti_alias = (gstring->control.anti_alias
1274 && FRAME_DEVICE (frame)->depth > 1);
1286 if (rfont_xft->font_aa)
1287 xft_font = rfont_xft->font_aa;
1290 double size = rfont->spec.size;
1292 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1295 rfont_xft->font_aa = xft_font;
1297 xft_font = rfont->fontp;
1302 if (rfont_xft->font_no_aa)
1303 xft_font = rfont_xft->font_no_aa;
1306 double size = rfont->spec.size;
1308 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1311 rfont_xft->font_no_aa = xft_font;
1313 xft_font = rfont->fontp;
1317 XftDrawChange (xft_draw, (Drawable) win);
1318 XftDrawSetClip (xft_draw, (Region) region);
1320 y -= rfont->baseline_offset >> 6;
1321 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1322 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->g.xadv)
1324 if (! g->g.adjusted && !g->left_padding && !g->right_padding)
1325 glyphs[nglyphs++] = g->g.code;
1329 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1330 last_x, y, glyphs, nglyphs);
1332 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1333 x + g->g.xoff, y + g->g.yoff, (FT_UInt *) &g->g.code, 1);
1334 last_x = x + g->g.xadv;
1338 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1342 xft_check_capability (MRealizedFont *rfont, MSymbol capability)
1344 MRealizedFontXft *rfont_xft = rfont->info;
1347 rfont->info = rfont_xft->info;
1348 result = mfont__ft_driver.check_capability (rfont, capability);
1349 rfont->info = rfont_xft;
1354 xft_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
1356 MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
1357 MRealizedFontXft *rfont_xft = rfont->info;
1360 rfont->info = rfont_xft->info;
1361 result = mfont__ft_driver.check_otf (font, spec);
1362 rfont->info = rfont_xft;
1367 xft_drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
1368 MFLTGlyphString *in, int from, int to,
1369 MFLTGlyphString *out,
1370 MFLTGlyphAdjustment *adjustment)
1372 MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
1373 MRealizedFontXft *rfont_xft = rfont->info;
1376 rfont->info = rfont_xft->info;
1377 result = mfont__ft_driver.drive_otf (font, spec, in, from, to, out,
1379 rfont->info = rfont_xft;
1384 xft_try_otf (MFLTFont *font, MFLTOtfSpec *spec,
1385 MFLTGlyphString *in, int from, int to)
1387 return xft_drive_otf (font, spec, in, from, to, NULL, NULL);
1393 xft_iterate_otf_feature (struct _MFLTFont *font, MFLTOtfSpec *spec,
1394 int from, int to, unsigned char *table)
1396 MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
1397 MRealizedFontXft *rfont_xft = rfont->info;
1400 rfont->info = rfont_xft->info;
1401 result = mfont__ft_driver.iterate_otf_feature (font, spec, from, to, table);
1402 rfont->info = rfont_xft;
1405 #endif /* HAVE_OTF */
1407 #endif /* HAVE_XFT2 */
1410 /* Functions for the device driver. */
1413 mwin__close_device (MFrame *frame)
1415 MWDevice *device = FRAME_DEVICE (frame);
1417 M17N_OBJECT_UNREF (device);
1421 mwin__device_get_prop (MFrame *frame, MSymbol key)
1423 MWDevice *device = FRAME_DEVICE (frame);
1425 if (key == Mdisplay)
1426 return (void *) device->display_info->display;
1428 return (void *) ScreenOfDisplay(device->display_info->display,
1429 device->screen_num);
1430 if (key == Mcolormap)
1431 return (void *) device->cmap;
1433 return (void *) device->depth;
1438 mwin__realize_face (MRealizedFace *rface)
1441 MSymbol foreground, background, videomode;
1442 MFaceHLineProp *hline;
1446 if (rface != rface->ascii_rface)
1448 rface->info = rface->ascii_rface->info;
1452 frame = rface->frame;
1453 MSTRUCT_CALLOC (info, MERROR_WIN);
1455 foreground = rface->face.property[MFACE_FOREGROUND];
1456 background = rface->face.property[MFACE_BACKGROUND];
1457 videomode = rface->face.property[MFACE_VIDEOMODE];
1459 videomode = frame->videomode;
1460 if (videomode != Mreverse)
1462 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1463 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1467 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1468 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1471 if (foreground == Mnil)
1472 foreground = frame->foreground;
1473 if (background == Mnil)
1474 background = frame->background;
1475 if (videomode == Mreverse)
1477 MSymbol temp = foreground;
1478 foreground = background;
1481 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1482 FRAME_VISUAL (frame),
1484 MSYMBOL_NAME (foreground),
1485 &info->xft_color_fore))
1487 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1488 FRAME_VISUAL (frame),
1490 MSYMBOL_NAME (background),
1491 &info->xft_color_back))
1493 #endif /* HAVE_XFT2 */
1495 hline = rface->hline;
1499 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1501 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1508 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1510 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1512 if (box->color_left && box->color_left != box->color_top)
1513 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1515 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1517 if (box->color_bottom && box->color_bottom != box->color_top)
1518 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1520 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1522 if (box->color_right && box->color_right != box->color_bottom)
1523 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1525 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1533 mwin__free_realized_face (MRealizedFace *rface)
1535 if (rface == rface->ascii_rface)
1541 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1543 int x, int y, int width, int height, MDrawRegion region)
1545 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1548 gc = set_region (frame, gc, region);
1550 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1551 x, y, width, height);
1556 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1557 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1558 int reverse, MDrawRegion region)
1560 MRealizedFace *rface = from->rface;
1561 Display *display = FRAME_DISPLAY (rface->frame);
1562 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1568 gc = set_region (rface->frame, gc, region);
1569 for (; from < to; from++)
1571 XDrawRectangle (display, (Window) win, gc,
1572 x, y - gstring->ascent + 1, from->g.xadv - 1,
1573 gstring->ascent + gstring->descent - 2);
1580 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1581 MRealizedFace *rface, int reverse,
1582 int x, int y, int width, MDrawRegion region)
1584 enum MFaceHLineType type = rface->hline->type;
1585 GCInfo *info = rface->info;
1586 GC gc = gc = info->gc[GC_HLINE];
1589 y = (type == MFACE_HLINE_BOTTOM
1590 ? y + gstring->text_descent - rface->hline->width
1591 : type == MFACE_HLINE_UNDER
1593 : type == MFACE_HLINE_STRIKE_THROUGH
1594 ? y - ((gstring->ascent + gstring->descent) / 2)
1595 : y - gstring->text_ascent);
1597 gc = set_region (frame, gc, region);
1599 for (i = 0; i < rface->hline->width; i++)
1600 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1601 x, y + i, x + width - 1, y + i);
1606 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1607 MGlyph *g, int x, int y, int width, MDrawRegion region)
1609 Display *display = FRAME_DISPLAY (frame);
1610 MRealizedFace *rface = g->rface;
1611 MFaceBoxProp *box = rface->box;
1612 GCInfo *info = rface->info;
1613 GC gc_top, gc_left, gc_right, gc_btm;
1617 y0 = y - (gstring->text_ascent
1618 + rface->box->inner_vmargin + rface->box->width);
1619 y1 = y + (gstring->text_descent
1620 + rface->box->inner_vmargin + rface->box->width - 1);
1622 gc_top = info->gc[GC_BOX_TOP];
1624 gc_top = set_region (frame, gc_top, region);
1625 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1628 gc_btm = info->gc[GC_BOX_BOTTOM];
1630 if (g->type == GLYPH_BOX)
1634 if (g->left_padding)
1635 x0 = x + box->outer_hmargin, x1 = x + g->g.xadv - 1;
1637 x0 = x, x1 = x + g->g.xadv - box->outer_hmargin - 1;
1639 /* Draw the top side. */
1640 for (i = 0; i < box->width; i++)
1641 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, 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, x0, y1 - i, x1, y1 - i);
1649 if (g->left_padding > 0)
1651 /* Draw the left side. */
1652 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1656 gc_left = info->gc[GC_BOX_LEFT];
1658 gc_left = set_region (frame, gc_left, region);
1660 for (i = 0; i < rface->box->width; i++)
1661 XDrawLine (display, (Window) win, gc_left,
1662 x0 + i, y0 + i, x0 + i, y1 - i);
1666 /* Draw the right side. */
1667 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1671 gc_right = info->gc[GC_BOX_RIGHT];
1673 gc_right = set_region (frame, gc_right, region);
1675 for (i = 0; i < rface->box->width; i++)
1676 XDrawLine (display, (Window) win, gc_right,
1677 x1 - i, y0 + i, x1 - i, y1 - i);
1682 /* Draw the top side. */
1683 for (i = 0; i < box->width; i++)
1684 XDrawLine (display, (Window) win, gc_top,
1685 x, y0 + i, x + width - 1, y0 + i);
1687 /* Draw the bottom side. */
1688 if (region && gc_btm != gc_top)
1689 gc_btm = set_region (frame, gc_btm, region);
1690 for (i = 0; i < box->width; i++)
1691 XDrawLine (display, (Window) win, gc_btm,
1692 x, y1 - i, x + width - 1, y1 - i);
1699 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1700 int reverse, int x, int y,
1701 int width, int height, int row_bytes, unsigned char *bmp,
1704 Display *display = FRAME_DISPLAY (frame);
1706 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1709 gc = set_region (frame, gc, region);
1711 for (i = 0; i < height; i++, bmp += row_bytes)
1712 for (j = 0; j < width; j++)
1713 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1714 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1719 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1720 int intensity, MDrawPoint *points, int num,
1723 GCInfo *info = rface->info;
1726 if (! (gc = info->gc[intensity]))
1727 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1730 gc = set_region (frame, gc, region);
1732 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1733 (XPoint *) points, num, CoordModeOrigin);
1738 mwin__region_from_rect (MDrawMetric *rect)
1740 MDrawRegion region1 = XCreateRegion ();
1741 MDrawRegion region2 = XCreateRegion ();
1746 xrect.width = rect->width;
1747 xrect.height = rect->height;
1748 XUnionRectWithRegion (&xrect, region1, region2);
1749 XDestroyRegion (region1);
1754 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1756 MDrawRegion region1 = XCreateRegion ();
1761 xrect.width = rect->width;
1762 xrect.height = rect->height;
1764 XUnionRegion (region, region, region1);
1765 XUnionRectWithRegion (&xrect, region1, region);
1766 XDestroyRegion (region1);
1770 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1772 MDrawRegion region = XCreateRegion ();
1774 XUnionRegion (region1, region1, region);
1775 XIntersectRegion (region, region2, region1);
1776 XDestroyRegion (region);
1780 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1782 MDrawRegion region1 = XCreateRegion ();
1787 xrect.width = rect->width;
1788 xrect.height = rect->height;
1789 XUnionRectWithRegion (&xrect, region1, region);
1790 XDestroyRegion (region1);
1794 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1798 XClipBox (region, &xrect);
1801 rect->width = xrect.width;
1802 rect->height = xrect.height;
1806 mwin__free_region (MDrawRegion region)
1808 XDestroyRegion (region);
1812 mwin__dump_region (MDrawRegion region)
1815 XClipBox (region, &rect);
1816 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1821 mwin__create_window (MFrame *frame, MDrawWindow parent)
1823 Display *display = FRAME_DISPLAY (frame);
1825 XWMHints wm_hints = { InputHint, False };
1826 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1827 XSetWindowAttributes set_attrs;
1830 GCInfo *info = frame->rface->info;
1833 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1834 mask = GCForeground;
1835 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1836 set_attrs.background_pixel = values.foreground;
1837 set_attrs.backing_store = Always;
1838 set_attrs.override_redirect = True;
1839 set_attrs.save_under = True;
1840 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1841 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1842 CopyFromParent, InputOutput, CopyFromParent,
1844 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1845 NULL, &wm_hints, &class_hints);
1846 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1847 return (MDrawWindow) win;
1851 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1854 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1856 if (XftDrawDrawable (xft_draw) == (Drawable) win)
1857 XftDrawChange (xft_draw, FRAME_DEVICE (frame)->drawable);
1858 #endif /* HAVE_XFT2 */
1859 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1864 mwin__event_window (void *event)
1866 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1870 mwin__print_event (void *arg, char *win_name)
1873 XEvent *event = (XEvent *) arg;
1875 switch (event->xany.type)
1877 case 2: event_name = "KeyPress"; break;
1878 case 3: event_name = "KeyRelease"; break;
1879 case 4: event_name = "ButtonPress"; break;
1880 case 5: event_name = "ButtonRelease"; break;
1881 case 6: event_name = "MotionNotify"; break;
1882 case 7: event_name = "EnterNotify"; break;
1883 case 8: event_name = "LeaveNotify"; break;
1884 case 9: event_name = "FocusIn"; break;
1885 case 10: event_name = "FocusOut"; break;
1886 case 11: event_name = "KeymapNotify"; break;
1887 case 12: event_name = "Expose"; break;
1888 case 13: event_name = "GraphicsExpose"; break;
1889 case 14: event_name = "NoExpose"; break;
1890 case 15: event_name = "VisibilityNotify"; break;
1891 case 16: event_name = "CreateNotify"; break;
1892 case 17: event_name = "DestroyNotify"; break;
1893 case 18: event_name = "UnmapNotify"; break;
1894 case 19: event_name = "MapNotify"; break;
1895 case 20: event_name = "MapRequest"; break;
1896 case 21: event_name = "ReparentNotify"; break;
1897 case 22: event_name = "ConfigureNotify"; break;
1898 case 23: event_name = "ConfigureRequest"; break;
1899 case 24: event_name = "GravityNotify"; break;
1900 case 25: event_name = "ResizeRequest"; break;
1901 case 26: event_name = "CirculateNotify"; break;
1902 case 27: event_name = "CirculateRequest"; break;
1903 case 28: event_name = "PropertyNotify"; break;
1904 case 29: event_name = "SelectionClear"; break;
1905 case 30: event_name = "SelectionRequest"; break;
1906 case 31: event_name = "SelectionNotify"; break;
1907 case 32: event_name = "ColormapNotify"; break;
1908 case 33: event_name = "ClientMessage"; break;
1909 case 34: event_name = "MappingNotify"; break;
1910 default: event_name = "unknown";
1913 fprintf (stderr, "%s: %s\n", win_name, event_name);
1918 mwin__map_window (MFrame *frame, MDrawWindow win)
1920 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1924 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1926 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1930 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1931 MDrawMetric *geometry)
1933 Display *display = FRAME_DISPLAY (frame);
1934 XWindowAttributes attr;
1935 Window parent = (Window) parent_win, root;
1937 XGetWindowAttributes (display, (Window) win, &attr);
1938 geometry->x = attr.x + attr.border_width;
1939 geometry->y = attr.y + attr.border_width;
1940 geometry->width = attr.width;
1941 geometry->height = attr.height;
1944 parent = RootWindow (display, FRAME_SCREEN (frame));
1947 Window this_parent, *children;
1950 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1953 if (this_parent == parent || this_parent == root)
1955 win = (MDrawWindow) this_parent;
1956 XGetWindowAttributes (display, (Window) win, &attr);
1957 geometry->x += attr.x + attr.border_width;
1958 geometry->y += attr.y + attr.border_width;
1963 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1964 MDrawMetric *current, MDrawMetric *new)
1966 Display *display = FRAME_DISPLAY (frame);
1967 unsigned int mask = 0;
1968 XWindowChanges values;
1970 if (current->width != new->width)
1973 if (new->width <= 0)
1975 values.width = current->width = new->width;
1977 if (current->height != new->height)
1980 if (new->height <= 0)
1982 values.height = current->height = new->height;
1984 if (current->x != new->x)
1987 values.x = current->x = new->x;
1989 if (current->y != new->y)
1992 current->y = new->y;
1993 values.y = current->y = new->y;
1996 XConfigureWindow (display, (Window) win, mask, &values);
1997 XClearWindow (display, (Window) win);
2001 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
2003 XEvent *event = (XEvent *) arg;
2004 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
2011 if (event->xany.type != KeyPress
2012 /* && event->xany.type != KeyRelease */
2015 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
2018 if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
2020 if (len == 1 && keysym >= XK_space && keysym <= XK_asciitilde)
2024 key = minput__char_to_key (c);
2025 if (c == ' ' && ((XKeyEvent *) event)->state & ShiftMask)
2026 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2030 char *str = XKeysymToString (keysym);
2034 key = msymbol (str);
2035 if (((XKeyEvent *) event)->state & ShiftMask)
2036 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2038 if (((XKeyEvent *) event)->state & ControlMask)
2039 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2040 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
2041 *modifiers |= MINPUT_KEY_META_MODIFIER;
2042 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
2043 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
2044 if (((XKeyEvent *) event)->state & disp_info->super_mask)
2045 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
2046 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
2047 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
2054 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
2056 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
2058 Display *display = FRAME_DISPLAY (frame);
2059 GCInfo *info = rface->info;
2062 for (i = 0; i <= GC_INVERSE; i++)
2064 XGetGCValues (display, info->gc[i], valuemask, &values);
2065 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
2066 values.foreground, values.background);
2067 fprintf (stderr, "\n");
2071 static MDeviceDriver x_driver =
2074 mwin__device_get_prop,
2076 mwin__free_realized_face,
2078 mwin__draw_empty_boxes,
2082 mwin__region_from_rect,
2083 mwin__union_rect_with_region,
2084 mwin__intersect_region,
2085 mwin__region_add_rect,
2086 mwin__region_to_rect,
2089 mwin__create_window,
2090 mwin__destroy_window,
2093 mwin__window_geometry,
2094 mwin__adjust_window,
2098 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
2103 M_iso8859_1 = msymbol ("iso8859-1");
2104 M_iso10646_1 = msymbol ("iso10646-1");
2106 display_info_list = mplist ();
2107 device_list = mplist ();
2110 xft_driver.select = mfont__ft_driver.select;
2111 xft_driver.list = mfont__ft_driver.list;
2112 xft_driver.list_family_names = mfont__ft_driver.list_family_names;
2115 Mxim = msymbol ("xim");
2116 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
2124 M17N_OBJECT_UNREF (display_info_list);
2125 M17N_OBJECT_UNREF (device_list);
2130 #ifdef X_SET_ERROR_HANDLER
2132 x_error_handler (Display *display, XErrorEvent *error)
2139 x_io_error_handler (Display *display)
2146 /** Return an MWDevice object corresponding to a display specified in
2149 It searches device_list for a device matching the display. If
2150 found, return the found object. Otherwise, return a newly created
2154 device_open (MFrame *frame, MPlist *param)
2156 Display *display = NULL;
2157 Screen *screen = NULL;
2159 Drawable drawable = 0;
2160 Widget widget = NULL;
2162 int auto_display = 0;
2163 MDisplayInfo *disp_info = NULL;
2164 MWDevice *device = NULL;
2166 XWindowAttributes attr;
2172 int use_xfont = 0, use_freetype = 0, use_xft = 0;
2174 for (plist = param; (key = mplist_key (plist)) != Mnil;
2175 plist = mplist_next (plist))
2177 if (key == Mdisplay)
2178 display = (Display *) mplist_value (plist);
2179 else if (key == Mscreen)
2180 screen = mplist_value (plist);
2181 else if (key == Mdrawable)
2182 drawable = (Drawable) mplist_value (plist);
2183 else if (key == Mdepth)
2184 depth = (unsigned) mplist_value (plist);
2185 else if (key == Mwidget)
2186 widget = (Widget) mplist_value (plist);
2187 else if (key == Mcolormap)
2188 cmap = (Colormap) mplist_value (plist);
2189 else if (key == Mfont)
2191 MSymbol val = MPLIST_SYMBOL (plist);
2195 #ifdef HAVE_FREETYPE
2196 else if (val == Mfreetype)
2199 else if (val == Mxft)
2206 /* If none of them is specified, use all of them. */
2207 if (! use_xfont && ! use_freetype && ! use_xft)
2208 use_xfont = use_freetype = use_xft = 1;
2212 display = XtDisplay (widget);
2213 screen_num = XScreenNumberOfScreen (XtScreen (widget));
2214 depth = DefaultDepth (display, screen_num);
2220 unsigned width, height, border_width;
2223 MERROR (MERROR_WIN, -1);
2224 XGetGeometry (display, drawable, &root_window,
2225 &x, &y, &width, &height, &border_width, &depth);
2226 XGetWindowAttributes (display, root_window, &attr);
2227 screen_num = XScreenNumberOfScreen (attr.screen);
2232 display = DisplayOfScreen (screen);
2237 display = XOpenDisplay (NULL);
2239 MERROR (MERROR_WIN, -1);
2242 screen = DefaultScreenOfDisplay (display);
2244 screen_num = XScreenNumberOfScreen (screen);
2246 depth = DefaultDepth (display, screen_num);
2250 cmap = DefaultColormap (display, screen_num);
2252 for (plist = display_info_list; mplist_key (plist) != Mnil;
2253 plist = mplist_next (plist))
2255 disp_info = (MDisplayInfo *) mplist_value (plist);
2256 if (disp_info->display == display)
2260 if (mplist_key (plist) != Mnil)
2261 M17N_OBJECT_REF (disp_info);
2264 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2265 disp_info->display = display;
2266 disp_info->auto_display = auto_display;
2267 disp_info->font_list = mplist ();
2268 find_modifier_bits (disp_info);
2269 disp_info->MULE_BASELINE_OFFSET
2270 = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
2271 disp_info->AVERAGE_WIDTH
2272 = XInternAtom (display, "AVERAGE_WIDTH", False);
2273 mplist_add (display_info_list, Mt, disp_info);
2276 for (plist = device_list; mplist_key (plist) != Mnil;
2277 plist = mplist_next (plist))
2279 device = (MWDevice *) mplist_value (plist);
2280 if (device->display_info == disp_info
2281 && device->depth == depth
2282 && device->cmap == cmap
2283 && device->screen_num == screen_num)
2287 if (mplist_key (plist) != Mnil)
2288 M17N_OBJECT_REF (device);
2291 unsigned long valuemask = GCForeground;
2295 M17N_OBJECT (device, free_device, MERROR_WIN);
2296 device->display_info = disp_info;
2297 device->screen_num = screen_num;
2298 /* A drawable on which to create GCs. */
2299 device->drawable = XCreatePixmap (display,
2300 RootWindow (display, screen_num),
2302 device->depth = depth;
2303 device->cmap = cmap;
2304 pixels = DisplayHeight (display, screen_num);
2305 mm = DisplayHeightMM (display, screen_num);
2306 device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
2307 device->realized_face_list = mplist ();
2308 device->realized_font_list = mplist ();
2309 mplist_add (device->realized_font_list, Mt, NULL);
2310 device->realized_fontset_list = mplist ();
2311 device->gc_list = mplist ();
2312 values.foreground = BlackPixel (display, screen_num);
2313 device->scratch_gc = XCreateGC (display, device->drawable,
2314 valuemask, &values);
2316 device->xft_draw = XftDrawCreate (display, device->drawable,
2317 DefaultVisual (display, screen_num),
2322 frame->device = device;
2323 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2324 frame->dpi = device->resy;
2325 frame->driver = &x_driver;
2326 frame->font_driver_list = mplist ();
2330 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2333 #endif /* HAVE_XFT2 */
2334 #ifdef HAVE_FREETYPE
2336 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2337 #endif /* HAVE_FREETYPE */
2338 if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
2339 mplist_add (frame->font_driver_list, Mx, &xfont_driver);
2341 frame->realized_font_list = device->realized_font_list;
2342 frame->realized_face_list = device->realized_face_list;
2343 frame->realized_fontset_list = device->realized_fontset_list;
2347 XtResource resources[] = {
2348 { XtNfont, XtCFont, XtRString, sizeof (String),
2349 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2350 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2351 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2352 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2353 XtOffset (AppDataPtr, background), XtRString, "white" },
2354 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2355 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2358 XtGetApplicationResources (widget, &app_data,
2359 resources, XtNumber (resources), NULL, 0);
2360 frame->foreground = msymbol (app_data.foreground);
2361 frame->background = msymbol (app_data.background);
2362 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2366 app_data.font = DEFAULT_FONT;
2367 frame->foreground = msymbol ("black");
2368 frame->background = msymbol ("white");
2369 frame->videomode = Mnormal;
2372 if (strcmp (app_data.font, DEFAULT_FONT) != 0)
2374 XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
2375 unsigned long value;
2380 font = mfont_parse_name (app_data.font, Mx);
2382 && XGetFontProperty (xfont, XA_FONT, &value)
2383 && (name = ((char *) XGetAtomName (display, (Atom) value))))
2384 font = mfont_parse_name (name, Mx);
2385 XFreeFont (display, xfont);
2389 font = mfont_parse_name (DEFAULT_FONT, Mx);
2390 else if (! font->size)
2392 face = mface_from_font (font);
2394 face->property[MFACE_FONTSET] = mfontset (NULL);
2395 face->property[MFACE_FOREGROUND] = frame->foreground;
2396 face->property[MFACE_BACKGROUND] = frame->background;
2397 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2398 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2399 face->property[MFACE_VIDEOMODE] = frame->videomode;
2400 mface_put_prop (face, Mhook_func,
2401 mface_get_prop (mface__default, Mhook_func));
2402 face->property[MFACE_RATIO] = (void *) 100;
2403 mplist_push (param, Mface, face);
2404 M17N_OBJECT_UNREF (face);
2406 #ifdef X_SET_ERROR_HANDLER
2407 XSetErrorHandler (x_error_handler);
2408 XSetIOErrorHandler (x_io_error_handler);
2415 /* XIM (X Input Method) handler */
2417 typedef struct MInputXIMMethodInfo
2423 } MInputXIMMethodInfo;
2425 typedef struct MInputXIMContextInfo
2429 MConverter *converter;
2430 } MInputXIMContextInfo;
2433 xim_open_im (MInputMethod *im)
2435 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
2436 MLocale *saved, *this;
2437 char *save_modifier_list;
2439 MInputXIMMethodInfo *im_info;
2441 saved = mlocale_set (LC_CTYPE, NULL);
2442 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
2444 /* The specified locale is not supported. */
2445 MERROR (MERROR_LOCALE, -1);
2446 if (mlocale_get_prop (this, Mcoding) == Mnil)
2448 /* Unable to decode the output of XIM. */
2449 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2450 MERROR (MERROR_LOCALE, -1);
2453 if (arg->modifier_list)
2454 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
2456 save_modifier_list = XSetLocaleModifiers ("");
2457 if (! save_modifier_list)
2459 /* The specified locale is not supported by X. */
2460 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2461 MERROR (MERROR_LOCALE, -1);
2464 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
2467 /* No input method is available in the current locale. */
2468 XSetLocaleModifiers (save_modifier_list);
2469 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2470 MERROR (MERROR_WIN, -1);
2473 MSTRUCT_MALLOC (im_info, MERROR_WIN);
2474 im_info->display = arg->display;
2476 im_info->language = mlocale_get_prop (this, Mlanguage);
2477 im_info->coding = mlocale_get_prop (this, Mcoding);
2480 XSetLocaleModifiers (save_modifier_list);
2481 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2487 xim_close_im (MInputMethod *im)
2489 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
2491 XCloseIM (im_info->xim);
2496 xim_create_ic (MInputContext *ic)
2498 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
2499 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2500 MInputXIMContextInfo *ic_info;
2503 if (! arg->input_style)
2505 /* By default, use Root style. */
2506 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
2507 arg->preedit_attrs = NULL;
2508 arg->status_attrs = NULL;
2511 if (! arg->preedit_attrs && ! arg->status_attrs)
2512 xic = XCreateIC (im_info->xim,
2513 XNInputStyle, arg->input_style,
2514 XNClientWindow, arg->client_win,
2515 XNFocusWindow, arg->focus_win,
2517 else if (arg->preedit_attrs && ! arg->status_attrs)
2518 xic = XCreateIC (im_info->xim,
2519 XNInputStyle, arg->input_style,
2520 XNClientWindow, arg->client_win,
2521 XNFocusWindow, arg->focus_win,
2522 XNPreeditAttributes, arg->preedit_attrs,
2524 else if (! arg->preedit_attrs && arg->status_attrs)
2525 xic = XCreateIC (im_info->xim,
2526 XNInputStyle, arg->input_style,
2527 XNClientWindow, arg->client_win,
2528 XNFocusWindow, arg->focus_win,
2529 XNStatusAttributes, arg->status_attrs,
2532 xic = XCreateIC (im_info->xim,
2533 XNInputStyle, arg->input_style,
2534 XNClientWindow, arg->client_win,
2535 XNFocusWindow, arg->focus_win,
2536 XNPreeditAttributes, arg->preedit_attrs,
2537 XNStatusAttributes, arg->status_attrs,
2540 MERROR (MERROR_WIN, -1);
2542 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
2544 ic_info->win = arg->focus_win;
2545 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
2551 xim_destroy_ic (MInputContext *ic)
2553 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2555 XDestroyIC (ic_info->xic);
2556 mconv_free_converter (ic_info->converter);
2562 xim_filter (MInputContext *ic, MSymbol key, void *event)
2564 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2566 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
2571 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2573 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2574 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2575 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
2581 buf = (char *) alloca (512);
2582 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
2583 if (status == XBufferOverflow)
2585 buf = (char *) alloca (len);
2586 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
2589 mtext_reset (ic->produced);
2593 mconv_reset_converter (ic_info->converter);
2594 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
2595 mconv_decode (ic_info->converter, ic->produced);
2596 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2597 Mlanguage, (void *) im_info->language);
2598 mtext_cpy (mt, ic->produced);
2599 mtext_reset (ic->produced);
2607 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2611 /*** @addtogroup m17nInputMethodWin */
2616 @brief Input method driver for XIM.
2618 The driver #minput_xim_driver is for the foreign input method of
2619 name #Mxim. It uses XIM (X Input Methods) as a background input
2622 As the symbol #Mxim has property #Minput_driver whose value is
2623 a pointer to this driver, the input method of language #Mnil
2624 and name #Mxim uses this driver.
2626 Therefore, for such input methods, the driver dependent arguments
2627 to the functions whose name begin with minput_ must be as follows.
2629 The argument $ARG of the function minput_open_im () must be a
2630 pointer to the structure #MInputXIMArgIM. See the documentation
2631 of #MInputXIMArgIM for more details.
2633 The argument $ARG of the function minput_create_ic () must be a
2634 pointer to the structure #MInputXIMArgIC. See the documentation
2635 of #MInputXIMArgIC for more details.
2637 The argument $ARG of the function minput_filter () must be a
2638 pointer to the structure @c XEvent. The argument $KEY is ignored.
2640 The argument $ARG of the function minput_lookup () must be the
2641 same one as that of the function minput_filter (). The argument
2645 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2647 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
2648 XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2650 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2651 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
2652 ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2654 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
2655 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2657 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
2658 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
2660 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
2661 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
2663 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
2664 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2666 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2667 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
2669 MInputDriver minput_xim_driver =
2670 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2671 xim_filter, xim_lookup, NULL };
2675 #else /* not HAVE_X11 */
2677 int device_open () { return -1; }
2679 #endif /* not HAVE_X11 */