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
34 #include <X11/keysym.h>
35 #include <X11/Xlocale.h>
36 #include <X11/Xutil.h>
37 #include <X11/Xresource.h>
38 #include <X11/Xatom.h>
39 #include <X11/StringDefs.h>
40 #include <X11/Intrinsic.h>
44 #include "m17n-misc.h"
46 #include "internal-gui.h"
55 /* Common header for the m17n object. */
60 /* If nonzero, <display> is opened by this library. Thus it should
61 be closed on freeing this structure. */
64 /** List of available fonts on the display (except for iso8859-1 and
65 iso10646-1 fonts). Keys are font registries, values are
67 MPlist *font_registry_list;
69 MPlist *iso8859_1_family_list;
71 MPlist *iso10646_1_family_list;
73 /* List of information about each font. Keys are font registries,
74 values are (MFontInfo *). */
75 MPlist *realized_font_list;
77 /** Modifier bit masks of the display. */
84 /* Anchor of the chain of MDisplayInfo objects. */
85 static MPlist *display_info_list;
88 /* Color value and the corresponding GC. */
91 unsigned int rgb; /* (red << 16) | (green << 8) | blue */
98 GC_NORMAL = GC_INVERSE + 7,
111 /* The first 8 elements are indexed by an intensity for
112 anti-aliasing. The 2nd to 7th are created on demand. */
118 /* Common header for the m17n object. */
121 MDisplayInfo *display_info;
133 /** List of pointers to realized faces on the frame. */
134 MPlist *realized_face_list;
136 /** List of pointers to realized fontsets on the frame. */
137 MPlist *realized_fontset_list;
139 /** List of XColors vs GCs on the frame. */
143 static MPlist *device_list;
145 static MSymbol M_iso8859_1, M_iso10646_1;
147 #define FRAME_DISPLAY(frame) (frame->device->display_info->display)
148 #define FRAME_SCREEN(frame) (frame->device->screen_num)
150 #define DEFAULT_FONT "-misc-fixed-medium-r-normal--*-120-*-*-*-*-iso8859-1"
151 #define FALLBACK_FONT "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1"
158 Boolean reverse_video;
159 } AppData, *AppDataPtr;
162 free_display_info (void *object)
164 MDisplayInfo *disp_info = (MDisplayInfo *) object;
167 for (plist = disp_info->font_registry_list;
168 mplist_key (plist) != Mnil; plist = mplist_next (plist))
170 MFontList *registry_list = mplist_value (plist);
172 if (registry_list->fonts)
173 free (registry_list->fonts);
174 free (registry_list);
176 M17N_OBJECT_UNREF (disp_info->font_registry_list);
178 for (plist = disp_info->iso8859_1_family_list;
179 mplist_key (plist) != Mnil; plist = mplist_next (plist))
181 MFontList *family_list = mplist_value (plist);
183 if (family_list->fonts)
184 free (family_list->fonts);
187 M17N_OBJECT_UNREF (disp_info->iso8859_1_family_list);
189 for (plist = disp_info->iso10646_1_family_list;
190 mplist_key (plist) != Mnil; plist = mplist_next (plist))
192 MFontList *family_list = mplist_value (plist);
194 if (family_list->fonts)
195 free (family_list->fonts);
198 M17N_OBJECT_UNREF (disp_info->iso10646_1_family_list);
200 for (plist = disp_info->realized_font_list;
201 mplist_key (plist) != Mnil; plist = mplist_next (plist))
202 mfont__free_realized ((MRealizedFont *) mplist_value (plist));
203 M17N_OBJECT_UNREF (disp_info->realized_font_list);
205 if (disp_info->auto_display)
206 XCloseDisplay (disp_info->display);
212 free_device (void *object)
214 MWDevice *device = (MWDevice *) object;
217 for (plist = device->realized_fontset_list;
218 mplist_key (plist) != Mnil; plist = mplist_next (plist))
219 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
220 M17N_OBJECT_UNREF (device->realized_fontset_list);
222 for (plist = device->realized_face_list;
223 mplist_key (plist) != Mnil; plist = mplist_next (plist))
224 mface__free_realized ((MRealizedFace *) mplist_value (plist));
225 M17N_OBJECT_UNREF (device->realized_face_list);
227 MPLIST_DO (plist, device->gc_list)
229 XFreeGC (device->display_info->display,
230 ((RGB_GC *) MPLIST_VAL (plist))->gc);
231 free (MPLIST_VAL (plist));
233 M17N_OBJECT_UNREF (device->gc_list);
234 XFreeGC (device->display_info->display, device->scratch_gc);
236 XFreePixmap (device->display_info->display, device->drawable);
237 M17N_OBJECT_UNREF (device->display_info);
243 find_modifier_bits (MDisplayInfo *disp_info)
245 Display *display = disp_info->display;
246 XModifierKeymap *mods;
247 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
248 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
249 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
250 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
251 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
252 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
253 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
254 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
257 mods = XGetModifierMapping (display);
258 /* We skip the first three sets for Shift, Lock, and Control. The
259 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
260 for (i = 3; i < 8; i++)
261 for (j = 0; j < mods->max_keypermod; j++)
263 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
267 if (code == meta_l || code == meta_r)
268 disp_info->meta_mask |= (1 << i);
269 else if (code == alt_l || code == alt_r)
270 disp_info->alt_mask |= (1 << i);
271 else if (code == super_l || code == super_r)
272 disp_info->super_mask |= (1 << i);
273 else if (code == hyper_l || code == hyper_r)
274 disp_info->hyper_mask |= (1 << i);
277 /* If meta keys are not in any modifier, use alt keys as meta
279 if (! disp_info->meta_mask)
281 disp_info->meta_mask = disp_info->alt_mask;
282 disp_info->alt_mask = 0;
284 /* If both meta and alt are assigned to the same modifier, give meta
286 if (disp_info->meta_mask & disp_info->alt_mask)
287 disp_info->alt_mask &= ~disp_info->meta_mask;
289 XFreeModifiermap (mods);
293 get_rgb_gc (MWDevice *device, XColor *xcolor)
295 int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
296 | (xcolor->blue >> 8));
299 unsigned long valuemask = GCForeground;
302 MPLIST_DO (plist, device->gc_list)
304 rgb_gc = MPLIST_VAL (plist);
306 if (rgb_gc->rgb == rgb)
308 if (rgb_gc->rgb > rgb)
312 if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
315 rgb_gc = malloc (sizeof (RGB_GC));
317 values.foreground = xcolor->pixel;
318 rgb_gc->gc = XCreateGC (device->display_info->display,
319 device->drawable, valuemask, &values);
320 mplist_push (plist, Mt, rgb_gc);
325 get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
327 MWDevice *device = frame->device;
335 color = for_foreground ? frame->foreground : frame->background;
337 if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
338 msymbol_name (color), &xcolor))
340 rgb_gc = get_rgb_gc (device, &xcolor);
344 *rgb_ret = rgb_gc->rgb;
349 GCInfo *info = frame->rface->info;
354 rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
356 rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
364 get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
366 int rgb_fore, rgb_back;
371 if (info->gc[intensity])
372 return info->gc[intensity];
374 rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
375 xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
376 + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
377 xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
378 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
379 xcolor.blue = (((rgb_fore & 0xFF) * intensity
380 + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
381 rgb_gc = get_rgb_gc (device, &xcolor);
385 gc =get_gc_for_anti_alias (device, info,
386 intensity < 4 ? intensity - 1 : intensity + 1);
387 return (info->gc[intensity] = gc);
391 /** X font handler */
393 /** Indices to each field of split font name. */
415 /** Split the fontname NAME into each XLFD field destructively. Set
416 each element of the table pointed by PROPERTY_IDX to a pointer to
417 the corresponding font property name. Store the point size and
418 the resolution-Y of the font to the place pointed by POINT and
421 If NAME does not contain all XLFD fields, the unspecified fields is
422 treated as wild cards. */
425 split_font_name (char *name, char **field,
426 unsigned short *size, unsigned short *resy)
431 for (i = 0, p = name; *p; p++)
434 if (*p == '-' && i < XLFD_FIELD_MAX)
437 if (i != XLFD_ENCODING)
442 if (i < XLFD_REGISTRY)
444 for (; i < XLFD_FIELD_MAX; i++)
447 if (*(field[XLFD_RESY]) == '*')
450 *resy = atoi (field[XLFD_RESY]);
451 if (*(field[XLFD_PIXEL]) == '*')
453 if (*(field[XLFD_POINT]) != '*')
454 *size = atoi (field[XLFD_POINT]) * *resy / 72;
458 else if (*(field[XLFD_PIXEL]) == '[')
460 /* The pixel size field specifies a transformation matrix of the
461 form "[A B C D]". The XLFD spec says that the scalar value N
462 for the pixel size is equivalent to D. */
463 char *p0 = field[XLFD_PIXEL] + 1, *p1;
466 for (i = 0; i < 4; i++, p0 = p1)
467 d = strtod (p0, &p1);
471 *size = atoi (field[XLFD_PIXEL]) * 10;
472 if (*size == 0 && *(field[XLFD_POINT]) != '*')
474 *size = atoi (field[XLFD_POINT]);
476 *size = *size * *resy / 72;
478 *size = *size * 100 / 72;
485 build_font_name (MFont *font, char *name, int limit)
490 unsigned short size, resy;
492 prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
493 prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
494 prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
495 prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
496 prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
497 prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
498 prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
499 for (len = 0, i = 0; i < 7; i++)
503 str[i] = msymbol_name (prop[i]);
504 len += strlen (str[i]);
514 + 3 /* 3 asterisks */
515 + 30 /* 3 integers (each 10 digits) */
516 + 1) /* '\0' terminal */
520 size = (int) mfont_get_prop (font, Msize);
524 size = size / 10 + 1;
525 resy = (int) mfont_get_prop (font, Mresolution);
527 sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
528 str[0], str[1], str[2], str[3], str[4], str[5],
529 size, resy, resy, str[6]);
534 build_font_list (MFrame *frame, MSymbol family, MSymbol registry,
538 MFontList *font_list;
543 MSTRUCT_CALLOC (font_list, MERROR_WIN);
547 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s",
548 msymbol_name (registry));
549 font_list->tag = registry;
553 sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s",
554 msymbol_name (family), msymbol_name (registry));
555 font_list->tag = family;
558 fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts);
561 MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN);
562 for (i = j = 0; i < nfonts; i++)
563 if (mwin__parse_font_name (fontnames[i], font_list->fonts + j) >= 0
564 && (font_list->fonts[j].property[MFONT_SIZE] != 0
565 || font_list->fonts[j].property[MFONT_RESY] == 0))
567 font_list->fonts[j].property[MFONT_TYPE] = MFONT_TYPE_WIN + 1;
570 XFreeFontNames (fontnames);
571 font_list->nfonts = j;
573 mplist_add (plist, font_list->tag, font_list);
574 return (nfonts > 0 ? font_list : NULL);
578 static MRealizedFont *xfont_select (MFrame *, MFont *, MFont *, int);
579 static int xfont_open (MRealizedFont *);
580 static void xfont_close (MRealizedFont *);
581 static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
582 static unsigned xfont_encode_char (MRealizedFont *, int, unsigned);
583 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
584 MGlyph *, MGlyph *, int, MDrawRegion);
586 MFontDriver xfont_driver =
587 { xfont_select, xfont_open, xfont_close,
588 xfont_find_metric, xfont_encode_char, xfont_render };
590 /* The X font driver function SELECT. */
592 static MRealizedFont *
593 xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size)
595 MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
596 MRealizedFont *rfont;
597 MFontList *font_list = NULL;
600 int best_score, score;
603 || ! strchr (MSYMBOL_NAME (registry), '-'))
606 /* We handles iso8859-1 and iso10646-1 fonts specially because there
607 exists so many such fonts. */
608 if (registry == M_iso8859_1 || registry == M_iso10646_1)
611 = (registry == M_iso8859_1
612 ? frame->device->display_info->iso8859_1_family_list
613 : frame->device->display_info->iso10646_1_family_list);
614 MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY);
618 font_list = (MFontList *) mplist_get (family_list, family);
620 font_list = build_font_list (frame, family, registry, family_list);
624 family = FONT_PROPERTY (request, MFONT_FAMILY);
625 font_list = (MFontList *) mplist_get (family_list, family);
627 font_list = build_font_list (frame, family, registry, family_list);
632 MPlist *registry_list
633 = frame->device->display_info->font_registry_list;
635 font_list = (MFontList *) mplist_get (registry_list, registry);
637 font_list = build_font_list (frame, Mnil, registry, registry_list);
642 for (i = 0, best_score = -1, best_font = NULL; i < font_list->nfonts; i++)
643 if ((best_score = mfont__score (font_list->fonts + i, spec, request,
648 best_font = font_list->fonts + i;
649 for (; best_score > 0 && i < font_list->nfonts ; i++)
651 score = mfont__score (font_list->fonts + i, spec, request,
653 if (score >= 0 && score < best_score)
655 best_font = font_list->fonts + i;
660 MSTRUCT_CALLOC (rfont, MERROR_WIN);
661 rfont->frame = frame;
663 rfont->request = *request;
664 rfont->font = *best_font;
665 if (best_font->property[MFONT_SIZE] == 0)
666 rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE];
667 rfont->score = best_score;
668 rfont->driver = &xfont_driver;
680 close_xfont (void *object)
682 MXFontInfo *xfont = (MXFontInfo *) object;
685 XFreeFont (FRAME_DISPLAY (xfont->frame), xfont->f);
690 /* The X font driver function OPEN. */
693 xfont_open (MRealizedFont *rfont)
697 MFrame *frame = rfont->frame;
698 int mdebug_mask = MDEBUG_FONT;
700 /* This never fail to generate a valid fontname because open_spec
701 should correspond to a font available on the system. */
702 build_font_name (&rfont->font, name, 1024);
703 M17N_OBJECT (xfont, close_xfont, MERROR_WIN);
705 xfont->frame = frame;
706 xfont->f = XLoadQueryFont (FRAME_DISPLAY (frame), name);
710 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
713 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
715 rfont->ascent = xfont->f->ascent;
716 rfont->descent = xfont->f->descent;
721 /* The X font driver function CLOSE. */
724 xfont_close (MRealizedFont *rfont)
726 M17N_OBJECT_UNREF (rfont->info);
729 /* The X font driver function FIND_METRIC. */
732 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
735 MXFontInfo *xfont = (MXFontInfo *) rfont->info;
736 XFontStruct *f = xfont->f;
737 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
739 for (; g != gend; g++)
741 if (g->code == MCHAR_INVALID_CODE)
743 g->lbearing = f->max_bounds.lbearing;
744 g->rbearing = f->max_bounds.rbearing;
745 g->width = f->max_bounds.width;
746 g->ascent = f->ascent;
747 g->descent = f->descent;
751 int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
752 XCharStruct *pcm = NULL;
754 if (f->per_char != NULL)
756 if (f->min_byte1 == 0 && f->max_byte1 == 0)
759 && byte2 >= f->min_char_or_byte2
760 && byte2 <= f->max_char_or_byte2)
761 pcm = f->per_char + byte2 - f->min_char_or_byte2;
765 if (byte1 >= f->min_byte1
766 && byte1 <= f->max_byte1
767 && byte2 >= f->min_char_or_byte2
768 && byte2 <= f->max_char_or_byte2)
771 + ((f->max_char_or_byte2-f->min_char_or_byte2 + 1)
772 * (byte1 - f->min_byte1))
773 + (byte2 - f->min_char_or_byte2));
780 g->lbearing = pcm->lbearing;
781 g->rbearing = pcm->rbearing;
782 g->width = pcm->width;
783 g->ascent = pcm->ascent;
784 g->descent = pcm->descent;
788 /* If the per_char pointer is null, all glyphs between
789 the first and last character indexes inclusive have
790 the same information, as given by both min_bounds and
793 g->rbearing = f->max_bounds.width;
794 g->width = f->max_bounds.width;
795 g->ascent = f->ascent;
796 g->descent = f->descent;
803 /* The X font driver function ENCODE_CHAR. */
806 xfont_encode_char (MRealizedFont *rfont, int c, unsigned code)
810 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
813 if (rfont->status < 0)
815 if (rfont->status == 0)
817 if (xfont_open (rfont) < 0)
820 xfont = (MXFontInfo *) rfont->info;
822 all_chars_exist = (! f->per_char || f->all_chars_exist == True);
823 min_byte1 = f->min_byte1;
824 max_byte1 = f->max_byte1;
825 min_byte2 = f->min_char_or_byte2;
826 max_byte2 = f->max_char_or_byte2;
828 if (min_byte1 == 0 && max_byte1 == 0)
833 return ((code >= min_byte2 && code <= max_byte2)
834 ? code : MCHAR_INVALID_CODE);
835 pcm = f->per_char + (code - min_byte2);
836 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
837 ? code : MCHAR_INVALID_CODE);
841 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
845 return ((byte1 >= min_byte1 && byte1 <= max_byte1
846 && byte2 >= min_byte2 && byte2 <= max_byte2)
847 ? code : MCHAR_INVALID_CODE);
848 pcm = f->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
849 + (byte2 - min_byte2));
850 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
851 ? code : MCHAR_INVALID_CODE);
856 set_region (MFrame *frame, GC gc, MDrawRegion region)
858 unsigned long valuemask = GCForeground;
860 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
861 frame->device->scratch_gc);
862 XSetRegion (FRAME_DISPLAY (frame), frame->device->scratch_gc, region);
863 return frame->device->scratch_gc;
866 /* The X font driver function RENDER. */
869 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
870 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
872 MRealizedFace *rface = from->rface;
875 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
882 /* It is assured that the all glyphs in the current range use the
883 same realized face. */
884 display = FRAME_DISPLAY (rface->frame);
887 gc = set_region (rface->frame, gc, region);
888 XSetFont (display, gc, ((MXFontInfo *) (rface->rfont->info))->f->fid);
890 if (from->code == MCHAR_INVALID_CODE)
894 for (; from < to; from++)
896 XDrawRectangle (display, (Window) win, gc,
897 x0, y - gstring->ascent + 1, from->width - 1,
898 gstring->ascent + gstring->descent - 2);
904 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
905 for (i = 0, g = from; g < to; i++, g++)
907 code[i].byte1 = g->code >> 8;
908 code[i].byte2 = g->code & 0xFF;
914 if (g->type == GLYPH_PAD)
916 else if (g->type == GLYPH_SPACE)
917 for (; g < to && g->type == GLYPH_SPACE; g++)
919 else if (! g->rface->rfont)
921 if ((g->c >= 0x200B && g->c <= 0x200F)
922 || (g->c >= 0x202A && g->c <= 0x202E))
926 /* As a font is not found for this character, draw an
928 int box_width = g->width;
929 int box_height = gstring->ascent + gstring->descent;
935 XDrawRectangle (display, (Window) win, gc,
936 x, y - gstring->ascent, box_width, box_height);
940 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
942 XDrawString16 (display, (Window) win, gc,
943 x + g->xoff, y + g->yoff, code + (g - from), 1);
950 int code_idx = g - from;
953 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
956 XDrawString16 (display, (Window) win, gc, orig_x, y,
964 /* XIM (X Input Method) handler */
966 typedef struct MInputXIMMethodInfo
972 } MInputXIMMethodInfo;
974 typedef struct MInputXIMContextInfo
978 MConverter *converter;
979 } MInputXIMContextInfo;
982 xim_open_im (MInputMethod *im)
984 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
985 MLocale *saved, *this;
986 char *save_modifier_list;
988 MInputXIMMethodInfo *im_info;
990 saved = mlocale_set (LC_CTYPE, NULL);
991 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
993 /* The specified locale is not supported. */
994 MERROR (MERROR_LOCALE, -1);
995 if (mlocale_get_prop (this, Mcoding) == Mnil)
997 /* Unable to decode the output of XIM. */
998 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
999 MERROR (MERROR_LOCALE, -1);
1002 if (arg->modifier_list)
1003 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
1005 save_modifier_list = XSetLocaleModifiers ("");
1006 if (! save_modifier_list)
1008 /* The specified locale is not supported by X. */
1009 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1010 MERROR (MERROR_LOCALE, -1);
1013 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
1016 /* No input method is available in the current locale. */
1017 XSetLocaleModifiers (save_modifier_list);
1018 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1019 MERROR (MERROR_WIN, -1);
1022 MSTRUCT_MALLOC (im_info, MERROR_WIN);
1023 im_info->display = arg->display;
1025 im_info->language = mlocale_get_prop (this, Mlanguage);
1026 im_info->coding = mlocale_get_prop (this, Mcoding);
1029 XSetLocaleModifiers (save_modifier_list);
1030 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1036 xim_close_im (MInputMethod *im)
1038 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
1040 XCloseIM (im_info->xim);
1045 xim_create_ic (MInputContext *ic)
1047 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
1048 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1049 MInputXIMContextInfo *ic_info;
1052 if (! arg->input_style)
1054 /* By default, use Root style. */
1055 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
1056 arg->preedit_attrs = NULL;
1057 arg->status_attrs = NULL;
1060 if (! arg->preedit_attrs && ! arg->status_attrs)
1061 xic = XCreateIC (im_info->xim,
1062 XNInputStyle, arg->input_style,
1063 XNClientWindow, arg->client_win,
1064 XNFocusWindow, arg->focus_win,
1066 else if (arg->preedit_attrs && ! arg->status_attrs)
1067 xic = XCreateIC (im_info->xim,
1068 XNInputStyle, arg->input_style,
1069 XNClientWindow, arg->client_win,
1070 XNFocusWindow, arg->focus_win,
1071 XNPreeditAttributes, arg->preedit_attrs,
1073 else if (! arg->preedit_attrs && arg->status_attrs)
1074 xic = XCreateIC (im_info->xim,
1075 XNInputStyle, arg->input_style,
1076 XNClientWindow, arg->client_win,
1077 XNFocusWindow, arg->focus_win,
1078 XNStatusAttributes, arg->status_attrs,
1081 xic = XCreateIC (im_info->xim,
1082 XNInputStyle, arg->input_style,
1083 XNClientWindow, arg->client_win,
1084 XNFocusWindow, arg->focus_win,
1085 XNPreeditAttributes, arg->preedit_attrs,
1086 XNStatusAttributes, arg->status_attrs,
1089 MERROR (MERROR_WIN, -1);
1091 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
1093 ic_info->win = arg->focus_win;
1094 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
1100 xim_destroy_ic (MInputContext *ic)
1102 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1104 XDestroyIC (ic_info->xic);
1105 mconv_free_converter (ic_info->converter);
1111 xim_filter (MInputContext *ic, MSymbol key, void *event)
1113 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1115 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
1120 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1122 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1123 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1124 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
1130 buf = (char *) alloca (512);
1131 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
1132 if (status == XBufferOverflow)
1134 buf = (char *) alloca (len);
1135 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
1138 mtext_reset (ic->produced);
1142 mconv_reset_converter (ic_info->converter);
1143 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
1144 mconv_decode (ic_info->converter, ic->produced);
1145 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1146 Mlanguage, (void *) im_info->language);
1147 mtext_cpy (mt, ic->produced);
1148 mtext_reset (ic->produced);
1154 #ifdef X_SET_ERROR_HANDLER
1156 x_error_handler (Display *display, XErrorEvent *error)
1163 x_io_error_handler (Display *display)
1175 Mdisplay = msymbol ("display");
1176 Mscreen = msymbol ("screen");
1177 Mdrawable = msymbol ("drawable");
1178 Mdepth = msymbol ("depth");
1179 Mwidget = msymbol ("widget");
1180 M_iso8859_1 = msymbol ("iso8859-1");
1181 M_iso10646_1 = msymbol ("iso10646-1");
1183 display_info_list = mplist ();
1184 device_list = mplist ();
1186 mfont__driver_list[MFONT_TYPE_WIN] = &xfont_driver;
1188 Mxim = msymbol ("xim");
1189 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
1197 M17N_OBJECT_UNREF (display_info_list);
1198 M17N_OBJECT_UNREF (device_list);
1202 mwin__parse_font_name (char *name, MFont *font)
1204 char *field[XLFD_FIELD_MAX];
1205 unsigned short size, resy;
1206 MSymbol attrs[MFONT_PROPERTY_MAX];
1207 char *copy = (char *) alloca (512);
1209 char *p, *last = NULL;
1211 len = strlen (name) + 1;
1212 for (i = 0, p = name; *p; p++)
1216 else if (p > name && *p == '*' && p[-1] == '-')
1220 memcpy (copy, name, len);
1223 memcpy (copy, name, last - name);
1225 strcat (copy, "-*");
1226 strcat (copy, last);
1229 if (split_font_name (copy, field, &size, &resy) < 0)
1231 attrs[MFONT_FOUNDRY]
1232 = *(field[XLFD_FOUNDRY]) != '*' ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
1234 = *(field[XLFD_FAMILY]) != '*' ? msymbol (field[XLFD_FAMILY]) : Mnil;
1236 = *(field[XLFD_WEIGHT]) != '*' ? msymbol (field[XLFD_WEIGHT]) : Mnil;
1238 = *(field[XLFD_SLANT]) != '*' ? msymbol (field[XLFD_SLANT]) : Mnil;
1239 attrs[MFONT_STRETCH]
1240 = *(field[XLFD_SWIDTH]) != '*' ? msymbol (field[XLFD_SWIDTH]) : Mnil;
1241 attrs[MFONT_ADSTYLE]
1242 = *(field[XLFD_ADSTYLE]) != '*' ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
1243 attrs[MFONT_REGISTRY]
1244 = *(field[XLFD_REGISTRY]) != '*' ? msymbol (field[XLFD_REGISTRY]) : Mnil;
1245 mfont__set_spec (font, attrs, size, resy);
1251 mwin__build_font_name (MFont *font)
1255 if (build_font_name (font, name, 1024) < 0)
1257 return strdup (name);
1260 /** Return an MWDevice object corresponding to a display specified in
1263 It searches device_list for a device matching the display. If
1264 found, return the found object. Otherwise, return a newly created
1268 mwin__open_device (MFrame *frame, MPlist *param)
1270 Display *display = NULL;
1271 Screen *screen = NULL;
1273 Drawable drawable = 0;
1274 Widget widget = NULL;
1276 int auto_display = 0;
1277 MDisplayInfo *disp_info = NULL;
1278 MWDevice *device = NULL;
1280 XWindowAttributes attr;
1286 for (plist = param; (key = mplist_key (plist)) != Mnil;
1287 plist = mplist_next (plist))
1289 if (key == Mdisplay)
1290 display = (Display *) mplist_value (plist);
1291 else if (key == Mscreen)
1292 screen = mplist_value (plist);
1293 else if (key == Mdrawable)
1294 drawable = (Drawable) mplist_value (plist);
1295 else if (key == Mdepth)
1296 depth = (unsigned) mplist_value (plist);
1297 else if (key == Mwidget)
1298 widget = (Widget) mplist_value (plist);
1299 else if (key == Mcolormap)
1300 cmap = (Colormap) mplist_value (plist);
1305 display = XtDisplay (widget);
1306 screen_num = XScreenNumberOfScreen (XtScreen (widget));
1307 depth = DefaultDepth (display, screen_num);
1313 unsigned width, height, border_width;
1316 MERROR (MERROR_WIN, NULL);
1317 XGetGeometry (display, drawable, &root_window,
1318 &x, &y, &width, &height, &border_width, &depth);
1319 XGetWindowAttributes (display, root_window, &attr);
1320 screen_num = XScreenNumberOfScreen (attr.screen);
1325 display = DisplayOfScreen (screen);
1330 display = XOpenDisplay (NULL);
1332 MERROR (MERROR_WIN, NULL);
1335 screen = DefaultScreenOfDisplay (display);
1337 screen_num = XScreenNumberOfScreen (screen);
1339 depth = DefaultDepth (display, screen_num);
1343 cmap = DefaultColormap (display, screen_num);
1345 for (plist = display_info_list; mplist_key (plist) != Mnil;
1346 plist = mplist_next (plist))
1348 disp_info = (MDisplayInfo *) mplist_value (plist);
1349 if (disp_info->display == display)
1353 if (mplist_key (plist) != Mnil)
1354 M17N_OBJECT_REF (disp_info);
1357 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
1358 disp_info->display = display;
1359 disp_info->auto_display = auto_display;
1360 disp_info->font_registry_list = mplist ();
1361 disp_info->iso8859_1_family_list = mplist ();
1362 disp_info->iso10646_1_family_list = mplist ();
1363 disp_info->realized_font_list = mplist ();
1364 find_modifier_bits (disp_info);
1365 mplist_add (display_info_list, Mt, disp_info);
1368 for (plist = device_list; mplist_key (plist) != Mnil;
1369 plist = mplist_next (plist))
1371 device = (MWDevice *) mplist_value (plist);
1372 if (device->display_info == disp_info
1373 && device->depth == depth
1374 && device->cmap == cmap)
1378 if (mplist_key (plist) != Mnil)
1379 M17N_OBJECT_REF (device);
1382 unsigned long valuemask = GCForeground;
1385 M17N_OBJECT (device, free_device, MERROR_WIN);
1386 device->display_info = disp_info;
1387 device->screen_num = screen_num;
1388 /* A drawable on which to create GCs. */
1389 device->drawable = XCreatePixmap (display,
1390 RootWindow (display, screen_num),
1392 device->depth = depth;
1393 device->cmap = cmap;
1394 device->realized_face_list = mplist ();
1395 device->realized_fontset_list = mplist ();
1396 device->gc_list = mplist ();
1397 values.foreground = BlackPixel (display, screen_num);
1398 device->scratch_gc = XCreateGC (display, device->drawable,
1399 valuemask, &values);
1402 frame->realized_font_list = disp_info->realized_font_list;
1403 frame->realized_face_list = device->realized_face_list;
1404 frame->realized_fontset_list = device->realized_fontset_list;
1408 XtResource resources[] = {
1409 { XtNfont, XtCFont, XtRString, sizeof (String),
1410 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
1411 { XtNforeground, XtCForeground, XtRString, sizeof (String),
1412 XtOffset (AppDataPtr, foreground), XtRString, "black" },
1413 { XtNbackground, XtCBackground, XtRString, sizeof (String),
1414 XtOffset (AppDataPtr, background), XtRString, "white" },
1415 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
1416 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
1419 XtGetApplicationResources (widget, &app_data,
1420 resources, XtNumber (resources), NULL, 0);
1421 frame->foreground = msymbol (app_data.foreground);
1422 frame->background = msymbol (app_data.background);
1423 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
1427 app_data.font = DEFAULT_FONT;
1428 frame->foreground = msymbol ("black");
1429 frame->background = msymbol ("white");
1430 frame->videomode = Mnormal;
1433 frame->font = mfont ();
1436 char **names = XListFonts (display, app_data.font, 1, &nfonts);
1440 if (mwin__parse_font_name (names[0], frame->font) < 0)
1442 /* The font name does not conform to XLFD. Try to open the
1443 font and get XA_FONT property. */
1444 XFontStruct *xfont = XLoadQueryFont (display, names[0]);
1449 unsigned long value;
1452 if (XGetFontProperty (xfont, XA_FONT, &value)
1453 && (name = ((char *)
1454 XGetAtomName (display, (Atom) value))))
1456 if (mwin__parse_font_name (name, frame->font) >= 0)
1459 XFreeFont (display, xfont);
1462 XFreeFontNames (names);
1465 mwin__parse_font_name (FALLBACK_FONT, frame->font);
1468 #ifdef X_SET_ERROR_HANDLER
1469 XSetErrorHandler (x_error_handler);
1470 XSetIOErrorHandler (x_io_error_handler);
1477 mwin__close_device (MFrame *frame)
1479 M17N_OBJECT_UNREF (frame->device);
1483 mwin__device_get_prop (MWDevice *device, MSymbol key)
1485 if (key == Mdisplay)
1486 return (void *) device->display_info->display;
1488 return (void *) ScreenOfDisplay(device->display_info->display,
1489 device->screen_num);
1490 if (key == Mcolormap)
1491 return (void *) device->cmap;
1493 return (void *) device->depth;
1498 mwin__realize_face (MRealizedFace *rface)
1501 MSymbol foreground, background, videomode;
1502 MFaceHLineProp *hline;
1507 if (rface != rface->ascii_rface)
1509 rface->info = rface->ascii_rface->info;
1513 frame = rface->frame;
1514 MSTRUCT_CALLOC (info, MERROR_WIN);
1516 foreground = rface->face.property[MFACE_FOREGROUND];
1517 background = rface->face.property[MFACE_BACKGROUND];
1518 videomode = rface->face.property[MFACE_VIDEOMODE];
1520 videomode = frame->videomode;
1521 if (videomode != Mreverse)
1523 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1524 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1528 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1529 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1532 hline = rface->hline;
1536 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1538 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1545 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1547 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1549 if (box->color_left && box->color_left != box->color_top)
1550 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1552 info->gc[GC_BOX_LEFT] = info->gc[GC_NORMAL];
1554 if (box->color_bottom && box->color_bottom != box->color_top)
1555 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1557 info->gc[GC_BOX_BOTTOM] = info->gc[GC_NORMAL];
1559 if (box->color_right && box->color_right != box->color_top)
1560 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1562 info->gc[GC_BOX_RIGHT] = info->gc[GC_NORMAL];
1567 func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
1569 (func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]);
1574 mwin__free_realized_face (MRealizedFace *rface)
1576 if (rface == rface->ascii_rface)
1582 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1584 int x, int y, int width, int height, MDrawRegion region)
1586 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1589 gc = set_region (frame, gc, region);
1591 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1592 x, y, width, height);
1597 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1598 MRealizedFace *rface, int reverse,
1599 int x, int y, int width, MDrawRegion region)
1601 enum MFaceHLineType type = rface->hline->type;
1602 GCInfo *info = rface->info;
1603 GC gc = gc = info->gc[GC_HLINE];
1606 y = (type == MFACE_HLINE_BOTTOM
1607 ? y + gstring->text_descent - rface->hline->width
1608 : type == MFACE_HLINE_UNDER
1610 : type == MFACE_HLINE_STRIKE_THROUGH
1611 ? y - ((gstring->ascent + gstring->descent) / 2)
1612 : y - gstring->text_ascent);
1614 gc = set_region (frame, gc, region);
1616 for (i = 0; i < rface->hline->width; i++)
1617 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1618 x, y + i, x + width - 1, y + i);
1623 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1624 MGlyph *g, int x, int y, int width, MDrawRegion region)
1626 Display *display = FRAME_DISPLAY (frame);
1627 MRealizedFace *rface = g->rface;
1628 MFaceBoxProp *box = rface->box;
1629 GCInfo *info = rface->info;
1630 GC gc_top, gc_left, gc_right, gc_btm;
1634 y0 = y - (gstring->text_ascent
1635 + rface->box->inner_vmargin + rface->box->width);
1636 y1 = y + (gstring->text_descent
1637 + rface->box->inner_vmargin + rface->box->width - 1);
1639 gc_top = info->gc[GC_BOX_TOP];
1641 gc_top = set_region (frame, gc_top, region);
1642 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1645 gc_btm = info->gc[GC_BOX_BOTTOM];
1647 if (g->type == GLYPH_BOX)
1651 if (g->left_padding)
1652 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1654 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1656 /* Draw the top side. */
1657 for (i = 0; i < box->width; i++)
1658 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1660 /* Draw the bottom side. */
1661 if (region && gc_btm != gc_top)
1662 gc_btm = set_region (frame, gc_btm, region);
1663 for (i = 0; i < box->width; i++)
1664 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1666 if (g->left_padding > 0)
1668 /* Draw the left side. */
1669 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1673 gc_left = info->gc[GC_BOX_LEFT];
1675 gc_left = set_region (frame, gc_left, region);
1677 for (i = 0; i < rface->box->width; i++)
1678 XDrawLine (display, (Window) win, gc_left,
1679 x0 + i, y0 + i, x0 + i, y1 - i);
1683 /* Draw the right side. */
1684 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1688 gc_right = info->gc[GC_BOX_RIGHT];
1690 gc_right = set_region (frame, gc_right, region);
1692 for (i = 0; i < rface->box->width; i++)
1693 XDrawLine (display, (Window) win, gc_right,
1694 x1 - i, y0 + i, x1 - i, y1 - i);
1699 /* Draw the top side. */
1700 for (i = 0; i < box->width; i++)
1701 XDrawLine (display, (Window) win, gc_top,
1702 x, y0 + i, x + width - 1, y0 + i);
1704 /* Draw the bottom side. */
1705 if (region && gc_btm != gc_top)
1706 gc_btm = set_region (frame, gc_btm, region);
1707 for (i = 0; i < box->width; i++)
1708 XDrawLine (display, (Window) win, gc_btm,
1709 x, y1 - i, x + width - 1, y1 - i);
1716 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1717 int reverse, int x, int y,
1718 int width, int height, int row_bytes, unsigned char *bmp,
1721 Display *display = FRAME_DISPLAY (frame);
1723 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1726 gc = set_region (frame, gc, region);
1728 for (i = 0; i < height; i++, bmp += row_bytes)
1729 for (j = 0; j < width; j++)
1730 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1731 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1736 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1737 int intensity, MDrawPoint *points, int num,
1740 GCInfo *info = rface->info;
1743 if (! (gc = info->gc[intensity]))
1744 gc = info->gc[intensity] = get_gc_for_anti_alias (frame->device, info,
1747 gc = set_region (frame, gc, region);
1749 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1750 (XPoint *) points, num, CoordModeOrigin);
1755 mwin__region_from_rect (MDrawMetric *rect)
1757 MDrawRegion region1 = XCreateRegion ();
1758 MDrawRegion region2 = XCreateRegion ();
1763 xrect.width = rect->width;
1764 xrect.height = rect->height;
1765 XUnionRectWithRegion (&xrect, region1, region2);
1766 XDestroyRegion (region1);
1771 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1773 MDrawRegion region1 = XCreateRegion ();
1778 xrect.width = rect->width;
1779 xrect.height = rect->height;
1781 XUnionRegion (region, region, region1);
1782 XUnionRectWithRegion (&xrect, region1, region);
1783 XDestroyRegion (region1);
1787 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1789 MDrawRegion region = XCreateRegion ();
1791 XUnionRegion (region1, region1, region);
1792 XIntersectRegion (region, region2, region1);
1793 XDestroyRegion (region);
1797 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1799 MDrawRegion region1 = XCreateRegion ();
1804 xrect.width = rect->width;
1805 xrect.height = rect->height;
1806 XUnionRectWithRegion (&xrect, region1, region);
1807 XDestroyRegion (region1);
1811 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1815 XClipBox (region, &xrect);
1818 rect->width = xrect.width;
1819 rect->height = xrect.height;
1823 mwin__free_region (MDrawRegion region)
1825 XDestroyRegion (region);
1829 mwin__dump_region (MDrawRegion region)
1832 XClipBox (region, &rect);
1833 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1837 mwin__verify_region (MFrame *frame, MDrawRegion region)
1839 set_region (frame, ((GCInfo *) frame->rface->info)->gc[GC_NORMAL], region);
1843 mwin__create_window (MFrame *frame, MDrawWindow parent)
1845 Display *display = FRAME_DISPLAY (frame);
1847 XWMHints wm_hints = { InputHint, False };
1848 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1849 XWindowAttributes win_attrs;
1850 XSetWindowAttributes set_attrs;
1854 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1855 XGetWindowAttributes (display, (Window) parent, &win_attrs);
1856 set_attrs.background_pixel = win_attrs.backing_pixel;
1857 set_attrs.backing_store = Always;
1858 set_attrs.override_redirect = True;
1859 set_attrs.save_under = True;
1860 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1861 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1862 CopyFromParent, InputOutput, CopyFromParent,
1864 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1865 NULL, &wm_hints, &class_hints);
1866 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1867 return (MDrawWindow) win;
1871 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1873 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1878 mwin__event_window (void *event)
1880 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1884 mwin__print_event (void *arg, char *win_name)
1887 XEvent *event = (XEvent *) arg;
1889 switch (event->xany.type)
1891 case 2: event_name = "KeyPress"; break;
1892 case 3: event_name = "KeyRelease"; break;
1893 case 4: event_name = "ButtonPress"; break;
1894 case 5: event_name = "ButtonRelease"; break;
1895 case 6: event_name = "MotionNotify"; break;
1896 case 7: event_name = "EnterNotify"; break;
1897 case 8: event_name = "LeaveNotify"; break;
1898 case 9: event_name = "FocusIn"; break;
1899 case 10: event_name = "FocusOut"; break;
1900 case 11: event_name = "KeymapNotify"; break;
1901 case 12: event_name = "Expose"; break;
1902 case 13: event_name = "GraphicsExpose"; break;
1903 case 14: event_name = "NoExpose"; break;
1904 case 15: event_name = "VisibilityNotify"; break;
1905 case 16: event_name = "CreateNotify"; break;
1906 case 17: event_name = "DestroyNotify"; break;
1907 case 18: event_name = "UnmapNotify"; break;
1908 case 19: event_name = "MapNotify"; break;
1909 case 20: event_name = "MapRequest"; break;
1910 case 21: event_name = "ReparentNotify"; break;
1911 case 22: event_name = "ConfigureNotify"; break;
1912 case 23: event_name = "ConfigureRequest"; break;
1913 case 24: event_name = "GravityNotify"; break;
1914 case 25: event_name = "ResizeRequest"; break;
1915 case 26: event_name = "CirculateNotify"; break;
1916 case 27: event_name = "CirculateRequest"; break;
1917 case 28: event_name = "PropertyNotify"; break;
1918 case 29: event_name = "SelectionClear"; break;
1919 case 30: event_name = "SelectionRequest"; break;
1920 case 31: event_name = "SelectionNotify"; break;
1921 case 32: event_name = "ColormapNotify"; break;
1922 case 33: event_name = "ClientMessage"; break;
1923 case 34: event_name = "MappingNotify"; break;
1924 default: event_name = "unknown";
1927 fprintf (stderr, "%s: %s\n", win_name, event_name);
1932 mwin__map_window (MFrame *frame, MDrawWindow win)
1934 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1938 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1940 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1944 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1945 MDrawMetric *geometry)
1947 Display *display = FRAME_DISPLAY (frame);
1948 XWindowAttributes attr;
1949 Window parent = (Window) parent_win, root;
1951 XGetWindowAttributes (display, (Window) win, &attr);
1952 geometry->x = attr.x + attr.border_width;
1953 geometry->y = attr.y + attr.border_width;
1954 geometry->width = attr.width;
1955 geometry->height = attr.height;
1958 parent = RootWindow (display, FRAME_SCREEN (frame));
1961 Window this_parent, *children;
1964 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1967 if (this_parent == parent || this_parent == root)
1969 win = (MDrawWindow) this_parent;
1970 XGetWindowAttributes (display, (Window) win, &attr);
1971 geometry->x += attr.x + attr.border_width;
1972 geometry->y += attr.y + attr.border_width;
1977 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1978 MDrawMetric *current, MDrawMetric *new)
1980 Display *display = FRAME_DISPLAY (frame);
1981 unsigned int mask = 0;
1982 XWindowChanges values;
1984 if (current->width != new->width)
1987 if (new->width <= 0)
1989 values.width = current->width = new->width;
1991 if (current->height != new->height)
1994 if (new->height <= 0)
1996 values.height = current->height = new->height;
1998 if (current->x != new->x)
2001 values.x = current->x = new->x;
2003 if (current->y != new->y)
2006 current->y = new->y;
2007 values.y = current->y = new->y;
2010 XConfigureWindow (display, (Window) win, mask, &values);
2014 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
2016 XEvent *event = (XEvent *) arg;
2017 MDisplayInfo *disp_info = frame->device->display_info;
2024 if (event->xany.type != KeyPress
2025 /* && event->xany.type != KeyRelease */
2028 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
2035 if (c < XK_space || c > XK_asciitilde)
2037 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
2038 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2039 if (((XKeyEvent *) event)->state & ControlMask)
2041 if (c >= 'a' && c <= 'z')
2043 if (c >= ' ' && c < 127)
2044 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2046 key = minput__char_to_key (c);
2048 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
2052 char *str = XKeysymToString (keysym);
2056 key = msymbol (str);
2057 if (((XKeyEvent *) event)->state & ShiftMask)
2058 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2059 if (((XKeyEvent *) event)->state & ControlMask)
2060 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2062 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
2063 *modifiers |= MINPUT_KEY_META_MODIFIER;
2064 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
2065 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
2066 if (((XKeyEvent *) event)->state & disp_info->super_mask)
2067 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
2068 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
2069 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
2076 mwin__get_selection_text (MFrame *frame)
2083 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
2085 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
2087 Display *display = FRAME_DISPLAY (frame);
2088 GCInfo *info = rface->info;
2091 for (i = 0; i <= GC_INVERSE; i++)
2093 XGetGCValues (display, info->gc[i], valuemask, &values);
2094 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
2095 values.foreground, values.background);
2096 fprintf (stderr, "\n");
2101 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2106 /*** @addtogroup m17nFrame */
2111 @name Variables: Keys of frame parameter (X specific).
2113 These are the symbols to use as parameter keys for the function
2114 mframe () (which see). They are also keys of a frame property
2115 (except for #Mwidget). */
2118 /* Keywords for mwin__open_device (). */
2119 MSymbol Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap;
2125 /*** @addtogroup m17nInputMethodWin */
2130 @brief Input driver for XIM.
2132 The input driver #minput_xim_driver is for the foreign input
2133 method of name #Mxim. It uses XIM (X Input Methods) as a
2134 background input engine.
2136 As the symbol #Mxim has property #Minput_driver whose value is
2137 a pointer to this driver, the input method of language #Mnil
2138 and name #Mxim uses this driver.
2140 Therefore, for such input methods, the driver dependent arguments
2141 to the functions whose name begin with minput_ must be as follows.
2143 The argument $ARG of the function minput_open_im () must be a
2144 pointer to the structure #MInputXIMArgIM. See the documentation
2145 of #MInputXIMArgIM for more detail.
2147 The argument $ARG of the function minput_create_ic () must be a
2148 pointer to the structure #MInputXIMArgIC. See the documentation
2149 of #MInputXIMArgIC for more detail.
2151 The argument $ARG of the function minput_filter () must be a
2152 pointer to the structure @c XEvent. The argument $KEY is ignored.
2154 The argument $ARG of the function minput_lookup () must be the
2155 same one as that of the function minput_filter (). The argument
2159 @brief XIMÍÑÆþÎϥɥ饤¥Ð
2161 ÆþÎϥɥ饤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°Éô
2162 ÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤Î
2163 ÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2165 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2166 #Minput_driver ¤ò»ý¤Ä¤¿¤á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç
2167 ¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2169 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤˤϡ¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä
2170 °Ê²¼¤Î´Ø¿ô·²¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é
2173 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM ¤Ø¤Î
2174 ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤Î¥É
2175 ¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
2177 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC ¤Ø
2178 ¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤Î
2179 ¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
2181 ´Ø¿ô minput_filter () ¤Î°ú¿ô %ARG ¤Ï¹½Â¤ÂÎ @c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿
2182 ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2184 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2185 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì
2188 MInputDriver minput_xim_driver =
2189 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2190 xim_filter, xim_lookup, NULL };
2195 @brief Symbol of the name "xim".
2197 The variable Mxim is a symbol of name "xim". It is a name of the
2198 input method driver #minput_xim_driver. */