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 || code >= 0x10000)
814 return MCHAR_INVALID_CODE;
815 if (rfont->status == 0)
817 if (xfont_open (rfont) < 0)
818 return MCHAR_INVALID_CODE;
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)
832 if (code < min_byte2 || code > max_byte2)
833 return MCHAR_INVALID_CODE;
836 pcm = f->per_char + (code - min_byte2);
837 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
838 ? code : MCHAR_INVALID_CODE);
842 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
845 if (byte1 < min_byte1 || byte1 > max_byte1
846 || byte2 < min_byte2 || byte2 > max_byte2)
847 return MCHAR_INVALID_CODE;
851 pcm = f->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
852 + (byte2 - min_byte2));
853 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
854 ? code : MCHAR_INVALID_CODE);
859 set_region (MFrame *frame, GC gc, MDrawRegion region)
861 unsigned long valuemask = GCForeground;
863 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
864 frame->device->scratch_gc);
865 XSetRegion (FRAME_DISPLAY (frame), frame->device->scratch_gc, region);
866 return frame->device->scratch_gc;
869 /* The X font driver function RENDER. */
872 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
873 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
875 MRealizedFace *rface = from->rface;
878 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
885 /* It is assured that the all glyphs in the current range use the
886 same realized face. */
887 display = FRAME_DISPLAY (rface->frame);
890 gc = set_region (rface->frame, gc, region);
891 if (! rface->rfont || from->code == MCHAR_INVALID_CODE)
895 for (; from < to; from++)
897 XDrawRectangle (display, (Window) win, gc,
898 x0, y - gstring->ascent + 1, from->width - 1,
899 gstring->ascent + gstring->descent - 2);
905 XSetFont (display, gc, ((MXFontInfo *) (rface->rfont->info))->f->fid);
906 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
907 for (i = 0, g = from; g < to; i++, g++)
909 code[i].byte1 = g->code >> 8;
910 code[i].byte2 = g->code & 0xFF;
916 if (g->type == GLYPH_PAD)
918 else if (g->type == GLYPH_SPACE)
919 for (; g < to && g->type == GLYPH_SPACE; g++)
921 else if (! g->rface->rfont)
923 if ((g->c >= 0x200B && g->c <= 0x200F)
924 || (g->c >= 0x202A && g->c <= 0x202E))
928 /* As a font is not found for this character, draw an
930 int box_width = g->width;
931 int box_height = gstring->ascent + gstring->descent;
937 XDrawRectangle (display, (Window) win, gc,
938 x, y - gstring->ascent, box_width, box_height);
942 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
944 XDrawString16 (display, (Window) win, gc,
945 x + g->xoff, y + g->yoff, code + (g - from), 1);
952 int code_idx = g - from;
955 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
958 XDrawString16 (display, (Window) win, gc, orig_x, y,
966 /* XIM (X Input Method) handler */
968 typedef struct MInputXIMMethodInfo
974 } MInputXIMMethodInfo;
976 typedef struct MInputXIMContextInfo
980 MConverter *converter;
981 } MInputXIMContextInfo;
984 xim_open_im (MInputMethod *im)
986 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
987 MLocale *saved, *this;
988 char *save_modifier_list;
990 MInputXIMMethodInfo *im_info;
992 saved = mlocale_set (LC_CTYPE, NULL);
993 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
995 /* The specified locale is not supported. */
996 MERROR (MERROR_LOCALE, -1);
997 if (mlocale_get_prop (this, Mcoding) == Mnil)
999 /* Unable to decode the output of XIM. */
1000 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1001 MERROR (MERROR_LOCALE, -1);
1004 if (arg->modifier_list)
1005 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
1007 save_modifier_list = XSetLocaleModifiers ("");
1008 if (! save_modifier_list)
1010 /* The specified locale is not supported by X. */
1011 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1012 MERROR (MERROR_LOCALE, -1);
1015 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
1018 /* No input method is available in the current locale. */
1019 XSetLocaleModifiers (save_modifier_list);
1020 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1021 MERROR (MERROR_WIN, -1);
1024 MSTRUCT_MALLOC (im_info, MERROR_WIN);
1025 im_info->display = arg->display;
1027 im_info->language = mlocale_get_prop (this, Mlanguage);
1028 im_info->coding = mlocale_get_prop (this, Mcoding);
1031 XSetLocaleModifiers (save_modifier_list);
1032 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1038 xim_close_im (MInputMethod *im)
1040 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
1042 XCloseIM (im_info->xim);
1047 xim_create_ic (MInputContext *ic)
1049 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
1050 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1051 MInputXIMContextInfo *ic_info;
1054 if (! arg->input_style)
1056 /* By default, use Root style. */
1057 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
1058 arg->preedit_attrs = NULL;
1059 arg->status_attrs = NULL;
1062 if (! arg->preedit_attrs && ! arg->status_attrs)
1063 xic = XCreateIC (im_info->xim,
1064 XNInputStyle, arg->input_style,
1065 XNClientWindow, arg->client_win,
1066 XNFocusWindow, arg->focus_win,
1068 else if (arg->preedit_attrs && ! arg->status_attrs)
1069 xic = XCreateIC (im_info->xim,
1070 XNInputStyle, arg->input_style,
1071 XNClientWindow, arg->client_win,
1072 XNFocusWindow, arg->focus_win,
1073 XNPreeditAttributes, arg->preedit_attrs,
1075 else if (! arg->preedit_attrs && arg->status_attrs)
1076 xic = XCreateIC (im_info->xim,
1077 XNInputStyle, arg->input_style,
1078 XNClientWindow, arg->client_win,
1079 XNFocusWindow, arg->focus_win,
1080 XNStatusAttributes, arg->status_attrs,
1083 xic = XCreateIC (im_info->xim,
1084 XNInputStyle, arg->input_style,
1085 XNClientWindow, arg->client_win,
1086 XNFocusWindow, arg->focus_win,
1087 XNPreeditAttributes, arg->preedit_attrs,
1088 XNStatusAttributes, arg->status_attrs,
1091 MERROR (MERROR_WIN, -1);
1093 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
1095 ic_info->win = arg->focus_win;
1096 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
1102 xim_destroy_ic (MInputContext *ic)
1104 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1106 XDestroyIC (ic_info->xic);
1107 mconv_free_converter (ic_info->converter);
1113 xim_filter (MInputContext *ic, MSymbol key, void *event)
1115 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1117 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
1122 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1124 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1125 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1126 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
1132 buf = (char *) alloca (512);
1133 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
1134 if (status == XBufferOverflow)
1136 buf = (char *) alloca (len);
1137 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
1140 mtext_reset (ic->produced);
1144 mconv_reset_converter (ic_info->converter);
1145 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
1146 mconv_decode (ic_info->converter, ic->produced);
1147 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1148 Mlanguage, (void *) im_info->language);
1149 mtext_cpy (mt, ic->produced);
1150 mtext_reset (ic->produced);
1156 #ifdef X_SET_ERROR_HANDLER
1158 x_error_handler (Display *display, XErrorEvent *error)
1165 x_io_error_handler (Display *display)
1177 Mdisplay = msymbol ("display");
1178 Mscreen = msymbol ("screen");
1179 Mdrawable = msymbol ("drawable");
1180 Mdepth = msymbol ("depth");
1181 Mwidget = msymbol ("widget");
1182 M_iso8859_1 = msymbol ("iso8859-1");
1183 M_iso10646_1 = msymbol ("iso10646-1");
1185 display_info_list = mplist ();
1186 device_list = mplist ();
1188 mfont__driver_list[MFONT_TYPE_WIN] = &xfont_driver;
1190 Mxim = msymbol ("xim");
1191 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
1199 M17N_OBJECT_UNREF (display_info_list);
1200 M17N_OBJECT_UNREF (device_list);
1204 mwin__parse_font_name (char *name, MFont *font)
1206 char *field[XLFD_FIELD_MAX];
1207 unsigned short size, resy;
1208 MSymbol attrs[MFONT_PROPERTY_MAX];
1209 char *copy = (char *) alloca (512);
1211 char *p, *last = NULL;
1213 len = strlen (name) + 1;
1214 for (i = 0, p = name; *p; p++)
1218 else if (p > name && *p == '*' && p[-1] == '-')
1222 memcpy (copy, name, len);
1225 memcpy (copy, name, last - name);
1227 strcat (copy, "-*");
1228 strcat (copy, last);
1231 if (split_font_name (copy, field, &size, &resy) < 0)
1233 attrs[MFONT_FOUNDRY]
1234 = *(field[XLFD_FOUNDRY]) != '*' ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
1236 = *(field[XLFD_FAMILY]) != '*' ? msymbol (field[XLFD_FAMILY]) : Mnil;
1238 = *(field[XLFD_WEIGHT]) != '*' ? msymbol (field[XLFD_WEIGHT]) : Mnil;
1240 = *(field[XLFD_SLANT]) != '*' ? msymbol (field[XLFD_SLANT]) : Mnil;
1241 attrs[MFONT_STRETCH]
1242 = *(field[XLFD_SWIDTH]) != '*' ? msymbol (field[XLFD_SWIDTH]) : Mnil;
1243 attrs[MFONT_ADSTYLE]
1244 = *(field[XLFD_ADSTYLE]) != '*' ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
1245 attrs[MFONT_REGISTRY]
1246 = *(field[XLFD_REGISTRY]) != '*' ? msymbol (field[XLFD_REGISTRY]) : Mnil;
1247 mfont__set_spec (font, attrs, size, resy);
1253 mwin__build_font_name (MFont *font)
1257 if (build_font_name (font, name, 1024) < 0)
1259 return strdup (name);
1262 /** Return an MWDevice object corresponding to a display specified in
1265 It searches device_list for a device matching the display. If
1266 found, return the found object. Otherwise, return a newly created
1270 mwin__open_device (MFrame *frame, MPlist *param)
1272 Display *display = NULL;
1273 Screen *screen = NULL;
1275 Drawable drawable = 0;
1276 Widget widget = NULL;
1278 int auto_display = 0;
1279 MDisplayInfo *disp_info = NULL;
1280 MWDevice *device = NULL;
1282 XWindowAttributes attr;
1288 for (plist = param; (key = mplist_key (plist)) != Mnil;
1289 plist = mplist_next (plist))
1291 if (key == Mdisplay)
1292 display = (Display *) mplist_value (plist);
1293 else if (key == Mscreen)
1294 screen = mplist_value (plist);
1295 else if (key == Mdrawable)
1296 drawable = (Drawable) mplist_value (plist);
1297 else if (key == Mdepth)
1298 depth = (unsigned) mplist_value (plist);
1299 else if (key == Mwidget)
1300 widget = (Widget) mplist_value (plist);
1301 else if (key == Mcolormap)
1302 cmap = (Colormap) mplist_value (plist);
1307 display = XtDisplay (widget);
1308 screen_num = XScreenNumberOfScreen (XtScreen (widget));
1309 depth = DefaultDepth (display, screen_num);
1315 unsigned width, height, border_width;
1318 MERROR (MERROR_WIN, NULL);
1319 XGetGeometry (display, drawable, &root_window,
1320 &x, &y, &width, &height, &border_width, &depth);
1321 XGetWindowAttributes (display, root_window, &attr);
1322 screen_num = XScreenNumberOfScreen (attr.screen);
1327 display = DisplayOfScreen (screen);
1332 display = XOpenDisplay (NULL);
1334 MERROR (MERROR_WIN, NULL);
1337 screen = DefaultScreenOfDisplay (display);
1339 screen_num = XScreenNumberOfScreen (screen);
1341 depth = DefaultDepth (display, screen_num);
1345 cmap = DefaultColormap (display, screen_num);
1347 for (plist = display_info_list; mplist_key (plist) != Mnil;
1348 plist = mplist_next (plist))
1350 disp_info = (MDisplayInfo *) mplist_value (plist);
1351 if (disp_info->display == display)
1355 if (mplist_key (plist) != Mnil)
1356 M17N_OBJECT_REF (disp_info);
1359 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
1360 disp_info->display = display;
1361 disp_info->auto_display = auto_display;
1362 disp_info->font_registry_list = mplist ();
1363 disp_info->iso8859_1_family_list = mplist ();
1364 disp_info->iso10646_1_family_list = mplist ();
1365 disp_info->realized_font_list = mplist ();
1366 find_modifier_bits (disp_info);
1367 mplist_add (display_info_list, Mt, disp_info);
1370 for (plist = device_list; mplist_key (plist) != Mnil;
1371 plist = mplist_next (plist))
1373 device = (MWDevice *) mplist_value (plist);
1374 if (device->display_info == disp_info
1375 && device->depth == depth
1376 && device->cmap == cmap)
1380 if (mplist_key (plist) != Mnil)
1381 M17N_OBJECT_REF (device);
1384 unsigned long valuemask = GCForeground;
1387 M17N_OBJECT (device, free_device, MERROR_WIN);
1388 device->display_info = disp_info;
1389 device->screen_num = screen_num;
1390 /* A drawable on which to create GCs. */
1391 device->drawable = XCreatePixmap (display,
1392 RootWindow (display, screen_num),
1394 device->depth = depth;
1395 device->cmap = cmap;
1396 device->realized_face_list = mplist ();
1397 device->realized_fontset_list = mplist ();
1398 device->gc_list = mplist ();
1399 values.foreground = BlackPixel (display, screen_num);
1400 device->scratch_gc = XCreateGC (display, device->drawable,
1401 valuemask, &values);
1404 frame->realized_font_list = disp_info->realized_font_list;
1405 frame->realized_face_list = device->realized_face_list;
1406 frame->realized_fontset_list = device->realized_fontset_list;
1410 XtResource resources[] = {
1411 { XtNfont, XtCFont, XtRString, sizeof (String),
1412 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
1413 { XtNforeground, XtCForeground, XtRString, sizeof (String),
1414 XtOffset (AppDataPtr, foreground), XtRString, "black" },
1415 { XtNbackground, XtCBackground, XtRString, sizeof (String),
1416 XtOffset (AppDataPtr, background), XtRString, "white" },
1417 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
1418 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
1421 XtGetApplicationResources (widget, &app_data,
1422 resources, XtNumber (resources), NULL, 0);
1423 frame->foreground = msymbol (app_data.foreground);
1424 frame->background = msymbol (app_data.background);
1425 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
1429 app_data.font = DEFAULT_FONT;
1430 frame->foreground = msymbol ("black");
1431 frame->background = msymbol ("white");
1432 frame->videomode = Mnormal;
1435 frame->font = mfont ();
1438 char **names = XListFonts (display, app_data.font, 1, &nfonts);
1442 if (mwin__parse_font_name (names[0], frame->font) < 0)
1444 /* The font name does not conform to XLFD. Try to open the
1445 font and get XA_FONT property. */
1446 XFontStruct *xfont = XLoadQueryFont (display, names[0]);
1451 unsigned long value;
1454 if (XGetFontProperty (xfont, XA_FONT, &value)
1455 && (name = ((char *)
1456 XGetAtomName (display, (Atom) value))))
1458 if (mwin__parse_font_name (name, frame->font) >= 0)
1461 XFreeFont (display, xfont);
1464 XFreeFontNames (names);
1467 mwin__parse_font_name (FALLBACK_FONT, frame->font);
1470 #ifdef X_SET_ERROR_HANDLER
1471 XSetErrorHandler (x_error_handler);
1472 XSetIOErrorHandler (x_io_error_handler);
1479 mwin__close_device (MFrame *frame)
1481 M17N_OBJECT_UNREF (frame->device);
1485 mwin__device_get_prop (MWDevice *device, MSymbol key)
1487 if (key == Mdisplay)
1488 return (void *) device->display_info->display;
1490 return (void *) ScreenOfDisplay(device->display_info->display,
1491 device->screen_num);
1492 if (key == Mcolormap)
1493 return (void *) device->cmap;
1495 return (void *) device->depth;
1500 mwin__realize_face (MRealizedFace *rface)
1503 MSymbol foreground, background, videomode;
1504 MFaceHLineProp *hline;
1509 if (rface != rface->ascii_rface)
1511 rface->info = rface->ascii_rface->info;
1515 frame = rface->frame;
1516 MSTRUCT_CALLOC (info, MERROR_WIN);
1518 foreground = rface->face.property[MFACE_FOREGROUND];
1519 background = rface->face.property[MFACE_BACKGROUND];
1520 videomode = rface->face.property[MFACE_VIDEOMODE];
1522 videomode = frame->videomode;
1523 if (videomode != Mreverse)
1525 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1526 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1530 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1531 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1534 hline = rface->hline;
1538 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1540 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1547 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1549 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1551 if (box->color_left && box->color_left != box->color_top)
1552 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1554 info->gc[GC_BOX_LEFT] = info->gc[GC_NORMAL];
1556 if (box->color_bottom && box->color_bottom != box->color_top)
1557 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1559 info->gc[GC_BOX_BOTTOM] = info->gc[GC_NORMAL];
1561 if (box->color_right && box->color_right != box->color_top)
1562 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1564 info->gc[GC_BOX_RIGHT] = info->gc[GC_NORMAL];
1569 func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
1571 (func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]);
1576 mwin__free_realized_face (MRealizedFace *rface)
1578 if (rface == rface->ascii_rface)
1584 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1586 int x, int y, int width, int height, MDrawRegion region)
1588 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1591 gc = set_region (frame, gc, region);
1593 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1594 x, y, width, height);
1599 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1600 MRealizedFace *rface, int reverse,
1601 int x, int y, int width, MDrawRegion region)
1603 enum MFaceHLineType type = rface->hline->type;
1604 GCInfo *info = rface->info;
1605 GC gc = gc = info->gc[GC_HLINE];
1608 y = (type == MFACE_HLINE_BOTTOM
1609 ? y + gstring->text_descent - rface->hline->width
1610 : type == MFACE_HLINE_UNDER
1612 : type == MFACE_HLINE_STRIKE_THROUGH
1613 ? y - ((gstring->ascent + gstring->descent) / 2)
1614 : y - gstring->text_ascent);
1616 gc = set_region (frame, gc, region);
1618 for (i = 0; i < rface->hline->width; i++)
1619 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1620 x, y + i, x + width - 1, y + i);
1625 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1626 MGlyph *g, int x, int y, int width, MDrawRegion region)
1628 Display *display = FRAME_DISPLAY (frame);
1629 MRealizedFace *rface = g->rface;
1630 MFaceBoxProp *box = rface->box;
1631 GCInfo *info = rface->info;
1632 GC gc_top, gc_left, gc_right, gc_btm;
1636 y0 = y - (gstring->text_ascent
1637 + rface->box->inner_vmargin + rface->box->width);
1638 y1 = y + (gstring->text_descent
1639 + rface->box->inner_vmargin + rface->box->width - 1);
1641 gc_top = info->gc[GC_BOX_TOP];
1643 gc_top = set_region (frame, gc_top, region);
1644 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1647 gc_btm = info->gc[GC_BOX_BOTTOM];
1649 if (g->type == GLYPH_BOX)
1653 if (g->left_padding)
1654 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1656 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1658 /* Draw the top side. */
1659 for (i = 0; i < box->width; i++)
1660 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1662 /* Draw the bottom side. */
1663 if (region && gc_btm != gc_top)
1664 gc_btm = set_region (frame, gc_btm, region);
1665 for (i = 0; i < box->width; i++)
1666 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1668 if (g->left_padding > 0)
1670 /* Draw the left side. */
1671 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1675 gc_left = info->gc[GC_BOX_LEFT];
1677 gc_left = set_region (frame, gc_left, region);
1679 for (i = 0; i < rface->box->width; i++)
1680 XDrawLine (display, (Window) win, gc_left,
1681 x0 + i, y0 + i, x0 + i, y1 - i);
1685 /* Draw the right side. */
1686 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1690 gc_right = info->gc[GC_BOX_RIGHT];
1692 gc_right = set_region (frame, gc_right, region);
1694 for (i = 0; i < rface->box->width; i++)
1695 XDrawLine (display, (Window) win, gc_right,
1696 x1 - i, y0 + i, x1 - i, y1 - i);
1701 /* Draw the top side. */
1702 for (i = 0; i < box->width; i++)
1703 XDrawLine (display, (Window) win, gc_top,
1704 x, y0 + i, x + width - 1, y0 + i);
1706 /* Draw the bottom side. */
1707 if (region && gc_btm != gc_top)
1708 gc_btm = set_region (frame, gc_btm, region);
1709 for (i = 0; i < box->width; i++)
1710 XDrawLine (display, (Window) win, gc_btm,
1711 x, y1 - i, x + width - 1, y1 - i);
1718 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1719 int reverse, int x, int y,
1720 int width, int height, int row_bytes, unsigned char *bmp,
1723 Display *display = FRAME_DISPLAY (frame);
1725 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1728 gc = set_region (frame, gc, region);
1730 for (i = 0; i < height; i++, bmp += row_bytes)
1731 for (j = 0; j < width; j++)
1732 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1733 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1738 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1739 int intensity, MDrawPoint *points, int num,
1742 GCInfo *info = rface->info;
1745 if (! (gc = info->gc[intensity]))
1746 gc = info->gc[intensity] = get_gc_for_anti_alias (frame->device, info,
1749 gc = set_region (frame, gc, region);
1751 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1752 (XPoint *) points, num, CoordModeOrigin);
1757 mwin__region_from_rect (MDrawMetric *rect)
1759 MDrawRegion region1 = XCreateRegion ();
1760 MDrawRegion region2 = XCreateRegion ();
1765 xrect.width = rect->width;
1766 xrect.height = rect->height;
1767 XUnionRectWithRegion (&xrect, region1, region2);
1768 XDestroyRegion (region1);
1773 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1775 MDrawRegion region1 = XCreateRegion ();
1780 xrect.width = rect->width;
1781 xrect.height = rect->height;
1783 XUnionRegion (region, region, region1);
1784 XUnionRectWithRegion (&xrect, region1, region);
1785 XDestroyRegion (region1);
1789 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1791 MDrawRegion region = XCreateRegion ();
1793 XUnionRegion (region1, region1, region);
1794 XIntersectRegion (region, region2, region1);
1795 XDestroyRegion (region);
1799 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1801 MDrawRegion region1 = XCreateRegion ();
1806 xrect.width = rect->width;
1807 xrect.height = rect->height;
1808 XUnionRectWithRegion (&xrect, region1, region);
1809 XDestroyRegion (region1);
1813 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1817 XClipBox (region, &xrect);
1820 rect->width = xrect.width;
1821 rect->height = xrect.height;
1825 mwin__free_region (MDrawRegion region)
1827 XDestroyRegion (region);
1831 mwin__dump_region (MDrawRegion region)
1834 XClipBox (region, &rect);
1835 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1839 mwin__verify_region (MFrame *frame, MDrawRegion region)
1841 set_region (frame, ((GCInfo *) frame->rface->info)->gc[GC_NORMAL], region);
1845 mwin__create_window (MFrame *frame, MDrawWindow parent)
1847 Display *display = FRAME_DISPLAY (frame);
1849 XWMHints wm_hints = { InputHint, False };
1850 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1851 XSetWindowAttributes set_attrs;
1854 GCInfo *info = frame->rface->info;
1857 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1858 mask = GCForeground;
1859 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1860 set_attrs.background_pixel = values.foreground;
1861 set_attrs.backing_store = Always;
1862 set_attrs.override_redirect = True;
1863 set_attrs.save_under = True;
1864 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1865 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1866 CopyFromParent, InputOutput, CopyFromParent,
1868 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1869 NULL, &wm_hints, &class_hints);
1870 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1871 return (MDrawWindow) win;
1875 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1877 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1882 mwin__event_window (void *event)
1884 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1888 mwin__print_event (void *arg, char *win_name)
1891 XEvent *event = (XEvent *) arg;
1893 switch (event->xany.type)
1895 case 2: event_name = "KeyPress"; break;
1896 case 3: event_name = "KeyRelease"; break;
1897 case 4: event_name = "ButtonPress"; break;
1898 case 5: event_name = "ButtonRelease"; break;
1899 case 6: event_name = "MotionNotify"; break;
1900 case 7: event_name = "EnterNotify"; break;
1901 case 8: event_name = "LeaveNotify"; break;
1902 case 9: event_name = "FocusIn"; break;
1903 case 10: event_name = "FocusOut"; break;
1904 case 11: event_name = "KeymapNotify"; break;
1905 case 12: event_name = "Expose"; break;
1906 case 13: event_name = "GraphicsExpose"; break;
1907 case 14: event_name = "NoExpose"; break;
1908 case 15: event_name = "VisibilityNotify"; break;
1909 case 16: event_name = "CreateNotify"; break;
1910 case 17: event_name = "DestroyNotify"; break;
1911 case 18: event_name = "UnmapNotify"; break;
1912 case 19: event_name = "MapNotify"; break;
1913 case 20: event_name = "MapRequest"; break;
1914 case 21: event_name = "ReparentNotify"; break;
1915 case 22: event_name = "ConfigureNotify"; break;
1916 case 23: event_name = "ConfigureRequest"; break;
1917 case 24: event_name = "GravityNotify"; break;
1918 case 25: event_name = "ResizeRequest"; break;
1919 case 26: event_name = "CirculateNotify"; break;
1920 case 27: event_name = "CirculateRequest"; break;
1921 case 28: event_name = "PropertyNotify"; break;
1922 case 29: event_name = "SelectionClear"; break;
1923 case 30: event_name = "SelectionRequest"; break;
1924 case 31: event_name = "SelectionNotify"; break;
1925 case 32: event_name = "ColormapNotify"; break;
1926 case 33: event_name = "ClientMessage"; break;
1927 case 34: event_name = "MappingNotify"; break;
1928 default: event_name = "unknown";
1931 fprintf (stderr, "%s: %s\n", win_name, event_name);
1936 mwin__map_window (MFrame *frame, MDrawWindow win)
1938 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1942 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1944 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1948 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1949 MDrawMetric *geometry)
1951 Display *display = FRAME_DISPLAY (frame);
1952 XWindowAttributes attr;
1953 Window parent = (Window) parent_win, root;
1955 XGetWindowAttributes (display, (Window) win, &attr);
1956 geometry->x = attr.x + attr.border_width;
1957 geometry->y = attr.y + attr.border_width;
1958 geometry->width = attr.width;
1959 geometry->height = attr.height;
1962 parent = RootWindow (display, FRAME_SCREEN (frame));
1965 Window this_parent, *children;
1968 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1971 if (this_parent == parent || this_parent == root)
1973 win = (MDrawWindow) this_parent;
1974 XGetWindowAttributes (display, (Window) win, &attr);
1975 geometry->x += attr.x + attr.border_width;
1976 geometry->y += attr.y + attr.border_width;
1981 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1982 MDrawMetric *current, MDrawMetric *new)
1984 Display *display = FRAME_DISPLAY (frame);
1985 unsigned int mask = 0;
1986 XWindowChanges values;
1988 if (current->width != new->width)
1991 if (new->width <= 0)
1993 values.width = current->width = new->width;
1995 if (current->height != new->height)
1998 if (new->height <= 0)
2000 values.height = current->height = new->height;
2002 if (current->x != new->x)
2005 values.x = current->x = new->x;
2007 if (current->y != new->y)
2010 current->y = new->y;
2011 values.y = current->y = new->y;
2014 XConfigureWindow (display, (Window) win, mask, &values);
2015 XClearWindow (display, (Window) win);
2019 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
2021 XEvent *event = (XEvent *) arg;
2022 MDisplayInfo *disp_info = frame->device->display_info;
2029 if (event->xany.type != KeyPress
2030 /* && event->xany.type != KeyRelease */
2033 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
2040 if (c < XK_space || c > XK_asciitilde)
2042 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
2043 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2044 if (((XKeyEvent *) event)->state & ControlMask)
2046 if (c >= 'a' && c <= 'z')
2048 if (c >= ' ' && c < 127)
2049 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2051 key = minput__char_to_key (c);
2053 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
2057 char *str = XKeysymToString (keysym);
2061 key = msymbol (str);
2062 if (((XKeyEvent *) event)->state & ShiftMask)
2063 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2064 if (((XKeyEvent *) event)->state & ControlMask)
2065 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2067 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
2068 *modifiers |= MINPUT_KEY_META_MODIFIER;
2069 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
2070 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
2071 if (((XKeyEvent *) event)->state & disp_info->super_mask)
2072 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
2073 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
2074 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
2081 mwin__get_selection_text (MFrame *frame)
2088 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
2090 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
2092 Display *display = FRAME_DISPLAY (frame);
2093 GCInfo *info = rface->info;
2096 for (i = 0; i <= GC_INVERSE; i++)
2098 XGetGCValues (display, info->gc[i], valuemask, &values);
2099 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
2100 values.foreground, values.background);
2101 fprintf (stderr, "\n");
2106 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2111 /*** @addtogroup m17nFrame */
2116 @name Variables: Keys of frame parameter (X specific).
2118 These are the symbols to use as parameter keys for the function
2119 mframe () (which see). They are also keys of a frame property
2120 (except for #Mwidget). */
2123 /* Keywords for mwin__open_device (). */
2124 MSymbol Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap;
2130 /*** @addtogroup m17nInputMethodWin */
2135 @brief Input driver for XIM.
2137 The input driver #minput_xim_driver is for the foreign input
2138 method of name #Mxim. It uses XIM (X Input Methods) as a
2139 background input engine.
2141 As the symbol #Mxim has property #Minput_driver whose value is
2142 a pointer to this driver, the input method of language #Mnil
2143 and name #Mxim uses this driver.
2145 Therefore, for such input methods, the driver dependent arguments
2146 to the functions whose name begin with minput_ must be as follows.
2148 The argument $ARG of the function minput_open_im () must be a
2149 pointer to the structure #MInputXIMArgIM. See the documentation
2150 of #MInputXIMArgIM for more detail.
2152 The argument $ARG of the function minput_create_ic () must be a
2153 pointer to the structure #MInputXIMArgIC. See the documentation
2154 of #MInputXIMArgIC for more detail.
2156 The argument $ARG of the function minput_filter () must be a
2157 pointer to the structure @c XEvent. The argument $KEY is ignored.
2159 The argument $ARG of the function minput_lookup () must be the
2160 same one as that of the function minput_filter (). The argument
2164 @brief XIMÍÑÆþÎϥɥ饤¥Ð
2166 ÆþÎϥɥ饤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°Éô
2167 ÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤Î
2168 ÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2170 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2171 #Minput_driver ¤ò»ý¤Ä¤¿¤á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç
2172 ¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2174 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤˤϡ¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä
2175 °Ê²¼¤Î´Ø¿ô·²¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é
2178 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM ¤Ø¤Î
2179 ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤Î¥É
2180 ¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
2182 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC ¤Ø
2183 ¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤Î
2184 ¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
2186 ´Ø¿ô minput_filter () ¤Î°ú¿ô %ARG ¤Ï¹½Â¤ÂÎ @c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿
2187 ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2189 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2190 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì
2193 MInputDriver minput_xim_driver =
2194 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2195 xim_filter, xim_lookup, NULL };
2200 @brief Symbol of the name "xim".
2202 The variable Mxim is a symbol of name "xim". It is a name of the
2203 input method driver #minput_xim_driver. */