1 /* m17n-X.c -- implementation of the GUI API on X Windows.
2 Copyright (C) 2003, 2004
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
24 /*** @addtogroup m17nInternal
36 #include <X11/keysym.h>
37 #include <X11/Xlocale.h>
38 #include <X11/Xutil.h>
39 #include <X11/Xresource.h>
40 #include <X11/Xatom.h>
41 #include <X11/StringDefs.h>
42 #include <X11/Intrinsic.h>
45 #include <X11/Xft/Xft.h>
46 #endif /* HAVE_XFT2 */
50 #include "m17n-misc.h"
52 #include "internal-gui.h"
61 /* Common header for the m17n object. */
66 /* If nonzero, <display> is opened by this library. Thus it should
67 be closed on freeing this structure. */
70 /** List of available fonts on the display (except for iso8859-1 and
71 iso10646-1 fonts). Keys are font registries, values are
73 MPlist *font_registry_list;
75 MPlist *iso8859_1_family_list;
77 MPlist *iso10646_1_family_list;
79 /* List of information about each font. Keys are font registries,
80 values are (MFontInfo *). */
81 MPlist *realized_font_list;
83 /** Modifier bit masks of the display. */
90 /* Anchor of the chain of MDisplayInfo objects. */
91 static MPlist *display_info_list;
94 /* Color value and the corresponding GC. */
97 unsigned int rgb; /* (red << 16) | (green << 8) | blue */
104 GC_NORMAL = GC_INVERSE + 7,
117 /* The first 8 elements are indexed by an intensity for
118 anti-aliasing. The 2nd to 7th are created on demand. */
121 XftColor xft_color_fore, xft_color_back;
127 /* Common header for the m17n object. */
130 MDisplayInfo *display_info;
146 /** List of pointers to realized faces on the frame. */
147 MPlist *realized_face_list;
149 /** List of pointers to realized fontsets on the frame. */
150 MPlist *realized_fontset_list;
152 /** List of XColors vs GCs on the frame. */
156 static MPlist *device_list;
158 static MSymbol M_iso8859_1, M_iso10646_1;
160 #define FRAME_DISPLAY(frame) ((frame)->device->display_info->display)
161 #define FRAME_SCREEN(frame) ((frame)->device->screen_num)
162 #define FRAME_CMAP(frame) ((frame)->device->cmap)
163 #define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
164 FRAME_SCREEN (frame))
166 #define DEFAULT_FONT "-misc-fixed-medium-r-normal--*-120-*-*-*-*-iso8859-1"
167 #define FALLBACK_FONT "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1"
174 Boolean reverse_video;
175 } AppData, *AppDataPtr;
178 free_display_info (void *object)
180 MDisplayInfo *disp_info = (MDisplayInfo *) object;
183 for (plist = disp_info->font_registry_list;
184 mplist_key (plist) != Mnil; plist = mplist_next (plist))
186 MFontList *registry_list = mplist_value (plist);
188 if (registry_list->fonts)
189 free (registry_list->fonts);
190 free (registry_list);
192 M17N_OBJECT_UNREF (disp_info->font_registry_list);
194 for (plist = disp_info->iso8859_1_family_list;
195 mplist_key (plist) != Mnil; plist = mplist_next (plist))
197 MFontList *family_list = mplist_value (plist);
199 if (family_list->fonts)
200 free (family_list->fonts);
203 M17N_OBJECT_UNREF (disp_info->iso8859_1_family_list);
205 for (plist = disp_info->iso10646_1_family_list;
206 mplist_key (plist) != Mnil; plist = mplist_next (plist))
208 MFontList *family_list = mplist_value (plist);
210 if (family_list->fonts)
211 free (family_list->fonts);
214 M17N_OBJECT_UNREF (disp_info->iso10646_1_family_list);
216 for (plist = disp_info->realized_font_list;
217 mplist_key (plist) != Mnil; plist = mplist_next (plist))
218 mfont__free_realized ((MRealizedFont *) mplist_value (plist));
219 M17N_OBJECT_UNREF (disp_info->realized_font_list);
221 if (disp_info->auto_display)
222 XCloseDisplay (disp_info->display);
228 free_device (void *object)
230 MWDevice *device = (MWDevice *) object;
233 for (plist = device->realized_fontset_list;
234 mplist_key (plist) != Mnil; plist = mplist_next (plist))
235 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
236 M17N_OBJECT_UNREF (device->realized_fontset_list);
238 for (plist = device->realized_face_list;
239 mplist_key (plist) != Mnil; plist = mplist_next (plist))
240 mface__free_realized ((MRealizedFace *) mplist_value (plist));
241 M17N_OBJECT_UNREF (device->realized_face_list);
243 MPLIST_DO (plist, device->gc_list)
245 XFreeGC (device->display_info->display,
246 ((RGB_GC *) MPLIST_VAL (plist))->gc);
247 free (MPLIST_VAL (plist));
249 M17N_OBJECT_UNREF (device->gc_list);
250 XFreeGC (device->display_info->display, device->scratch_gc);
253 XftDrawDestroy (device->xft_draw);
256 XFreePixmap (device->display_info->display, device->drawable);
257 M17N_OBJECT_UNREF (device->display_info);
263 find_modifier_bits (MDisplayInfo *disp_info)
265 Display *display = disp_info->display;
266 XModifierKeymap *mods;
267 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
268 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
269 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
270 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
271 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
272 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
273 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
274 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
277 mods = XGetModifierMapping (display);
278 /* We skip the first three sets for Shift, Lock, and Control. The
279 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
280 for (i = 3; i < 8; i++)
281 for (j = 0; j < mods->max_keypermod; j++)
283 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
287 if (code == meta_l || code == meta_r)
288 disp_info->meta_mask |= (1 << i);
289 else if (code == alt_l || code == alt_r)
290 disp_info->alt_mask |= (1 << i);
291 else if (code == super_l || code == super_r)
292 disp_info->super_mask |= (1 << i);
293 else if (code == hyper_l || code == hyper_r)
294 disp_info->hyper_mask |= (1 << i);
297 /* If meta keys are not in any modifier, use alt keys as meta
299 if (! disp_info->meta_mask)
301 disp_info->meta_mask = disp_info->alt_mask;
302 disp_info->alt_mask = 0;
304 /* If both meta and alt are assigned to the same modifier, give meta
306 if (disp_info->meta_mask & disp_info->alt_mask)
307 disp_info->alt_mask &= ~disp_info->meta_mask;
309 XFreeModifiermap (mods);
313 get_rgb_gc (MWDevice *device, XColor *xcolor)
315 int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
316 | (xcolor->blue >> 8));
319 unsigned long valuemask = GCForeground;
322 MPLIST_DO (plist, device->gc_list)
324 rgb_gc = MPLIST_VAL (plist);
326 if (rgb_gc->rgb == rgb)
328 if (rgb_gc->rgb > rgb)
332 if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
335 rgb_gc = malloc (sizeof (RGB_GC));
337 values.foreground = xcolor->pixel;
338 rgb_gc->gc = XCreateGC (device->display_info->display,
339 device->drawable, valuemask, &values);
340 mplist_push (plist, Mt, rgb_gc);
345 get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
347 MWDevice *device = frame->device;
355 color = for_foreground ? frame->foreground : frame->background;
357 if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
358 msymbol_name (color), &xcolor))
360 rgb_gc = get_rgb_gc (device, &xcolor);
364 *rgb_ret = rgb_gc->rgb;
369 GCInfo *info = frame->rface->info;
374 rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
376 rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
384 get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
386 int rgb_fore, rgb_back;
391 if (info->gc[intensity])
392 return info->gc[intensity];
394 rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
395 xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
396 + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
397 xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
398 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
399 xcolor.blue = (((rgb_fore & 0xFF) * intensity
400 + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
401 rgb_gc = get_rgb_gc (device, &xcolor);
405 gc =get_gc_for_anti_alias (device, info,
406 intensity < 4 ? intensity - 1 : intensity + 1);
407 return (info->gc[intensity] = gc);
411 /** X font handler */
413 /** Indices to each field of split font name. */
435 /** Split the fontname NAME into each XLFD field destructively. Set
436 each element of the table pointed by PROPERTY_IDX to a pointer to
437 the corresponding font property name. Store the point size and
438 the resolution-Y of the font to the place pointed by POINT and
441 If NAME does not contain all XLFD fields, the unspecified fields is
442 treated as wild cards. */
445 split_font_name (char *name, char **field,
446 unsigned short *size, unsigned short *resy)
451 for (i = 0, p = name; *p; p++)
454 if (*p == '-' && i < XLFD_FIELD_MAX)
457 if (i != XLFD_ENCODING)
462 if (i < XLFD_REGISTRY)
464 for (; i < XLFD_FIELD_MAX; i++)
467 if (*(field[XLFD_RESY]) == '*')
470 *resy = atoi (field[XLFD_RESY]);
471 if (*(field[XLFD_PIXEL]) == '*')
473 if (*(field[XLFD_POINT]) != '*')
474 *size = atoi (field[XLFD_POINT]) * *resy / 72;
478 else if (*(field[XLFD_PIXEL]) == '[')
480 /* The pixel size field specifies a transformation matrix of the
481 form "[A B C D]". The XLFD spec says that the scalar value N
482 for the pixel size is equivalent to D. */
483 char *p0 = field[XLFD_PIXEL] + 1, *p1;
486 for (i = 0; i < 4; i++, p0 = p1)
487 d = strtod (p0, &p1);
491 *size = atoi (field[XLFD_PIXEL]) * 10;
492 if (*size == 0 && *(field[XLFD_POINT]) != '*')
494 *size = atoi (field[XLFD_POINT]);
496 *size = *size * *resy / 72;
498 *size = *size * 100 / 72;
505 build_font_name (MFont *font, char *name, int limit)
510 unsigned short size, resy;
512 prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
513 prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
514 prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
515 prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
516 prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
517 prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
518 prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
519 for (len = 0, i = 0; i < 7; i++)
523 str[i] = msymbol_name (prop[i]);
524 len += strlen (str[i]);
534 + 3 /* 3 asterisks */
535 + 30 /* 3 integers (each 10 digits) */
536 + 1) /* '\0' terminal */
540 size = (int) mfont_get_prop (font, Msize);
544 size = size / 10 + 1;
545 resy = (int) mfont_get_prop (font, Mresolution);
547 sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
548 str[0], str[1], str[2], str[3], str[4], str[5],
549 size, resy, resy, str[6]);
554 build_font_list (MFrame *frame, MSymbol family, MSymbol registry,
558 MFontList *font_list;
563 MSTRUCT_CALLOC (font_list, MERROR_WIN);
567 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s",
568 msymbol_name (registry));
569 font_list->tag = registry;
573 sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s",
574 msymbol_name (family), msymbol_name (registry));
575 font_list->tag = family;
578 fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts);
581 MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN);
582 for (i = j = 0; i < nfonts; i++)
583 if (mwin__parse_font_name (fontnames[i], font_list->fonts + j) >= 0
584 && (font_list->fonts[j].property[MFONT_SIZE] != 0
585 || font_list->fonts[j].property[MFONT_RESY] == 0))
587 font_list->fonts[j].property[MFONT_TYPE] = MFONT_TYPE_WIN + 1;
590 XFreeFontNames (fontnames);
591 font_list->nfonts = j;
593 mplist_add (plist, font_list->tag, font_list);
594 return (nfonts > 0 ? font_list : NULL);
598 static MRealizedFont *xfont_select (MFrame *, MFont *, MFont *, int);
599 static int xfont_open (MRealizedFont *);
600 static void xfont_close (MRealizedFont *);
601 static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
602 static unsigned xfont_encode_char (MRealizedFont *, int, unsigned);
603 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
604 MGlyph *, MGlyph *, int, MDrawRegion);
606 static MFontDriver xfont_driver =
607 { xfont_select, xfont_open, xfont_close,
608 xfont_find_metric, xfont_encode_char, xfont_render };
610 /* The X font driver function SELECT. */
612 static MRealizedFont *
613 xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size)
615 MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
616 MRealizedFont *rfont;
617 MFontList *font_list = NULL;
620 int best_score, score;
623 || ! strchr (MSYMBOL_NAME (registry), '-'))
626 /* We handles iso8859-1 and iso10646-1 fonts specially because there
627 exists so many such fonts. */
628 if (registry == M_iso8859_1 || registry == M_iso10646_1)
631 = (registry == M_iso8859_1
632 ? frame->device->display_info->iso8859_1_family_list
633 : frame->device->display_info->iso10646_1_family_list);
634 MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY);
638 font_list = (MFontList *) mplist_get (family_list, family);
640 font_list = build_font_list (frame, family, registry, family_list);
644 family = FONT_PROPERTY (request, MFONT_FAMILY);
645 font_list = (MFontList *) mplist_get (family_list, family);
647 font_list = build_font_list (frame, family, registry, family_list);
652 MPlist *registry_list
653 = frame->device->display_info->font_registry_list;
655 font_list = (MFontList *) mplist_get (registry_list, registry);
657 font_list = build_font_list (frame, Mnil, registry, registry_list);
662 for (i = 0, best_score = -1, best_font = NULL; i < font_list->nfonts; i++)
663 if ((best_score = mfont__score (font_list->fonts + i, spec, request,
668 best_font = font_list->fonts + i;
669 for (; best_score > 0 && i < font_list->nfonts ; i++)
671 score = mfont__score (font_list->fonts + i, spec, request,
673 if (score >= 0 && score < best_score)
675 best_font = font_list->fonts + i;
680 MSTRUCT_CALLOC (rfont, MERROR_WIN);
681 rfont->frame = frame;
683 rfont->request = *request;
684 rfont->font = *best_font;
685 if (best_font->property[MFONT_SIZE] == 0)
686 rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE];
687 rfont->score = best_score;
688 rfont->driver = &xfont_driver;
700 close_xfont (void *object)
702 MXFontInfo *xfont = (MXFontInfo *) object;
705 XFreeFont (FRAME_DISPLAY (xfont->frame), xfont->f);
710 /* The X font driver function OPEN. */
713 xfont_open (MRealizedFont *rfont)
717 MFrame *frame = rfont->frame;
718 int mdebug_mask = MDEBUG_FONT;
720 /* This never fail to generate a valid fontname because open_spec
721 should correspond to a font available on the system. */
722 build_font_name (&rfont->font, name, 1024);
723 M17N_OBJECT (xfont, close_xfont, MERROR_WIN);
725 xfont->frame = frame;
726 xfont->f = XLoadQueryFont (FRAME_DISPLAY (frame), name);
730 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
733 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
735 rfont->ascent = xfont->f->ascent;
736 rfont->descent = xfont->f->descent;
741 /* The X font driver function CLOSE. */
744 xfont_close (MRealizedFont *rfont)
746 M17N_OBJECT_UNREF (rfont->info);
749 /* The X font driver function FIND_METRIC. */
752 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
755 MXFontInfo *xfont = (MXFontInfo *) rfont->info;
756 XFontStruct *f = xfont->f;
757 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
759 for (; g != gend; g++)
761 if (g->code == MCHAR_INVALID_CODE)
763 g->lbearing = f->max_bounds.lbearing;
764 g->rbearing = f->max_bounds.rbearing;
765 g->width = f->max_bounds.width;
766 g->ascent = f->ascent;
767 g->descent = f->descent;
771 int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
772 XCharStruct *pcm = NULL;
774 if (f->per_char != NULL)
776 if (f->min_byte1 == 0 && f->max_byte1 == 0)
779 && byte2 >= f->min_char_or_byte2
780 && byte2 <= f->max_char_or_byte2)
781 pcm = f->per_char + byte2 - f->min_char_or_byte2;
785 if (byte1 >= f->min_byte1
786 && byte1 <= f->max_byte1
787 && byte2 >= f->min_char_or_byte2
788 && byte2 <= f->max_char_or_byte2)
791 + ((f->max_char_or_byte2-f->min_char_or_byte2 + 1)
792 * (byte1 - f->min_byte1))
793 + (byte2 - f->min_char_or_byte2));
800 g->lbearing = pcm->lbearing;
801 g->rbearing = pcm->rbearing;
802 g->width = pcm->width;
803 g->ascent = pcm->ascent;
804 g->descent = pcm->descent;
808 /* If the per_char pointer is null, all glyphs between
809 the first and last character indexes inclusive have
810 the same information, as given by both min_bounds and
813 g->rbearing = f->max_bounds.width;
814 g->width = f->max_bounds.width;
815 g->ascent = f->ascent;
816 g->descent = f->descent;
823 /* The X font driver function ENCODE_CHAR. */
826 xfont_encode_char (MRealizedFont *rfont, int c, unsigned code)
830 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
833 if (rfont->status < 0 || code >= 0x10000)
834 return MCHAR_INVALID_CODE;
835 if (rfont->status == 0)
837 if (xfont_open (rfont) < 0)
838 return MCHAR_INVALID_CODE;
840 xfont = (MXFontInfo *) rfont->info;
842 all_chars_exist = (! f->per_char || f->all_chars_exist == True);
843 min_byte1 = f->min_byte1;
844 max_byte1 = f->max_byte1;
845 min_byte2 = f->min_char_or_byte2;
846 max_byte2 = f->max_char_or_byte2;
848 if (min_byte1 == 0 && max_byte1 == 0)
852 if (code < min_byte2 || code > max_byte2)
853 return MCHAR_INVALID_CODE;
856 pcm = f->per_char + (code - min_byte2);
857 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
858 ? code : MCHAR_INVALID_CODE);
862 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
865 if (byte1 < min_byte1 || byte1 > max_byte1
866 || byte2 < min_byte2 || byte2 > max_byte2)
867 return MCHAR_INVALID_CODE;
871 pcm = f->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
872 + (byte2 - min_byte2));
873 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
874 ? code : MCHAR_INVALID_CODE);
879 set_region (MFrame *frame, GC gc, MDrawRegion region)
881 unsigned long valuemask = GCForeground;
883 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
884 frame->device->scratch_gc);
885 XSetRegion (FRAME_DISPLAY (frame), frame->device->scratch_gc, region);
886 return frame->device->scratch_gc;
889 /* The X font driver function RENDER. */
892 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
893 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
895 MRealizedFace *rface = from->rface;
898 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
905 /* It is assured that the all glyphs in the current range use the
906 same realized face. */
907 display = FRAME_DISPLAY (rface->frame);
910 gc = set_region (rface->frame, gc, region);
911 if (! rface->rfont || from->code == MCHAR_INVALID_CODE)
915 for (; from < to; from++)
917 XDrawRectangle (display, (Window) win, gc,
918 x0, y - gstring->ascent + 1, from->width - 1,
919 gstring->ascent + gstring->descent - 2);
925 XSetFont (display, gc, ((MXFontInfo *) (rface->rfont->info))->f->fid);
926 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
927 for (i = 0, g = from; g < to; i++, g++)
929 code[i].byte1 = g->code >> 8;
930 code[i].byte2 = g->code & 0xFF;
936 if (g->type == GLYPH_PAD)
938 else if (g->type == GLYPH_SPACE)
939 for (; g < to && g->type == GLYPH_SPACE; g++)
941 else if (! g->rface->rfont)
943 if ((g->c >= 0x200B && g->c <= 0x200F)
944 || (g->c >= 0x202A && g->c <= 0x202E))
948 /* As a font is not found for this character, draw an
950 int box_width = g->width;
951 int box_height = gstring->ascent + gstring->descent;
957 XDrawRectangle (display, (Window) win, gc,
958 x, y - gstring->ascent, box_width, box_height);
962 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
964 XDrawString16 (display, (Window) win, gc,
965 x + g->xoff, y + g->yoff, code + (g - from), 1);
972 int code_idx = g - from;
975 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
978 XDrawString16 (display, (Window) win, gc, orig_x, y,
986 /* XIM (X Input Method) handler */
988 typedef struct MInputXIMMethodInfo
994 } MInputXIMMethodInfo;
996 typedef struct MInputXIMContextInfo
1000 MConverter *converter;
1001 } MInputXIMContextInfo;
1004 xim_open_im (MInputMethod *im)
1006 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
1007 MLocale *saved, *this;
1008 char *save_modifier_list;
1010 MInputXIMMethodInfo *im_info;
1012 saved = mlocale_set (LC_CTYPE, NULL);
1013 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
1015 /* The specified locale is not supported. */
1016 MERROR (MERROR_LOCALE, -1);
1017 if (mlocale_get_prop (this, Mcoding) == Mnil)
1019 /* Unable to decode the output of XIM. */
1020 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1021 MERROR (MERROR_LOCALE, -1);
1024 if (arg->modifier_list)
1025 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
1027 save_modifier_list = XSetLocaleModifiers ("");
1028 if (! save_modifier_list)
1030 /* The specified locale is not supported by X. */
1031 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1032 MERROR (MERROR_LOCALE, -1);
1035 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
1038 /* No input method is available in the current locale. */
1039 XSetLocaleModifiers (save_modifier_list);
1040 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1041 MERROR (MERROR_WIN, -1);
1044 MSTRUCT_MALLOC (im_info, MERROR_WIN);
1045 im_info->display = arg->display;
1047 im_info->language = mlocale_get_prop (this, Mlanguage);
1048 im_info->coding = mlocale_get_prop (this, Mcoding);
1051 XSetLocaleModifiers (save_modifier_list);
1052 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1058 xim_close_im (MInputMethod *im)
1060 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
1062 XCloseIM (im_info->xim);
1067 xim_create_ic (MInputContext *ic)
1069 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
1070 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1071 MInputXIMContextInfo *ic_info;
1074 if (! arg->input_style)
1076 /* By default, use Root style. */
1077 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
1078 arg->preedit_attrs = NULL;
1079 arg->status_attrs = NULL;
1082 if (! arg->preedit_attrs && ! arg->status_attrs)
1083 xic = XCreateIC (im_info->xim,
1084 XNInputStyle, arg->input_style,
1085 XNClientWindow, arg->client_win,
1086 XNFocusWindow, arg->focus_win,
1088 else if (arg->preedit_attrs && ! arg->status_attrs)
1089 xic = XCreateIC (im_info->xim,
1090 XNInputStyle, arg->input_style,
1091 XNClientWindow, arg->client_win,
1092 XNFocusWindow, arg->focus_win,
1093 XNPreeditAttributes, arg->preedit_attrs,
1095 else if (! arg->preedit_attrs && arg->status_attrs)
1096 xic = XCreateIC (im_info->xim,
1097 XNInputStyle, arg->input_style,
1098 XNClientWindow, arg->client_win,
1099 XNFocusWindow, arg->focus_win,
1100 XNStatusAttributes, arg->status_attrs,
1103 xic = XCreateIC (im_info->xim,
1104 XNInputStyle, arg->input_style,
1105 XNClientWindow, arg->client_win,
1106 XNFocusWindow, arg->focus_win,
1107 XNPreeditAttributes, arg->preedit_attrs,
1108 XNStatusAttributes, arg->status_attrs,
1111 MERROR (MERROR_WIN, -1);
1113 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
1115 ic_info->win = arg->focus_win;
1116 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
1122 xim_destroy_ic (MInputContext *ic)
1124 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1126 XDestroyIC (ic_info->xic);
1127 mconv_free_converter (ic_info->converter);
1133 xim_filter (MInputContext *ic, MSymbol key, void *event)
1135 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1137 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
1142 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1144 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1145 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1146 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
1152 buf = (char *) alloca (512);
1153 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
1154 if (status == XBufferOverflow)
1156 buf = (char *) alloca (len);
1157 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
1160 mtext_reset (ic->produced);
1164 mconv_reset_converter (ic_info->converter);
1165 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
1166 mconv_decode (ic_info->converter, ic->produced);
1167 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1168 Mlanguage, (void *) im_info->language);
1169 mtext_cpy (mt, ic->produced);
1170 mtext_reset (ic->produced);
1176 #ifdef X_SET_ERROR_HANDLER
1178 x_error_handler (Display *display, XErrorEvent *error)
1185 x_io_error_handler (Display *display)
1197 Mdisplay = msymbol ("display");
1198 Mscreen = msymbol ("screen");
1199 Mdrawable = msymbol ("drawable");
1200 Mdepth = msymbol ("depth");
1201 Mwidget = msymbol ("widget");
1202 M_iso8859_1 = msymbol ("iso8859-1");
1203 M_iso10646_1 = msymbol ("iso10646-1");
1205 display_info_list = mplist ();
1206 device_list = mplist ();
1208 mfont__driver_list[MFONT_TYPE_WIN] = &xfont_driver;
1210 Mxim = msymbol ("xim");
1211 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
1219 M17N_OBJECT_UNREF (display_info_list);
1220 M17N_OBJECT_UNREF (device_list);
1224 mwin__parse_font_name (char *name, MFont *font)
1226 char *field[XLFD_FIELD_MAX];
1227 unsigned short size, resy;
1228 MSymbol attrs[MFONT_PROPERTY_MAX];
1229 char *copy = (char *) alloca (512);
1231 char *p, *last = NULL;
1233 len = strlen (name) + 1;
1234 for (i = 0, p = name; *p; p++)
1238 else if (p > name && *p == '*' && p[-1] == '-')
1242 memcpy (copy, name, len);
1245 memcpy (copy, name, last - name);
1247 strcat (copy, "-*");
1248 strcat (copy, last);
1251 if (split_font_name (copy, field, &size, &resy) < 0)
1253 attrs[MFONT_FOUNDRY]
1254 = *(field[XLFD_FOUNDRY]) != '*' ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
1256 = *(field[XLFD_FAMILY]) != '*' ? msymbol (field[XLFD_FAMILY]) : Mnil;
1258 = *(field[XLFD_WEIGHT]) != '*' ? msymbol (field[XLFD_WEIGHT]) : Mnil;
1260 = *(field[XLFD_SLANT]) != '*' ? msymbol (field[XLFD_SLANT]) : Mnil;
1261 attrs[MFONT_STRETCH]
1262 = *(field[XLFD_SWIDTH]) != '*' ? msymbol (field[XLFD_SWIDTH]) : Mnil;
1263 attrs[MFONT_ADSTYLE]
1264 = *(field[XLFD_ADSTYLE]) != '*' ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
1265 attrs[MFONT_REGISTRY]
1266 = *(field[XLFD_REGISTRY]) != '*' ? msymbol (field[XLFD_REGISTRY]) : Mnil;
1267 mfont__set_spec (font, attrs, size, resy);
1273 mwin__build_font_name (MFont *font)
1277 if (build_font_name (font, name, 1024) < 0)
1279 return strdup (name);
1282 /** Return an MWDevice object corresponding to a display specified in
1285 It searches device_list for a device matching the display. If
1286 found, return the found object. Otherwise, return a newly created
1290 mwin__open_device (MFrame *frame, MPlist *param)
1292 Display *display = NULL;
1293 Screen *screen = NULL;
1295 Drawable drawable = 0;
1296 Widget widget = NULL;
1298 int auto_display = 0;
1299 MDisplayInfo *disp_info = NULL;
1300 MWDevice *device = NULL;
1302 XWindowAttributes attr;
1308 for (plist = param; (key = mplist_key (plist)) != Mnil;
1309 plist = mplist_next (plist))
1311 if (key == Mdisplay)
1312 display = (Display *) mplist_value (plist);
1313 else if (key == Mscreen)
1314 screen = mplist_value (plist);
1315 else if (key == Mdrawable)
1316 drawable = (Drawable) mplist_value (plist);
1317 else if (key == Mdepth)
1318 depth = (unsigned) mplist_value (plist);
1319 else if (key == Mwidget)
1320 widget = (Widget) mplist_value (plist);
1321 else if (key == Mcolormap)
1322 cmap = (Colormap) mplist_value (plist);
1327 display = XtDisplay (widget);
1328 screen_num = XScreenNumberOfScreen (XtScreen (widget));
1329 depth = DefaultDepth (display, screen_num);
1335 unsigned width, height, border_width;
1338 MERROR (MERROR_WIN, NULL);
1339 XGetGeometry (display, drawable, &root_window,
1340 &x, &y, &width, &height, &border_width, &depth);
1341 XGetWindowAttributes (display, root_window, &attr);
1342 screen_num = XScreenNumberOfScreen (attr.screen);
1347 display = DisplayOfScreen (screen);
1352 display = XOpenDisplay (NULL);
1354 MERROR (MERROR_WIN, NULL);
1357 screen = DefaultScreenOfDisplay (display);
1359 screen_num = XScreenNumberOfScreen (screen);
1361 depth = DefaultDepth (display, screen_num);
1365 cmap = DefaultColormap (display, screen_num);
1367 for (plist = display_info_list; mplist_key (plist) != Mnil;
1368 plist = mplist_next (plist))
1370 disp_info = (MDisplayInfo *) mplist_value (plist);
1371 if (disp_info->display == display)
1375 if (mplist_key (plist) != Mnil)
1376 M17N_OBJECT_REF (disp_info);
1379 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
1380 disp_info->display = display;
1381 disp_info->auto_display = auto_display;
1382 disp_info->font_registry_list = mplist ();
1383 disp_info->iso8859_1_family_list = mplist ();
1384 disp_info->iso10646_1_family_list = mplist ();
1385 disp_info->realized_font_list = mplist ();
1386 find_modifier_bits (disp_info);
1387 mplist_add (display_info_list, Mt, disp_info);
1390 for (plist = device_list; mplist_key (plist) != Mnil;
1391 plist = mplist_next (plist))
1393 device = (MWDevice *) mplist_value (plist);
1394 if (device->display_info == disp_info
1395 && device->depth == depth
1396 && device->cmap == cmap)
1400 if (mplist_key (plist) != Mnil)
1401 M17N_OBJECT_REF (device);
1404 unsigned long valuemask = GCForeground;
1407 M17N_OBJECT (device, free_device, MERROR_WIN);
1408 device->display_info = disp_info;
1409 device->screen_num = screen_num;
1410 /* A drawable on which to create GCs. */
1411 device->drawable = XCreatePixmap (display,
1412 RootWindow (display, screen_num),
1414 device->depth = depth;
1415 device->cmap = cmap;
1416 device->realized_face_list = mplist ();
1417 device->realized_fontset_list = mplist ();
1418 device->gc_list = mplist ();
1419 values.foreground = BlackPixel (display, screen_num);
1420 device->scratch_gc = XCreateGC (display, device->drawable,
1421 valuemask, &values);
1423 device->xft_draw = XftDrawCreate (display, device->drawable,
1424 DefaultVisual (display, screen_num),
1429 frame->realized_font_list = disp_info->realized_font_list;
1430 frame->realized_face_list = device->realized_face_list;
1431 frame->realized_fontset_list = device->realized_fontset_list;
1435 XtResource resources[] = {
1436 { XtNfont, XtCFont, XtRString, sizeof (String),
1437 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
1438 { XtNforeground, XtCForeground, XtRString, sizeof (String),
1439 XtOffset (AppDataPtr, foreground), XtRString, "black" },
1440 { XtNbackground, XtCBackground, XtRString, sizeof (String),
1441 XtOffset (AppDataPtr, background), XtRString, "white" },
1442 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
1443 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
1446 XtGetApplicationResources (widget, &app_data,
1447 resources, XtNumber (resources), NULL, 0);
1448 frame->foreground = msymbol (app_data.foreground);
1449 frame->background = msymbol (app_data.background);
1450 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
1454 app_data.font = DEFAULT_FONT;
1455 frame->foreground = msymbol ("black");
1456 frame->background = msymbol ("white");
1457 frame->videomode = Mnormal;
1460 frame->font = mfont ();
1463 char **names = XListFonts (display, app_data.font, 1, &nfonts);
1467 if (mwin__parse_font_name (names[0], frame->font) < 0)
1469 /* The font name does not conform to XLFD. Try to open the
1470 font and get XA_FONT property. */
1471 XFontStruct *xfont = XLoadQueryFont (display, names[0]);
1476 unsigned long value;
1479 if (XGetFontProperty (xfont, XA_FONT, &value)
1480 && (name = ((char *)
1481 XGetAtomName (display, (Atom) value))))
1483 if (mwin__parse_font_name (name, frame->font) >= 0)
1486 XFreeFont (display, xfont);
1489 XFreeFontNames (names);
1492 mwin__parse_font_name (FALLBACK_FONT, frame->font);
1495 #ifdef X_SET_ERROR_HANDLER
1496 XSetErrorHandler (x_error_handler);
1497 XSetIOErrorHandler (x_io_error_handler);
1504 mwin__close_device (MFrame *frame)
1506 M17N_OBJECT_UNREF (frame->device);
1510 mwin__device_get_prop (MWDevice *device, MSymbol key)
1512 if (key == Mdisplay)
1513 return (void *) device->display_info->display;
1515 return (void *) ScreenOfDisplay(device->display_info->display,
1516 device->screen_num);
1517 if (key == Mcolormap)
1518 return (void *) device->cmap;
1520 return (void *) device->depth;
1525 mwin__realize_face (MRealizedFace *rface)
1528 MSymbol foreground, background, videomode;
1529 MFaceHLineProp *hline;
1534 if (rface != rface->ascii_rface)
1536 rface->info = rface->ascii_rface->info;
1540 frame = rface->frame;
1541 MSTRUCT_CALLOC (info, MERROR_WIN);
1543 foreground = rface->face.property[MFACE_FOREGROUND];
1544 background = rface->face.property[MFACE_BACKGROUND];
1545 videomode = rface->face.property[MFACE_VIDEOMODE];
1547 videomode = frame->videomode;
1548 if (videomode != Mreverse)
1550 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1551 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1555 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1556 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1559 if (foreground == Mnil)
1560 foreground = frame->foreground;
1561 if (background == Mnil)
1562 background = frame->background;
1563 if (videomode == Mreverse)
1565 MSymbol temp = foreground;
1566 foreground = background;
1569 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1570 FRAME_VISUAL (frame),
1572 MSYMBOL_NAME (foreground),
1573 &info->xft_color_fore))
1575 if (! XftColorAllocName (FRAME_DISPLAY (frame),
1576 FRAME_VISUAL (frame),
1578 MSYMBOL_NAME (background),
1579 &info->xft_color_back))
1583 hline = rface->hline;
1587 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1589 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1596 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1598 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1600 if (box->color_left && box->color_left != box->color_top)
1601 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1603 info->gc[GC_BOX_LEFT] = info->gc[GC_NORMAL];
1605 if (box->color_bottom && box->color_bottom != box->color_top)
1606 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1608 info->gc[GC_BOX_BOTTOM] = info->gc[GC_NORMAL];
1610 if (box->color_right && box->color_right != box->color_top)
1611 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1613 info->gc[GC_BOX_RIGHT] = info->gc[GC_NORMAL];
1618 func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
1620 (func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]);
1625 mwin__free_realized_face (MRealizedFace *rface)
1627 if (rface == rface->ascii_rface)
1633 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1635 int x, int y, int width, int height, MDrawRegion region)
1637 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1640 gc = set_region (frame, gc, region);
1642 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1643 x, y, width, height);
1648 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1649 MRealizedFace *rface, int reverse,
1650 int x, int y, int width, MDrawRegion region)
1652 enum MFaceHLineType type = rface->hline->type;
1653 GCInfo *info = rface->info;
1654 GC gc = gc = info->gc[GC_HLINE];
1657 y = (type == MFACE_HLINE_BOTTOM
1658 ? y + gstring->text_descent - rface->hline->width
1659 : type == MFACE_HLINE_UNDER
1661 : type == MFACE_HLINE_STRIKE_THROUGH
1662 ? y - ((gstring->ascent + gstring->descent) / 2)
1663 : y - gstring->text_ascent);
1665 gc = set_region (frame, gc, region);
1667 for (i = 0; i < rface->hline->width; i++)
1668 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1669 x, y + i, x + width - 1, y + i);
1674 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1675 MGlyph *g, int x, int y, int width, MDrawRegion region)
1677 Display *display = FRAME_DISPLAY (frame);
1678 MRealizedFace *rface = g->rface;
1679 MFaceBoxProp *box = rface->box;
1680 GCInfo *info = rface->info;
1681 GC gc_top, gc_left, gc_right, gc_btm;
1685 y0 = y - (gstring->text_ascent
1686 + rface->box->inner_vmargin + rface->box->width);
1687 y1 = y + (gstring->text_descent
1688 + rface->box->inner_vmargin + rface->box->width - 1);
1690 gc_top = info->gc[GC_BOX_TOP];
1692 gc_top = set_region (frame, gc_top, region);
1693 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1696 gc_btm = info->gc[GC_BOX_BOTTOM];
1698 if (g->type == GLYPH_BOX)
1702 if (g->left_padding)
1703 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1705 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1707 /* Draw the top side. */
1708 for (i = 0; i < box->width; i++)
1709 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1711 /* Draw the bottom side. */
1712 if (region && gc_btm != gc_top)
1713 gc_btm = set_region (frame, gc_btm, region);
1714 for (i = 0; i < box->width; i++)
1715 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1717 if (g->left_padding > 0)
1719 /* Draw the left side. */
1720 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1724 gc_left = info->gc[GC_BOX_LEFT];
1726 gc_left = set_region (frame, gc_left, region);
1728 for (i = 0; i < rface->box->width; i++)
1729 XDrawLine (display, (Window) win, gc_left,
1730 x0 + i, y0 + i, x0 + i, y1 - i);
1734 /* Draw the right side. */
1735 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1739 gc_right = info->gc[GC_BOX_RIGHT];
1741 gc_right = set_region (frame, gc_right, region);
1743 for (i = 0; i < rface->box->width; i++)
1744 XDrawLine (display, (Window) win, gc_right,
1745 x1 - i, y0 + i, x1 - i, y1 - i);
1750 /* Draw the top side. */
1751 for (i = 0; i < box->width; i++)
1752 XDrawLine (display, (Window) win, gc_top,
1753 x, y0 + i, x + width - 1, y0 + i);
1755 /* Draw the bottom side. */
1756 if (region && gc_btm != gc_top)
1757 gc_btm = set_region (frame, gc_btm, region);
1758 for (i = 0; i < box->width; i++)
1759 XDrawLine (display, (Window) win, gc_btm,
1760 x, y1 - i, x + width - 1, y1 - i);
1767 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1768 int reverse, int x, int y,
1769 int width, int height, int row_bytes, unsigned char *bmp,
1772 Display *display = FRAME_DISPLAY (frame);
1774 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1777 gc = set_region (frame, gc, region);
1779 for (i = 0; i < height; i++, bmp += row_bytes)
1780 for (j = 0; j < width; j++)
1781 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1782 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1787 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1788 int intensity, MDrawPoint *points, int num,
1791 GCInfo *info = rface->info;
1794 if (! (gc = info->gc[intensity]))
1795 gc = info->gc[intensity] = get_gc_for_anti_alias (frame->device, info,
1798 gc = set_region (frame, gc, region);
1800 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1801 (XPoint *) points, num, CoordModeOrigin);
1806 mwin__region_from_rect (MDrawMetric *rect)
1808 MDrawRegion region1 = XCreateRegion ();
1809 MDrawRegion region2 = XCreateRegion ();
1814 xrect.width = rect->width;
1815 xrect.height = rect->height;
1816 XUnionRectWithRegion (&xrect, region1, region2);
1817 XDestroyRegion (region1);
1822 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1824 MDrawRegion region1 = XCreateRegion ();
1829 xrect.width = rect->width;
1830 xrect.height = rect->height;
1832 XUnionRegion (region, region, region1);
1833 XUnionRectWithRegion (&xrect, region1, region);
1834 XDestroyRegion (region1);
1838 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1840 MDrawRegion region = XCreateRegion ();
1842 XUnionRegion (region1, region1, region);
1843 XIntersectRegion (region, region2, region1);
1844 XDestroyRegion (region);
1848 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1850 MDrawRegion region1 = XCreateRegion ();
1855 xrect.width = rect->width;
1856 xrect.height = rect->height;
1857 XUnionRectWithRegion (&xrect, region1, region);
1858 XDestroyRegion (region1);
1862 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1866 XClipBox (region, &xrect);
1869 rect->width = xrect.width;
1870 rect->height = xrect.height;
1874 mwin__free_region (MDrawRegion region)
1876 XDestroyRegion (region);
1880 mwin__dump_region (MDrawRegion region)
1883 XClipBox (region, &rect);
1884 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1888 mwin__verify_region (MFrame *frame, MDrawRegion region)
1890 set_region (frame, ((GCInfo *) frame->rface->info)->gc[GC_NORMAL], region);
1894 mwin__create_window (MFrame *frame, MDrawWindow parent)
1896 Display *display = FRAME_DISPLAY (frame);
1898 XWMHints wm_hints = { InputHint, False };
1899 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1900 XSetWindowAttributes set_attrs;
1903 GCInfo *info = frame->rface->info;
1906 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1907 mask = GCForeground;
1908 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1909 set_attrs.background_pixel = values.foreground;
1910 set_attrs.backing_store = Always;
1911 set_attrs.override_redirect = True;
1912 set_attrs.save_under = True;
1913 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1914 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1915 CopyFromParent, InputOutput, CopyFromParent,
1917 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1918 NULL, &wm_hints, &class_hints);
1919 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1920 return (MDrawWindow) win;
1924 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1926 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1931 mwin__event_window (void *event)
1933 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1937 mwin__print_event (void *arg, char *win_name)
1940 XEvent *event = (XEvent *) arg;
1942 switch (event->xany.type)
1944 case 2: event_name = "KeyPress"; break;
1945 case 3: event_name = "KeyRelease"; break;
1946 case 4: event_name = "ButtonPress"; break;
1947 case 5: event_name = "ButtonRelease"; break;
1948 case 6: event_name = "MotionNotify"; break;
1949 case 7: event_name = "EnterNotify"; break;
1950 case 8: event_name = "LeaveNotify"; break;
1951 case 9: event_name = "FocusIn"; break;
1952 case 10: event_name = "FocusOut"; break;
1953 case 11: event_name = "KeymapNotify"; break;
1954 case 12: event_name = "Expose"; break;
1955 case 13: event_name = "GraphicsExpose"; break;
1956 case 14: event_name = "NoExpose"; break;
1957 case 15: event_name = "VisibilityNotify"; break;
1958 case 16: event_name = "CreateNotify"; break;
1959 case 17: event_name = "DestroyNotify"; break;
1960 case 18: event_name = "UnmapNotify"; break;
1961 case 19: event_name = "MapNotify"; break;
1962 case 20: event_name = "MapRequest"; break;
1963 case 21: event_name = "ReparentNotify"; break;
1964 case 22: event_name = "ConfigureNotify"; break;
1965 case 23: event_name = "ConfigureRequest"; break;
1966 case 24: event_name = "GravityNotify"; break;
1967 case 25: event_name = "ResizeRequest"; break;
1968 case 26: event_name = "CirculateNotify"; break;
1969 case 27: event_name = "CirculateRequest"; break;
1970 case 28: event_name = "PropertyNotify"; break;
1971 case 29: event_name = "SelectionClear"; break;
1972 case 30: event_name = "SelectionRequest"; break;
1973 case 31: event_name = "SelectionNotify"; break;
1974 case 32: event_name = "ColormapNotify"; break;
1975 case 33: event_name = "ClientMessage"; break;
1976 case 34: event_name = "MappingNotify"; break;
1977 default: event_name = "unknown";
1980 fprintf (stderr, "%s: %s\n", win_name, event_name);
1985 mwin__map_window (MFrame *frame, MDrawWindow win)
1987 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1991 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1993 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1997 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1998 MDrawMetric *geometry)
2000 Display *display = FRAME_DISPLAY (frame);
2001 XWindowAttributes attr;
2002 Window parent = (Window) parent_win, root;
2004 XGetWindowAttributes (display, (Window) win, &attr);
2005 geometry->x = attr.x + attr.border_width;
2006 geometry->y = attr.y + attr.border_width;
2007 geometry->width = attr.width;
2008 geometry->height = attr.height;
2011 parent = RootWindow (display, FRAME_SCREEN (frame));
2014 Window this_parent, *children;
2017 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
2020 if (this_parent == parent || this_parent == root)
2022 win = (MDrawWindow) this_parent;
2023 XGetWindowAttributes (display, (Window) win, &attr);
2024 geometry->x += attr.x + attr.border_width;
2025 geometry->y += attr.y + attr.border_width;
2030 mwin__adjust_window (MFrame *frame, MDrawWindow win,
2031 MDrawMetric *current, MDrawMetric *new)
2033 Display *display = FRAME_DISPLAY (frame);
2034 unsigned int mask = 0;
2035 XWindowChanges values;
2037 if (current->width != new->width)
2040 if (new->width <= 0)
2042 values.width = current->width = new->width;
2044 if (current->height != new->height)
2047 if (new->height <= 0)
2049 values.height = current->height = new->height;
2051 if (current->x != new->x)
2054 values.x = current->x = new->x;
2056 if (current->y != new->y)
2059 current->y = new->y;
2060 values.y = current->y = new->y;
2063 XConfigureWindow (display, (Window) win, mask, &values);
2064 XClearWindow (display, (Window) win);
2068 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
2070 XEvent *event = (XEvent *) arg;
2071 MDisplayInfo *disp_info = frame->device->display_info;
2078 if (event->xany.type != KeyPress
2079 /* && event->xany.type != KeyRelease */
2082 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
2089 if (c < XK_space || c > XK_asciitilde)
2091 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
2092 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2093 if (((XKeyEvent *) event)->state & ControlMask)
2095 if (c >= 'a' && c <= 'z')
2097 if (c >= ' ' && c < 127)
2098 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2100 key = minput__char_to_key (c);
2102 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
2106 char *str = XKeysymToString (keysym);
2110 key = msymbol (str);
2111 if (((XKeyEvent *) event)->state & ShiftMask)
2112 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2113 if (((XKeyEvent *) event)->state & ControlMask)
2114 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2116 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
2117 *modifiers |= MINPUT_KEY_META_MODIFIER;
2118 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
2119 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
2120 if (((XKeyEvent *) event)->state & disp_info->super_mask)
2121 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
2122 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
2123 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
2130 mwin__get_selection_text (MFrame *frame)
2137 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
2139 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
2141 Display *display = FRAME_DISPLAY (frame);
2142 GCInfo *info = rface->info;
2145 for (i = 0; i <= GC_INVERSE; i++)
2147 XGetGCValues (display, info->gc[i], valuemask, &values);
2148 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
2149 values.foreground, values.background);
2150 fprintf (stderr, "\n");
2158 XftFont *font_no_aa;
2164 mwin__xft_close (void *object)
2166 MXftFontInfo *font_info = object;
2168 if (font_info->font_aa)
2169 XftFontClose (FRAME_DISPLAY (font_info->frame), font_info->font_aa);
2170 if (font_info->font_no_aa)
2171 XftFontClose (FRAME_DISPLAY (font_info->frame), font_info->font_no_aa);
2177 mwin__xft_open (MFrame *frame, char *fontname, int size)
2179 MXftFontInfo *font_info;
2180 XftPattern *pattern, *match;
2183 MSTRUCT_CALLOC (font_info, MERROR_WIN);
2185 font_info->frame = frame;
2186 pattern = XftNameParse (fontname);
2187 XftPatternAddDouble (pattern, XFT_PIXEL_SIZE, (double) size);
2188 XftPatternAddBool (pattern, XFT_ANTIALIAS, 1);
2189 match = XftFontMatch (FRAME_DISPLAY (frame), FRAME_SCREEN (frame),
2191 font_info->font_aa = XftFontOpenPattern (FRAME_DISPLAY (frame), match);
2192 if (! font_info->font_aa)
2194 XftPatternDel (pattern, XFT_ANTIALIAS);
2195 XftPatternAddBool (pattern, XFT_ANTIALIAS, 0);
2196 match = XftFontMatch (FRAME_DISPLAY (frame), FRAME_SCREEN (frame),
2198 font_info->font_no_aa = XftFontOpenPattern (FRAME_DISPLAY (frame), match);
2199 if (! font_info->font_no_aa)
2201 XftPatternDestroy (pattern);
2205 if (font_info->font_aa)
2206 XftFontClose (FRAME_DISPLAY (frame), font_info->font_aa);
2207 XftPatternDestroy (pattern);
2214 mwin__xft_get_metric (void *object, FT_Face ft_face, MGlyph *g)
2216 MXftFontInfo *font_info = object;
2223 code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code);
2225 XftGlyphExtents (FRAME_DISPLAY (font_info->frame),
2226 font_info->font_aa, &code, 1, &extents);
2227 g->lbearing = extents.x;
2228 g->rbearing = extents.width - extents.x;
2229 g->width = extents.xOff;
2230 g->ascent = extents.y;
2231 g->descent = extents.height - extents.y;
2236 mwin__xft_render (MDrawWindow win, int x, int y,
2237 MGlyphString *gstring, MGlyph *from, MGlyph *to,
2238 int reverse, MDrawRegion region,
2239 void *object, FT_Face ft_face)
2241 MXftFontInfo *font_info = object;
2242 MRealizedFace *rface = from->rface;
2243 MFrame *frame = rface->frame;
2244 XftDraw *xft_draw = frame->device->xft_draw;
2245 XftColor *xft_color = (! reverse
2246 ? &((GCInfo *) rface->info)->xft_color_fore
2247 : &((GCInfo *) rface->info)->xft_color_back);
2248 XftFont *xft_font = (gstring->control.anti_alias && frame->device->depth > 1
2249 ? font_info->font_aa : font_info->font_no_aa);
2258 XftDrawChange (xft_draw, (Drawable) win);
2259 XftDrawSetClip (xft_draw, (Region) region);
2261 glyphs = alloca (sizeof (FT_UInt) * (to - from));
2262 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
2269 code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code);
2270 if (g->xoff == 0 && g->yoff == 0)
2271 glyphs[nglyphs++] = code;
2275 XftDrawGlyphs (xft_draw, xft_color, xft_font,
2276 last_x, y, glyphs, nglyphs);
2278 XftDrawGlyphs (xft_draw, xft_color, xft_font,
2279 x + g->xoff, y + g->yoff, (FT_UInt *) &code, 1);
2280 last_x = x + g->width;
2284 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
2291 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2296 /*** @addtogroup m17nFrame */
2301 @name Variables: Keys of frame parameter (X specific).
2303 These are the symbols to use as parameter keys for the function
2304 mframe () (which see). They are also keys of a frame property
2305 except for #Mwidget. */
2307 @name ÊÑ¿ô¡§ ¥Õ¥ì¡¼¥à¥Ñ¥é¥á¡¼¥¿ÍÑ¥¡¼ (X ¸ÇÍ).
2309 ´Ø¿ô mframe () ¤Î¥Ñ¥é¥á¡¼¥¿¥¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¥·¥ó¥Ü¥ë¡£( mframe
2310 () ¤ÎÀâÌÀ»²¾È¡£) #Mwidget ¤ò½ü¤¤¤Æ¤Ï¥Õ¥ì¡¼¥à¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤Ç¤â¤¢
2316 /* Keywords for mwin__open_device (). */
2317 MSymbol Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap;
2323 /*** @addtogroup m17nInputMethodWin */
2328 @brief Input method driver for XIM.
2330 The driver #minput_xim_driver is for the foreign input method of
2331 name #Mxim. It uses XIM (X Input Methods) as a background input
2334 As the symbol #Mxim has property #Minput_driver whose value is
2335 a pointer to this driver, the input method of language #Mnil
2336 and name #Mxim uses this driver.
2338 Therefore, for such input methods, the driver dependent arguments
2339 to the functions whose name begin with minput_ must be as follows.
2341 The argument $ARG of the function minput_open_im () must be a
2342 pointer to the structure #MInputXIMArgIM. See the documentation
2343 of #MInputXIMArgIM for more detail.
2345 The argument $ARG of the function minput_create_ic () must be a
2346 pointer to the structure #MInputXIMArgIC. See the documentation
2347 of #MInputXIMArgIC for more detail.
2349 The argument $ARG of the function minput_filter () must be a
2350 pointer to the structure @c XEvent. The argument $KEY is ignored.
2352 The argument $ARG of the function minput_lookup () must be the
2353 same one as that of the function minput_filter (). The argument
2357 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2359 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã
2360 ¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸
2363 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2364 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç¤¢¤ëÆþÎÏ
2365 ¥á¥½¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2367 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø
2368 ¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2370 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM ¤Ø¤Î¥Ý
2371 ¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò
2374 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC ¤Ø¤Î
2375 ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ
2378 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿
2379 ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2381 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2382 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì
2385 MInputDriver minput_xim_driver =
2386 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2387 xim_filter, xim_lookup, NULL };
2392 @brief Symbol of the name "xim".
2394 The variable Mxim is a symbol of name "xim". It is a name of the
2395 input method driver #minput_xim_driver. */
2397 @brief "xim"¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë .
2399 ÊÑ¿ô Mxim ¤Ï"xim"¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£"xim" ¤ÏÆþÎϥ᥽¥Ã
2400 ¥É¥É¥é¥¤¥Ð #minput_xim_driver ¤Î̾Á°¤Ç¤¢¤ë¡£ */