1 /* m17n-X.c -- implementation of the GUI API on X Windows.
2 Copyright (C) 2003, 2004
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
28 /*** @addtogroup m17nInternal
38 #include <X11/keysym.h>
39 #include <X11/Xlocale.h>
40 #include <X11/Xutil.h>
41 #include <X11/Xresource.h>
42 #include <X11/Xatom.h>
43 #include <X11/StringDefs.h>
44 #include <X11/Intrinsic.h>
47 #include <X11/Xft/Xft.h>
48 #include <fontconfig/fcfreetype.h>
49 #endif /* HAVE_XFT2 */
53 #include "m17n-misc.h"
55 #include "internal-gui.h"
64 /* Common header for the m17n object. */
69 /* If nonzero, <display> is opened by this library. Thus it should
70 be closed on freeing this structure. */
73 /** List of available X-core fonts on the display. Keys are
74 registries and values are plists whose keys are families and
75 values are pointers to MFont. */
78 /** Nonzero means that <font_list> already contains all available
79 fonts on the display. */
82 /** Modifier bit masks of the display. */
88 Atom MULE_BASELINE_OFFSET;
92 /* Anchor of the chain of MDisplayInfo objects. */
93 static MPlist *display_info_list;
96 /* Color value and the corresponding GC. */
99 unsigned int rgb; /* (red << 16) | (green << 8) | blue */
106 GC_NORMAL = GC_INVERSE + 7,
119 /* The first 8 elements are indexed by an intensity for
120 anti-aliasing. The 2nd to 7th are created on demand. */
123 XftColor xft_color_fore, xft_color_back;
129 /* Common header for the m17n object. */
132 MDisplayInfo *display_info;
150 /** List of pointers to realized faces on the frame. */
151 MPlist *realized_face_list;
153 /* List of single element whose value is a root of chain of realized
155 MPlist *realized_font_list;
157 /** List of pointers to realized fontsets on the frame. */
158 MPlist *realized_fontset_list;
160 /** List of XColors vs GCs on the frame. */
164 static MPlist *device_list;
166 static MSymbol M_iso8859_1, M_iso10646_1;
168 #define FRAME_DEVICE(frame) ((MWDevice *) (frame)->device)
169 #define FRAME_DISPLAY(frame) (FRAME_DEVICE (frame)->display_info->display)
170 #define FRAME_SCREEN(frame) (FRAME_DEVICE (frame)->screen_num)
171 #define FRAME_CMAP(frame) (FRAME_DEVICE (frame)->cmap)
172 #define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
173 FRAME_SCREEN (frame))
175 #define DEFAULT_FONT "-*-*-medium-r-normal--13-*-*-*-c-*-iso8859-1"
182 Boolean reverse_video;
183 } AppData, *AppDataPtr;
186 free_display_info (void *object)
188 MDisplayInfo *disp_info = (MDisplayInfo *) object;
191 MPLIST_DO (plist, disp_info->font_list)
193 MPLIST_DO (pl, MPLIST_VAL (plist))
194 free (MPLIST_VAL (pl));
195 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
197 M17N_OBJECT_UNREF (disp_info->font_list);
199 if (disp_info->auto_display)
200 XCloseDisplay (disp_info->display);
206 free_device (void *object)
208 MWDevice *device = object;
211 for (plist = device->realized_fontset_list;
212 mplist_key (plist) != Mnil; plist = mplist_next (plist))
213 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
214 M17N_OBJECT_UNREF (device->realized_fontset_list);
216 if (MPLIST_VAL (device->realized_font_list))
217 mfont__free_realized (MPLIST_VAL (device->realized_font_list));
218 M17N_OBJECT_UNREF (device->realized_font_list);
220 MPLIST_DO (plist, device->realized_face_list)
222 MRealizedFace *rface = MPLIST_VAL (plist);
225 mface__free_realized (rface);
227 M17N_OBJECT_UNREF (device->realized_face_list);
229 MPLIST_DO (plist, device->gc_list)
231 XFreeGC (device->display_info->display,
232 ((RGB_GC *) MPLIST_VAL (plist))->gc);
233 free (MPLIST_VAL (plist));
235 M17N_OBJECT_UNREF (device->gc_list);
236 XFreeGC (device->display_info->display, device->scratch_gc);
239 XftDrawDestroy (device->xft_draw);
242 XFreePixmap (device->display_info->display, device->drawable);
243 M17N_OBJECT_UNREF (device->display_info);
249 find_modifier_bits (MDisplayInfo *disp_info)
251 Display *display = disp_info->display;
252 XModifierKeymap *mods;
253 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
254 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
255 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
256 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
257 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
258 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
259 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
260 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
263 mods = XGetModifierMapping (display);
264 /* We skip the first three sets for Shift, Lock, and Control. The
265 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
266 for (i = 3; i < 8; i++)
267 for (j = 0; j < mods->max_keypermod; j++)
269 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
273 if (code == meta_l || code == meta_r)
274 disp_info->meta_mask |= (1 << i);
275 else if (code == alt_l || code == alt_r)
276 disp_info->alt_mask |= (1 << i);
277 else if (code == super_l || code == super_r)
278 disp_info->super_mask |= (1 << i);
279 else if (code == hyper_l || code == hyper_r)
280 disp_info->hyper_mask |= (1 << i);
283 /* If meta keys are not in any modifier, use alt keys as meta
285 if (! disp_info->meta_mask)
287 disp_info->meta_mask = disp_info->alt_mask;
288 disp_info->alt_mask = 0;
290 /* If both meta and alt are assigned to the same modifier, give meta
292 if (disp_info->meta_mask & disp_info->alt_mask)
293 disp_info->alt_mask &= ~disp_info->meta_mask;
295 XFreeModifiermap (mods);
299 get_rgb_gc (MWDevice *device, XColor *xcolor)
301 int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
302 | (xcolor->blue >> 8));
305 unsigned long valuemask = GCForeground;
308 MPLIST_DO (plist, device->gc_list)
310 rgb_gc = MPLIST_VAL (plist);
312 if (rgb_gc->rgb == rgb)
314 if (rgb_gc->rgb > rgb)
318 if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
321 rgb_gc = malloc (sizeof (RGB_GC));
323 values.foreground = xcolor->pixel;
324 rgb_gc->gc = XCreateGC (device->display_info->display,
325 device->drawable, valuemask, &values);
326 mplist_push (plist, Mt, rgb_gc);
331 get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
333 MWDevice *device = FRAME_DEVICE (frame);
341 color = for_foreground ? frame->foreground : frame->background;
343 if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
344 msymbol_name (color), &xcolor))
346 rgb_gc = get_rgb_gc (device, &xcolor);
350 *rgb_ret = rgb_gc->rgb;
355 GCInfo *info = frame->rface->info;
360 rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
362 rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
370 get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
372 int rgb_fore, rgb_back;
377 if (info->gc[intensity])
378 return info->gc[intensity];
380 rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
381 xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
382 + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
383 xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
384 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
385 xcolor.blue = (((rgb_fore & 0xFF) * intensity
386 + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
387 rgb_gc = get_rgb_gc (device, &xcolor);
391 gc =get_gc_for_anti_alias (device, info,
392 intensity < 4 ? intensity - 1 : intensity + 1);
393 return (info->gc[intensity] = gc);
397 set_region (MFrame *frame, GC gc, MDrawRegion region)
399 unsigned long valuemask = GCForeground;
401 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
402 FRAME_DEVICE (frame)->scratch_gc);
403 XSetRegion (FRAME_DISPLAY (frame), FRAME_DEVICE (frame)->scratch_gc, region);
404 return FRAME_DEVICE (frame)->scratch_gc;
408 /** X font handler */
410 static MFont *xfont_select (MFrame *, MFont *, int);
411 static MRealizedFont *xfont_open (MFrame *, MFont *, MFont *, MRealizedFont *);
412 static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
413 static int xfont_has_char (MFrame *, MFont *, MFont *, int, unsigned);
414 static unsigned xfont_encode_char (MFrame *, MFont *, MFont *, unsigned);
415 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
416 MGlyph *, MGlyph *, int, MDrawRegion);
417 static int xfont_list (MFrame *, MPlist *, MFont *, int);
418 static void xfont_list_family_names (MFrame *, MPlist *);
419 static int xfont_check_capability (MRealizedFont *rfont, MSymbol capability);
421 static MFontDriver xfont_driver =
422 { xfont_select, xfont_open,
423 xfont_find_metric, xfont_has_char, xfont_encode_char,
424 xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability
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_iterate_otf_feature (struct _MFLTFont *font, MFLTOtfSpec *spec,
1060 int from, int to, unsigned char *table);
1063 static MFontDriver xft_driver =
1065 xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL, NULL,
1066 xft_check_capability, NULL, NULL, xft_check_otf, xft_drive_otf,
1068 xft_iterate_otf_feature
1069 #endif /* HAVE_OTF */
1073 close_xft (void *object)
1075 MRealizedFontXft *rfont_xft = object;
1077 if (rfont_xft->font_aa)
1078 XftFontClose (rfont_xft->display, rfont_xft->font_aa);
1079 if (rfont_xft->font_no_aa)
1080 XftFontClose (rfont_xft->display, rfont_xft->font_no_aa);
1081 M17N_OBJECT_UNREF (rfont_xft->info);
1087 xft_open_font (Display *display, MSymbol file, double size,
1093 pattern = FcPatternCreate ();
1094 FcPatternAddString (pattern, FC_FILE, (FcChar8 *) msymbol_name (file));
1095 FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
1096 FcPatternAddBool (pattern, FC_ANTIALIAS, anti_alias);
1097 font = XftFontOpenPattern (display, pattern);
1102 static MRealizedFont *
1103 xft_open (MFrame *frame, MFont *font, MFont *spec, MRealizedFont *rfont)
1105 Display *display = FRAME_DISPLAY (frame);
1106 int reg = spec->property[MFONT_REGISTRY];
1108 MRealizedFontXft *rfont_xft;
1109 FcBool anti_alias = FRAME_DEVICE (frame)->depth > 1 ? FcTrue : FcFalse;
1112 int ascent, descent, max_advance, average_width, baseline_offset;
1115 /* non-scalable font */
1117 else if (spec->size)
1119 int ratio = mfont_resize_ratio (font);
1121 size = ratio == 100 ? spec->size : spec->size * ratio / 100;
1128 MRealizedFont *save = NULL;
1130 for (; rfont; rfont = rfont->next)
1131 if (rfont->font == font
1132 && (rfont->font->size ? rfont->font->size == size
1133 : rfont->spec.size == size)
1134 && rfont->spec.property[MFONT_REGISTRY] == reg)
1138 if (rfont->driver == &xft_driver)
1143 rfont = (mfont__ft_driver.open) (frame, font, spec, rfont);
1146 ascent = rfont->ascent;
1147 descent = rfont->descent;
1148 max_advance = rfont->max_advance;
1149 average_width = rfont->average_width;
1150 baseline_offset = rfont->baseline_offset;
1151 spec = &rfont->spec;
1152 ft_face = rfont->fontp;
1153 xft_font = xft_open_font (display, font->file, size / 10, anti_alias);
1156 M17N_OBJECT (rfont_xft, close_xft, MERROR_WIN);
1157 rfont_xft->display = display;
1158 if (anti_alias == FcTrue)
1159 rfont_xft->font_aa = xft_font;
1161 rfont_xft->font_no_aa = xft_font;
1162 rfont_xft->ft_face = ft_face;
1163 rfont_xft->info = rfont->info;
1164 M17N_OBJECT_REF (rfont->info);
1165 MSTRUCT_CALLOC (rfont, MERROR_FONT_X);
1166 rfont->id = font->file;
1167 rfont->spec = *spec;
1168 rfont->spec.size = size;
1169 rfont->frame = frame;
1171 rfont->driver = &xft_driver;
1172 rfont->info = rfont_xft;
1173 rfont->ascent = ascent;
1174 rfont->descent = descent;
1175 rfont->max_advance = max_advance;
1176 rfont->average_width = average_width;
1177 rfont->baseline_offset = baseline_offset;
1178 rfont->x_ppem = ft_face->size->metrics.x_ppem;
1179 rfont->y_ppem = ft_face->size->metrics.y_ppem;
1180 rfont->fontp = xft_font;
1181 rfont->next = MPLIST_VAL (frame->realized_font_list);
1182 MPLIST_VAL (frame->realized_font_list) = rfont;
1187 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1190 Display *display = FRAME_DISPLAY (rfont->frame);
1191 XftFont *xft_font = rfont->fontp;
1192 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1194 for (; g != gend; g++)
1195 if (! g->g.measured)
1197 if (g->g.code == MCHAR_INVALID_CODE)
1200 g->g.rbearing = xft_font->max_advance_width << 6;
1201 g->g.xadv = g->g.rbearing << 6;
1202 g->g.ascent = xft_font->ascent << 6;
1203 g->g.descent = xft_font->descent << 6;
1209 XftGlyphExtents (display, xft_font, &g->g.code, 1, &extents);
1210 g->g.lbearing = (- extents.x) << 6;
1211 g->g.rbearing = (extents.width - extents.x) << 6;
1212 g->g.xadv = extents.xOff << 6;
1213 g->g.ascent = extents.y << 6;
1214 g->g.descent = (extents.height - extents.y) << 6;
1222 xft_has_char (MFrame *frame, MFont *font, MFont *spec, int c, unsigned code)
1226 if (font->type == MFONT_TYPE_REALIZED)
1228 MRealizedFont *rfont = (MRealizedFont *) font;
1229 MRealizedFontXft *rfont_xft = rfont->info;
1231 rfont->info = rfont_xft->info;
1232 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1233 rfont->info = rfont_xft;
1236 result = mfont__ft_driver.has_char (frame, font, spec, c, code);
1241 xft_encode_char (MFrame *frame, MFont *font, MFont *spec, unsigned code)
1243 if (font->type == MFONT_TYPE_REALIZED)
1245 MRealizedFont *rfont = (MRealizedFont *) font;
1246 MRealizedFontXft *rfont_xft = rfont->info;
1248 rfont->info = rfont_xft->info;
1249 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1250 rfont->info = rfont_xft;
1253 code = mfont__ft_driver.encode_char (frame, font, spec, code);
1258 xft_render (MDrawWindow win, int x, int y,
1259 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1260 int reverse, MDrawRegion region)
1262 MRealizedFace *rface = from->rface;
1263 MFrame *frame = rface->frame;
1264 Display *display = FRAME_DISPLAY (frame);
1265 MRealizedFont *rfont = rface->rfont;
1266 MRealizedFontXft *rfont_xft = rfont->info;
1267 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1268 XftColor *xft_color = (! reverse
1269 ? &((GCInfo *) rface->info)->xft_color_fore
1270 : &((GCInfo *) rface->info)->xft_color_back);
1271 int anti_alias = (gstring->control.anti_alias
1272 && FRAME_DEVICE (frame)->depth > 1);
1284 if (rfont_xft->font_aa)
1285 xft_font = rfont_xft->font_aa;
1288 double size = rfont->spec.size;
1290 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1293 rfont_xft->font_aa = xft_font;
1295 xft_font = rfont->fontp;
1300 if (rfont_xft->font_no_aa)
1301 xft_font = rfont_xft->font_no_aa;
1304 double size = rfont->spec.size;
1306 xft_font = xft_open_font (display, rfont->spec.file, size / 10,
1309 rfont_xft->font_no_aa = xft_font;
1311 xft_font = rfont->fontp;
1315 XftDrawChange (xft_draw, (Drawable) win);
1316 XftDrawSetClip (xft_draw, (Region) region);
1318 y -= rfont->baseline_offset >> 6;
1319 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1320 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->g.xadv)
1322 if (! g->g.adjusted && !g->left_padding && !g->right_padding)
1323 glyphs[nglyphs++] = g->g.code;
1327 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1328 last_x, y, glyphs, nglyphs);
1330 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1331 x + g->g.xoff, y + g->g.yoff, (FT_UInt *) &g->g.code, 1);
1332 last_x = x + g->g.xadv;
1336 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1340 xft_check_capability (MRealizedFont *rfont, MSymbol capability)
1342 MRealizedFontXft *rfont_xft = rfont->info;
1345 rfont->info = rfont_xft->info;
1346 result = mfont__ft_driver.check_capability (rfont, capability);
1347 rfont->info = rfont_xft;
1352 xft_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
1354 MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
1355 MRealizedFontXft *rfont_xft = rfont->info;
1358 rfont->info = rfont_xft->info;
1359 result = mfont__ft_driver.check_otf (font, spec);
1360 rfont->info = rfont_xft;
1365 xft_drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
1366 MFLTGlyphString *in, int from, int to,
1367 MFLTGlyphString *out,
1368 MFLTGlyphAdjustment *adjustment)
1370 MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
1371 MRealizedFontXft *rfont_xft = rfont->info;
1374 rfont->info = rfont_xft->info;
1375 result = mfont__ft_driver.drive_otf (font, spec, in, from, to, out,
1377 rfont->info = rfont_xft;
1384 xft_iterate_otf_feature (struct _MFLTFont *font, MFLTOtfSpec *spec,
1385 int from, int to, unsigned char *table)
1387 MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
1388 MRealizedFontXft *rfont_xft = rfont->info;
1391 rfont->info = rfont_xft->info;
1392 result = mfont__ft_driver.iterate_otf_feature (font, spec, from, to, table);
1393 rfont->info = rfont_xft;
1396 #endif /* HAVE_OTF */
1398 #endif /* HAVE_XFT2 */
1401 /* Functions for the device driver. */
1404 mwin__close_device (MFrame *frame)
1406 MWDevice *device = FRAME_DEVICE (frame);
1408 M17N_OBJECT_UNREF (device);
1412 mwin__device_get_prop (MFrame *frame, MSymbol key)
1414 MWDevice *device = FRAME_DEVICE (frame);
1416 if (key == Mdisplay)
1417 return (void *) device->display_info->display;
1419 return (void *) ScreenOfDisplay(device->display_info->display,
1420 device->screen_num);
1421 if (key == Mcolormap)
1422 return (void *) device->cmap;
1424 return (void *) device->depth;
1429 mwin__realize_face (MRealizedFace *rface)
1432 MSymbol foreground, background, videomode;
1433 MFaceHLineProp *hline;
1437 if (rface != rface->ascii_rface)
1439 rface->info = rface->ascii_rface->info;
1443 frame = rface->frame;
1444 MSTRUCT_CALLOC (info, MERROR_WIN);
1446 foreground = rface->face.property[MFACE_FOREGROUND];
1447 background = rface->face.property[MFACE_BACKGROUND];
1448 videomode = rface->face.property[MFACE_VIDEOMODE];
1450 videomode = frame->videomode;
1451 if (videomode != Mreverse)
1453 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1454 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1458 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1459 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1462 if (foreground == Mnil)
1463 foreground = frame->foreground;
1464 if (background == Mnil)
1465 background = frame->background;
1466 if (videomode == Mreverse)
1468 MSymbol temp = foreground;
1469 foreground = background;
1472 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1473 FRAME_VISUAL (frame),
1475 MSYMBOL_NAME (foreground),
1476 &info->xft_color_fore))
1478 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1479 FRAME_VISUAL (frame),
1481 MSYMBOL_NAME (background),
1482 &info->xft_color_back))
1484 #endif /* HAVE_XFT2 */
1486 hline = rface->hline;
1490 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1492 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1499 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1501 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1503 if (box->color_left && box->color_left != box->color_top)
1504 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1506 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
1508 if (box->color_bottom && box->color_bottom != box->color_top)
1509 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1511 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
1513 if (box->color_right && box->color_right != box->color_bottom)
1514 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1516 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
1524 mwin__free_realized_face (MRealizedFace *rface)
1526 if (rface == rface->ascii_rface)
1532 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1534 int x, int y, int width, int height, MDrawRegion region)
1536 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1539 gc = set_region (frame, gc, region);
1541 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1542 x, y, width, height);
1547 mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
1548 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1549 int reverse, MDrawRegion region)
1551 MRealizedFace *rface = from->rface;
1552 Display *display = FRAME_DISPLAY (rface->frame);
1553 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1559 gc = set_region (rface->frame, gc, region);
1560 for (; from < to; from++)
1562 XDrawRectangle (display, (Window) win, gc,
1563 x, y - gstring->ascent + 1, from->g.xadv - 1,
1564 gstring->ascent + gstring->descent - 2);
1571 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1572 MRealizedFace *rface, int reverse,
1573 int x, int y, int width, MDrawRegion region)
1575 enum MFaceHLineType type = rface->hline->type;
1576 GCInfo *info = rface->info;
1577 GC gc = gc = info->gc[GC_HLINE];
1580 y = (type == MFACE_HLINE_BOTTOM
1581 ? y + gstring->text_descent - rface->hline->width
1582 : type == MFACE_HLINE_UNDER
1584 : type == MFACE_HLINE_STRIKE_THROUGH
1585 ? y - ((gstring->ascent + gstring->descent) / 2)
1586 : y - gstring->text_ascent);
1588 gc = set_region (frame, gc, region);
1590 for (i = 0; i < rface->hline->width; i++)
1591 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1592 x, y + i, x + width - 1, y + i);
1597 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1598 MGlyph *g, int x, int y, int width, MDrawRegion region)
1600 Display *display = FRAME_DISPLAY (frame);
1601 MRealizedFace *rface = g->rface;
1602 MFaceBoxProp *box = rface->box;
1603 GCInfo *info = rface->info;
1604 GC gc_top, gc_left, gc_right, gc_btm;
1608 y0 = y - (gstring->text_ascent
1609 + rface->box->inner_vmargin + rface->box->width);
1610 y1 = y + (gstring->text_descent
1611 + rface->box->inner_vmargin + rface->box->width - 1);
1613 gc_top = info->gc[GC_BOX_TOP];
1615 gc_top = set_region (frame, gc_top, region);
1616 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1619 gc_btm = info->gc[GC_BOX_BOTTOM];
1621 if (g->type == GLYPH_BOX)
1625 if (g->left_padding)
1626 x0 = x + box->outer_hmargin, x1 = x + g->g.xadv - 1;
1628 x0 = x, x1 = x + g->g.xadv - box->outer_hmargin - 1;
1630 /* Draw the top side. */
1631 for (i = 0; i < box->width; i++)
1632 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1634 /* Draw the bottom side. */
1635 if (region && gc_btm != gc_top)
1636 gc_btm = set_region (frame, gc_btm, region);
1637 for (i = 0; i < box->width; i++)
1638 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1640 if (g->left_padding > 0)
1642 /* Draw the left side. */
1643 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1647 gc_left = info->gc[GC_BOX_LEFT];
1649 gc_left = set_region (frame, gc_left, region);
1651 for (i = 0; i < rface->box->width; i++)
1652 XDrawLine (display, (Window) win, gc_left,
1653 x0 + i, y0 + i, x0 + i, y1 - i);
1657 /* Draw the right side. */
1658 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1662 gc_right = info->gc[GC_BOX_RIGHT];
1664 gc_right = set_region (frame, gc_right, region);
1666 for (i = 0; i < rface->box->width; i++)
1667 XDrawLine (display, (Window) win, gc_right,
1668 x1 - i, y0 + i, x1 - i, y1 - i);
1673 /* Draw the top side. */
1674 for (i = 0; i < box->width; i++)
1675 XDrawLine (display, (Window) win, gc_top,
1676 x, y0 + i, x + width - 1, y0 + i);
1678 /* Draw the bottom side. */
1679 if (region && gc_btm != gc_top)
1680 gc_btm = set_region (frame, gc_btm, region);
1681 for (i = 0; i < box->width; i++)
1682 XDrawLine (display, (Window) win, gc_btm,
1683 x, y1 - i, x + width - 1, y1 - i);
1690 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1691 int reverse, int x, int y,
1692 int width, int height, int row_bytes, unsigned char *bmp,
1695 Display *display = FRAME_DISPLAY (frame);
1697 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1700 gc = set_region (frame, gc, region);
1702 for (i = 0; i < height; i++, bmp += row_bytes)
1703 for (j = 0; j < width; j++)
1704 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1705 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1710 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1711 int intensity, MDrawPoint *points, int num,
1714 GCInfo *info = rface->info;
1717 if (! (gc = info->gc[intensity]))
1718 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
1721 gc = set_region (frame, gc, region);
1723 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1724 (XPoint *) points, num, CoordModeOrigin);
1729 mwin__region_from_rect (MDrawMetric *rect)
1731 MDrawRegion region1 = XCreateRegion ();
1732 MDrawRegion region2 = XCreateRegion ();
1737 xrect.width = rect->width;
1738 xrect.height = rect->height;
1739 XUnionRectWithRegion (&xrect, region1, region2);
1740 XDestroyRegion (region1);
1745 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1747 MDrawRegion region1 = XCreateRegion ();
1752 xrect.width = rect->width;
1753 xrect.height = rect->height;
1755 XUnionRegion (region, region, region1);
1756 XUnionRectWithRegion (&xrect, region1, region);
1757 XDestroyRegion (region1);
1761 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1763 MDrawRegion region = XCreateRegion ();
1765 XUnionRegion (region1, region1, region);
1766 XIntersectRegion (region, region2, region1);
1767 XDestroyRegion (region);
1771 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1773 MDrawRegion region1 = XCreateRegion ();
1778 xrect.width = rect->width;
1779 xrect.height = rect->height;
1780 XUnionRectWithRegion (&xrect, region1, region);
1781 XDestroyRegion (region1);
1785 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1789 XClipBox (region, &xrect);
1792 rect->width = xrect.width;
1793 rect->height = xrect.height;
1797 mwin__free_region (MDrawRegion region)
1799 XDestroyRegion (region);
1803 mwin__dump_region (MDrawRegion region)
1806 XClipBox (region, &rect);
1807 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1812 mwin__create_window (MFrame *frame, MDrawWindow parent)
1814 Display *display = FRAME_DISPLAY (frame);
1816 XWMHints wm_hints = { InputHint, False };
1817 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1818 XSetWindowAttributes set_attrs;
1821 GCInfo *info = frame->rface->info;
1824 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1825 mask = GCForeground;
1826 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1827 set_attrs.background_pixel = values.foreground;
1828 set_attrs.backing_store = Always;
1829 set_attrs.override_redirect = True;
1830 set_attrs.save_under = True;
1831 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1832 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1833 CopyFromParent, InputOutput, CopyFromParent,
1835 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1836 NULL, &wm_hints, &class_hints);
1837 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1838 return (MDrawWindow) win;
1842 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1845 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1847 if (XftDrawDrawable (xft_draw) == (Drawable) win)
1848 XftDrawChange (xft_draw, FRAME_DEVICE (frame)->drawable);
1849 #endif /* HAVE_XFT2 */
1850 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1855 mwin__event_window (void *event)
1857 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1861 mwin__print_event (void *arg, char *win_name)
1864 XEvent *event = (XEvent *) arg;
1866 switch (event->xany.type)
1868 case 2: event_name = "KeyPress"; break;
1869 case 3: event_name = "KeyRelease"; break;
1870 case 4: event_name = "ButtonPress"; break;
1871 case 5: event_name = "ButtonRelease"; break;
1872 case 6: event_name = "MotionNotify"; break;
1873 case 7: event_name = "EnterNotify"; break;
1874 case 8: event_name = "LeaveNotify"; break;
1875 case 9: event_name = "FocusIn"; break;
1876 case 10: event_name = "FocusOut"; break;
1877 case 11: event_name = "KeymapNotify"; break;
1878 case 12: event_name = "Expose"; break;
1879 case 13: event_name = "GraphicsExpose"; break;
1880 case 14: event_name = "NoExpose"; break;
1881 case 15: event_name = "VisibilityNotify"; break;
1882 case 16: event_name = "CreateNotify"; break;
1883 case 17: event_name = "DestroyNotify"; break;
1884 case 18: event_name = "UnmapNotify"; break;
1885 case 19: event_name = "MapNotify"; break;
1886 case 20: event_name = "MapRequest"; break;
1887 case 21: event_name = "ReparentNotify"; break;
1888 case 22: event_name = "ConfigureNotify"; break;
1889 case 23: event_name = "ConfigureRequest"; break;
1890 case 24: event_name = "GravityNotify"; break;
1891 case 25: event_name = "ResizeRequest"; break;
1892 case 26: event_name = "CirculateNotify"; break;
1893 case 27: event_name = "CirculateRequest"; break;
1894 case 28: event_name = "PropertyNotify"; break;
1895 case 29: event_name = "SelectionClear"; break;
1896 case 30: event_name = "SelectionRequest"; break;
1897 case 31: event_name = "SelectionNotify"; break;
1898 case 32: event_name = "ColormapNotify"; break;
1899 case 33: event_name = "ClientMessage"; break;
1900 case 34: event_name = "MappingNotify"; break;
1901 default: event_name = "unknown";
1904 fprintf (stderr, "%s: %s\n", win_name, event_name);
1909 mwin__map_window (MFrame *frame, MDrawWindow win)
1911 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1915 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1917 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1921 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1922 MDrawMetric *geometry)
1924 Display *display = FRAME_DISPLAY (frame);
1925 XWindowAttributes attr;
1926 Window parent = (Window) parent_win, root;
1928 XGetWindowAttributes (display, (Window) win, &attr);
1929 geometry->x = attr.x + attr.border_width;
1930 geometry->y = attr.y + attr.border_width;
1931 geometry->width = attr.width;
1932 geometry->height = attr.height;
1935 parent = RootWindow (display, FRAME_SCREEN (frame));
1938 Window this_parent, *children;
1941 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1944 if (this_parent == parent || this_parent == root)
1946 win = (MDrawWindow) this_parent;
1947 XGetWindowAttributes (display, (Window) win, &attr);
1948 geometry->x += attr.x + attr.border_width;
1949 geometry->y += attr.y + attr.border_width;
1954 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1955 MDrawMetric *current, MDrawMetric *new)
1957 Display *display = FRAME_DISPLAY (frame);
1958 unsigned int mask = 0;
1959 XWindowChanges values;
1961 if (current->width != new->width)
1964 if (new->width <= 0)
1966 values.width = current->width = new->width;
1968 if (current->height != new->height)
1971 if (new->height <= 0)
1973 values.height = current->height = new->height;
1975 if (current->x != new->x)
1978 values.x = current->x = new->x;
1980 if (current->y != new->y)
1983 current->y = new->y;
1984 values.y = current->y = new->y;
1987 XConfigureWindow (display, (Window) win, mask, &values);
1988 XClearWindow (display, (Window) win);
1992 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1994 XEvent *event = (XEvent *) arg;
1995 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
2002 if (event->xany.type != KeyPress
2003 /* && event->xany.type != KeyRelease */
2006 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
2009 if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
2011 if (len == 1 && keysym >= XK_space && keysym <= XK_asciitilde)
2015 key = minput__char_to_key (c);
2016 if (c == ' ' && ((XKeyEvent *) event)->state & ShiftMask)
2017 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2021 char *str = XKeysymToString (keysym);
2025 key = msymbol (str);
2026 if (((XKeyEvent *) event)->state & ShiftMask)
2027 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2029 if (((XKeyEvent *) event)->state & ControlMask)
2030 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2031 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
2032 *modifiers |= MINPUT_KEY_META_MODIFIER;
2033 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
2034 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
2035 if (((XKeyEvent *) event)->state & disp_info->super_mask)
2036 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
2037 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
2038 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
2045 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
2047 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
2049 Display *display = FRAME_DISPLAY (frame);
2050 GCInfo *info = rface->info;
2053 for (i = 0; i <= GC_INVERSE; i++)
2055 XGetGCValues (display, info->gc[i], valuemask, &values);
2056 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
2057 values.foreground, values.background);
2058 fprintf (stderr, "\n");
2062 static MDeviceDriver x_driver =
2065 mwin__device_get_prop,
2067 mwin__free_realized_face,
2069 mwin__draw_empty_boxes,
2073 mwin__region_from_rect,
2074 mwin__union_rect_with_region,
2075 mwin__intersect_region,
2076 mwin__region_add_rect,
2077 mwin__region_to_rect,
2080 mwin__create_window,
2081 mwin__destroy_window,
2084 mwin__window_geometry,
2085 mwin__adjust_window,
2089 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
2094 M_iso8859_1 = msymbol ("iso8859-1");
2095 M_iso10646_1 = msymbol ("iso10646-1");
2097 display_info_list = mplist ();
2098 device_list = mplist ();
2101 xft_driver.select = mfont__ft_driver.select;
2102 xft_driver.list = mfont__ft_driver.list;
2103 xft_driver.list_family_names = mfont__ft_driver.list_family_names;
2106 Mxim = msymbol ("xim");
2107 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
2115 M17N_OBJECT_UNREF (display_info_list);
2116 M17N_OBJECT_UNREF (device_list);
2121 #ifdef X_SET_ERROR_HANDLER
2123 x_error_handler (Display *display, XErrorEvent *error)
2130 x_io_error_handler (Display *display)
2137 /** Return an MWDevice object corresponding to a display specified in
2140 It searches device_list for a device matching the display. If
2141 found, return the found object. Otherwise, return a newly created
2145 device_open (MFrame *frame, MPlist *param)
2147 Display *display = NULL;
2148 Screen *screen = NULL;
2150 Drawable drawable = 0;
2151 Widget widget = NULL;
2153 int auto_display = 0;
2154 MDisplayInfo *disp_info = NULL;
2155 MWDevice *device = NULL;
2157 XWindowAttributes attr;
2163 int use_xfont = 0, use_freetype = 0, use_xft = 0;
2165 for (plist = param; (key = mplist_key (plist)) != Mnil;
2166 plist = mplist_next (plist))
2168 if (key == Mdisplay)
2169 display = (Display *) mplist_value (plist);
2170 else if (key == Mscreen)
2171 screen = mplist_value (plist);
2172 else if (key == Mdrawable)
2173 drawable = (Drawable) mplist_value (plist);
2174 else if (key == Mdepth)
2175 depth = (unsigned) mplist_value (plist);
2176 else if (key == Mwidget)
2177 widget = (Widget) mplist_value (plist);
2178 else if (key == Mcolormap)
2179 cmap = (Colormap) mplist_value (plist);
2180 else if (key == Mfont)
2182 MSymbol val = MPLIST_SYMBOL (plist);
2186 #ifdef HAVE_FREETYPE
2187 else if (val == Mfreetype)
2190 else if (val == Mxft)
2197 /* If none of them is specified, use all of them. */
2198 if (! use_xfont && ! use_freetype && ! use_xft)
2199 use_xfont = use_freetype = use_xft = 1;
2203 display = XtDisplay (widget);
2204 screen_num = XScreenNumberOfScreen (XtScreen (widget));
2205 depth = DefaultDepth (display, screen_num);
2211 unsigned width, height, border_width;
2214 MERROR (MERROR_WIN, -1);
2215 XGetGeometry (display, drawable, &root_window,
2216 &x, &y, &width, &height, &border_width, &depth);
2217 XGetWindowAttributes (display, root_window, &attr);
2218 screen_num = XScreenNumberOfScreen (attr.screen);
2223 display = DisplayOfScreen (screen);
2228 display = XOpenDisplay (NULL);
2230 MERROR (MERROR_WIN, -1);
2233 screen = DefaultScreenOfDisplay (display);
2235 screen_num = XScreenNumberOfScreen (screen);
2237 depth = DefaultDepth (display, screen_num);
2241 cmap = DefaultColormap (display, screen_num);
2243 for (plist = display_info_list; mplist_key (plist) != Mnil;
2244 plist = mplist_next (plist))
2246 disp_info = (MDisplayInfo *) mplist_value (plist);
2247 if (disp_info->display == display)
2251 if (mplist_key (plist) != Mnil)
2252 M17N_OBJECT_REF (disp_info);
2255 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2256 disp_info->display = display;
2257 disp_info->auto_display = auto_display;
2258 disp_info->font_list = mplist ();
2259 find_modifier_bits (disp_info);
2260 disp_info->MULE_BASELINE_OFFSET
2261 = XInternAtom (display, "_MULE_BASELINE_OFFSET", False);
2262 disp_info->AVERAGE_WIDTH
2263 = XInternAtom (display, "AVERAGE_WIDTH", False);
2264 mplist_add (display_info_list, Mt, disp_info);
2267 for (plist = device_list; mplist_key (plist) != Mnil;
2268 plist = mplist_next (plist))
2270 device = (MWDevice *) mplist_value (plist);
2271 if (device->display_info == disp_info
2272 && device->depth == depth
2273 && device->cmap == cmap
2274 && device->screen_num == screen_num)
2278 if (mplist_key (plist) != Mnil)
2279 M17N_OBJECT_REF (device);
2282 unsigned long valuemask = GCForeground;
2286 M17N_OBJECT (device, free_device, MERROR_WIN);
2287 device->display_info = disp_info;
2288 device->screen_num = screen_num;
2289 /* A drawable on which to create GCs. */
2290 device->drawable = XCreatePixmap (display,
2291 RootWindow (display, screen_num),
2293 device->depth = depth;
2294 device->cmap = cmap;
2295 pixels = DisplayHeight (display, screen_num);
2296 mm = DisplayHeightMM (display, screen_num);
2297 device->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
2298 device->realized_face_list = mplist ();
2299 device->realized_font_list = mplist ();
2300 mplist_add (device->realized_font_list, Mt, NULL);
2301 device->realized_fontset_list = mplist ();
2302 device->gc_list = mplist ();
2303 values.foreground = BlackPixel (display, screen_num);
2304 device->scratch_gc = XCreateGC (display, device->drawable,
2305 valuemask, &values);
2307 device->xft_draw = XftDrawCreate (display, device->drawable,
2308 DefaultVisual (display, screen_num),
2313 frame->device = device;
2314 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2315 frame->dpi = device->resy;
2316 frame->driver = &x_driver;
2317 frame->font_driver_list = mplist ();
2321 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2324 #endif /* HAVE_XFT2 */
2325 #ifdef HAVE_FREETYPE
2327 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2328 #endif /* HAVE_FREETYPE */
2329 if (use_xfont || MPLIST_TAIL_P (frame->font_driver_list))
2330 mplist_add (frame->font_driver_list, Mx, &xfont_driver);
2332 frame->realized_font_list = device->realized_font_list;
2333 frame->realized_face_list = device->realized_face_list;
2334 frame->realized_fontset_list = device->realized_fontset_list;
2338 XtResource resources[] = {
2339 { XtNfont, XtCFont, XtRString, sizeof (String),
2340 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2341 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2342 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2343 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2344 XtOffset (AppDataPtr, background), XtRString, "white" },
2345 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2346 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2349 XtGetApplicationResources (widget, &app_data,
2350 resources, XtNumber (resources), NULL, 0);
2351 frame->foreground = msymbol (app_data.foreground);
2352 frame->background = msymbol (app_data.background);
2353 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2357 app_data.font = DEFAULT_FONT;
2358 frame->foreground = msymbol ("black");
2359 frame->background = msymbol ("white");
2360 frame->videomode = Mnormal;
2363 if (strcmp (app_data.font, DEFAULT_FONT) != 0)
2365 XFontStruct *xfont = XLoadQueryFont (display, app_data.font);
2366 unsigned long value;
2371 font = mfont_parse_name (app_data.font, Mx);
2373 && XGetFontProperty (xfont, XA_FONT, &value)
2374 && (name = ((char *) XGetAtomName (display, (Atom) value))))
2375 font = mfont_parse_name (name, Mx);
2376 XFreeFont (display, xfont);
2380 font = mfont_parse_name (DEFAULT_FONT, Mx);
2381 else if (! font->size)
2383 face = mface_from_font (font);
2385 face->property[MFACE_FONTSET] = mfontset (NULL);
2386 face->property[MFACE_FOREGROUND] = frame->foreground;
2387 face->property[MFACE_BACKGROUND] = frame->background;
2388 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2389 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2390 face->property[MFACE_VIDEOMODE] = frame->videomode;
2391 mface_put_prop (face, Mhook_func,
2392 mface_get_prop (mface__default, Mhook_func));
2393 face->property[MFACE_RATIO] = (void *) 100;
2394 mplist_push (param, Mface, face);
2395 M17N_OBJECT_UNREF (face);
2397 #ifdef X_SET_ERROR_HANDLER
2398 XSetErrorHandler (x_error_handler);
2399 XSetIOErrorHandler (x_io_error_handler);
2406 /* XIM (X Input Method) handler */
2408 typedef struct MInputXIMMethodInfo
2414 } MInputXIMMethodInfo;
2416 typedef struct MInputXIMContextInfo
2420 MConverter *converter;
2421 } MInputXIMContextInfo;
2424 xim_open_im (MInputMethod *im)
2426 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
2427 MLocale *saved, *this;
2428 char *save_modifier_list;
2430 MInputXIMMethodInfo *im_info;
2432 saved = mlocale_set (LC_CTYPE, NULL);
2433 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
2435 /* The specified locale is not supported. */
2436 MERROR (MERROR_LOCALE, -1);
2437 if (mlocale_get_prop (this, Mcoding) == Mnil)
2439 /* Unable to decode the output of XIM. */
2440 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2441 MERROR (MERROR_LOCALE, -1);
2444 if (arg->modifier_list)
2445 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
2447 save_modifier_list = XSetLocaleModifiers ("");
2448 if (! save_modifier_list)
2450 /* The specified locale is not supported by X. */
2451 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2452 MERROR (MERROR_LOCALE, -1);
2455 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
2458 /* No input method is available in the current locale. */
2459 XSetLocaleModifiers (save_modifier_list);
2460 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2461 MERROR (MERROR_WIN, -1);
2464 MSTRUCT_MALLOC (im_info, MERROR_WIN);
2465 im_info->display = arg->display;
2467 im_info->language = mlocale_get_prop (this, Mlanguage);
2468 im_info->coding = mlocale_get_prop (this, Mcoding);
2471 XSetLocaleModifiers (save_modifier_list);
2472 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
2478 xim_close_im (MInputMethod *im)
2480 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
2482 XCloseIM (im_info->xim);
2487 xim_create_ic (MInputContext *ic)
2489 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
2490 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2491 MInputXIMContextInfo *ic_info;
2494 if (! arg->input_style)
2496 /* By default, use Root style. */
2497 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
2498 arg->preedit_attrs = NULL;
2499 arg->status_attrs = NULL;
2502 if (! arg->preedit_attrs && ! arg->status_attrs)
2503 xic = XCreateIC (im_info->xim,
2504 XNInputStyle, arg->input_style,
2505 XNClientWindow, arg->client_win,
2506 XNFocusWindow, arg->focus_win,
2508 else if (arg->preedit_attrs && ! arg->status_attrs)
2509 xic = XCreateIC (im_info->xim,
2510 XNInputStyle, arg->input_style,
2511 XNClientWindow, arg->client_win,
2512 XNFocusWindow, arg->focus_win,
2513 XNPreeditAttributes, arg->preedit_attrs,
2515 else if (! arg->preedit_attrs && arg->status_attrs)
2516 xic = XCreateIC (im_info->xim,
2517 XNInputStyle, arg->input_style,
2518 XNClientWindow, arg->client_win,
2519 XNFocusWindow, arg->focus_win,
2520 XNStatusAttributes, arg->status_attrs,
2523 xic = XCreateIC (im_info->xim,
2524 XNInputStyle, arg->input_style,
2525 XNClientWindow, arg->client_win,
2526 XNFocusWindow, arg->focus_win,
2527 XNPreeditAttributes, arg->preedit_attrs,
2528 XNStatusAttributes, arg->status_attrs,
2531 MERROR (MERROR_WIN, -1);
2533 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
2535 ic_info->win = arg->focus_win;
2536 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
2542 xim_destroy_ic (MInputContext *ic)
2544 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2546 XDestroyIC (ic_info->xic);
2547 mconv_free_converter (ic_info->converter);
2553 xim_filter (MInputContext *ic, MSymbol key, void *event)
2555 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2557 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
2562 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
2564 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
2565 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
2566 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
2572 buf = (char *) alloca (512);
2573 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
2574 if (status == XBufferOverflow)
2576 buf = (char *) alloca (len);
2577 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
2580 mtext_reset (ic->produced);
2584 mconv_reset_converter (ic_info->converter);
2585 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
2586 mconv_decode (ic_info->converter, ic->produced);
2587 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
2588 Mlanguage, (void *) im_info->language);
2589 mtext_cpy (mt, ic->produced);
2590 mtext_reset (ic->produced);
2598 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2602 /*** @addtogroup m17nInputMethodWin */
2607 @brief Input method driver for XIM.
2609 The driver #minput_xim_driver is for the foreign input method of
2610 name #Mxim. It uses XIM (X Input Methods) as a background input
2613 As the symbol #Mxim has property #Minput_driver whose value is
2614 a pointer to this driver, the input method of language #Mnil
2615 and name #Mxim uses this driver.
2617 Therefore, for such input methods, the driver dependent arguments
2618 to the functions whose name begin with minput_ must be as follows.
2620 The argument $ARG of the function minput_open_im () must be a
2621 pointer to the structure #MInputXIMArgIM. See the documentation
2622 of #MInputXIMArgIM for more details.
2624 The argument $ARG of the function minput_create_ic () must be a
2625 pointer to the structure #MInputXIMArgIC. See the documentation
2626 of #MInputXIMArgIC for more details.
2628 The argument $ARG of the function minput_filter () must be a
2629 pointer to the structure @c XEvent. The argument $KEY is ignored.
2631 The argument $ARG of the function minput_lookup () must be the
2632 same one as that of the function minput_filter (). The argument
2636 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2638 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢
2639 XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2641 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2642 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim
2643 ¤Ç¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2645 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_
2646 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2648 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM
2649 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò»²¾È¡£
2651 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC
2652 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ¤ò»²¾È¡£
2654 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent
2655 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2657 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2658 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì¤ë¡£ */
2660 MInputDriver minput_xim_driver =
2661 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2662 xim_filter, xim_lookup, NULL };
2666 #else /* not HAVE_X11 */
2668 int device_open () { return -1; }
2670 #endif /* not HAVE_X11 */