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;
89 /* Common header for the m17n object. */
92 MDisplayInfo *display_info;
102 unsigned long foreground, background;
104 /** List of pointers to realized faces on the frame. */
105 MPlist *realized_face_list;
107 /** List of pointers to realized fontsets on the frame. */
108 MPlist *realized_fontset_list;
112 static MPlist *device_list;
114 static MSymbol M_iso8859_1, M_iso10646_1;
116 #define FRAME_DISPLAY(frame) (frame->device->display_info->display)
117 #define FRAME_SCREEN(frame) (frame->device->screen_num)
120 free_display_info (void *object)
122 MDisplayInfo *disp_info = (MDisplayInfo *) object;
125 for (plist = disp_info->font_registry_list;
126 mplist_key (plist) != Mnil; plist = mplist_next (plist))
128 MFontList *registry_list = mplist_value (plist);
130 if (registry_list->fonts)
131 free (registry_list->fonts);
132 free (registry_list);
134 M17N_OBJECT_UNREF (disp_info->font_registry_list);
136 for (plist = disp_info->iso8859_1_family_list;
137 mplist_key (plist) != Mnil; plist = mplist_next (plist))
139 MFontList *family_list = mplist_value (plist);
141 if (family_list->fonts)
142 free (family_list->fonts);
145 M17N_OBJECT_UNREF (disp_info->iso8859_1_family_list);
147 for (plist = disp_info->iso10646_1_family_list;
148 mplist_key (plist) != Mnil; plist = mplist_next (plist))
150 MFontList *family_list = mplist_value (plist);
152 if (family_list->fonts)
153 free (family_list->fonts);
156 M17N_OBJECT_UNREF (disp_info->iso10646_1_family_list);
158 for (plist = disp_info->realized_font_list;
159 mplist_key (plist) != Mnil; plist = mplist_next (plist))
160 mfont__free_realized ((MRealizedFont *) mplist_value (plist));
161 M17N_OBJECT_UNREF (disp_info->realized_font_list);
163 if (disp_info->auto_display)
164 XCloseDisplay (disp_info->display);
170 free_device (void *object)
172 MWDevice *device = (MWDevice *) object;
175 for (plist = device->realized_fontset_list;
176 mplist_key (plist) != Mnil; plist = mplist_next (plist))
177 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
178 M17N_OBJECT_UNREF (device->realized_fontset_list);
180 for (plist = device->realized_face_list;
181 mplist_key (plist) != Mnil; plist = mplist_next (plist))
182 mface__free_realized ((MRealizedFace *) mplist_value (plist));
183 M17N_OBJECT_UNREF (device->realized_face_list);
185 XFreePixmap (device->display_info->display, device->drawable);
186 M17N_OBJECT_UNREF (device->display_info);
192 find_modifier_bits (MDisplayInfo *disp_info)
194 Display *display = disp_info->display;
195 XModifierKeymap *mods;
196 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
197 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
198 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
199 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
200 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
201 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
202 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
203 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
206 mods = XGetModifierMapping (display);
207 /* We skip the first three sets for Shift, Lock, and Control. The
208 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
209 for (i = 3; i < 8; i++)
210 for (j = 0; j < mods->max_keypermod; j++)
212 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
216 if (code == meta_l || code == meta_r)
217 disp_info->meta_mask |= (1 << i);
218 else if (code == alt_l || code == alt_r)
219 disp_info->alt_mask |= (1 << i);
220 else if (code == super_l || code == super_r)
221 disp_info->super_mask |= (1 << i);
222 else if (code == hyper_l || code == hyper_r)
223 disp_info->hyper_mask |= (1 << i);
226 /* If meta keys are not in any modifier, use alt keys as meta
228 if (! disp_info->meta_mask)
230 disp_info->meta_mask = disp_info->alt_mask;
231 disp_info->alt_mask = 0;
233 /* If both meta and alt are assigned to the same modifier, give meta
235 if (disp_info->meta_mask & disp_info->alt_mask)
236 disp_info->alt_mask &= ~disp_info->meta_mask;
238 XFreeModifiermap (mods);
242 get_color (Display *display, Colormap cmap,
243 MSymbol color_name, MSymbol default_name,
244 unsigned long default_pixel)
248 if (XParseColor (display, cmap, msymbol_name (color_name), &exact_def)
249 && XAllocColor (display, cmap, &exact_def))
250 return exact_def.pixel;
252 if (XParseColor (display, cmap, msymbol_name (default_name), &exact_def)
253 && XAllocColor (display, cmap, &exact_def))
254 return exact_def.pixel;
256 return default_pixel;
260 /** X font handler */
262 /** Indices to each field of split font name. */
284 /** Split the fontname NAME into each XLFD field destructively. Set
285 each element of the table pointed by PROPERTY_IDX to a pointer to
286 the corresponding font property name. Store the point size and
287 the resolution-Y of the font to the place pointed by POINT and
290 If NAME does not contain all XLFD fields, the unspecified fields is
291 treated as wild cards. */
294 split_font_name (char *name, char **field,
295 unsigned short *size, unsigned short *resy)
300 for (i = 0, p = name; *p; p++)
303 if (*p == '-' && i < XLFD_FIELD_MAX)
306 if (i != XLFD_ENCODING)
311 if (i < XLFD_REGISTRY)
313 for (; i < XLFD_FIELD_MAX; i++)
316 if (*(field[XLFD_RESY]) == '*')
319 *resy = atoi (field[XLFD_RESY]);
320 if (*(field[XLFD_PIXEL]) == '*')
322 if (*(field[XLFD_POINT]) != '*')
323 *size = atoi (field[XLFD_POINT]) * *resy / 72;
327 else if (*(field[XLFD_PIXEL]) == '[')
329 /* The pixel size field specifies a transformation matrix of the
330 form "[A B C D]". The XLFD spec says that the scalar value N
331 for the pixel size is equivalent to D. */
332 char *p0 = field[XLFD_PIXEL] + 1, *p1;
335 for (i = 0; i < 4; i++, p0 = p1)
336 d = strtod (p0, &p1);
340 *size = atoi (field[XLFD_PIXEL]) * 10;
341 if (*size == 0 && *(field[XLFD_POINT]) != '*')
343 *size = atoi (field[XLFD_POINT]);
345 *size = *size * *resy / 72;
347 *size = *size * 100 / 72;
354 build_font_name (MFont *font, char *name, int limit)
359 unsigned short size, resy;
361 prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
362 prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
363 prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
364 prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
365 prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
366 prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
367 prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
368 for (len = 0, i = 0; i < 7; i++)
372 str[i] = msymbol_name (prop[i]);
373 len += strlen (str[i]);
383 + 3 /* 3 asterisks */
384 + 30 /* 3 integers (each 10 digits) */
385 + 1) /* '\0' terminal */
389 size = (int) mfont_get_prop (font, Msize);
393 size = size / 10 + 1;
394 resy = (int) mfont_get_prop (font, Mresolution);
396 sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
397 str[0], str[1], str[2], str[3], str[4], str[5],
398 size, resy, resy, str[6]);
403 build_font_list (MFrame *frame, MSymbol family, MSymbol registry,
407 MFontList *font_list;
412 MSTRUCT_CALLOC (font_list, MERROR_WIN);
416 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s",
417 msymbol_name (registry));
418 font_list->tag = registry;
422 sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s",
423 msymbol_name (family), msymbol_name (registry));
424 font_list->tag = family;
427 fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts);
430 MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN);
431 for (i = j = 0; i < nfonts; i++)
432 if (mwin__parse_font_name (fontnames[i], font_list->fonts + j) >= 0
433 && (font_list->fonts[j].property[MFONT_SIZE] != 0
434 || font_list->fonts[j].property[MFONT_RESY] == 0))
436 font_list->fonts[j].property[MFONT_TYPE] = MFONT_TYPE_WIN + 1;
439 XFreeFontNames (fontnames);
440 font_list->nfonts = j;
442 mplist_add (plist, font_list->tag, font_list);
443 return (nfonts > 0 ? font_list : NULL);
447 static MRealizedFont *xfont_select (MFrame *, MFont *, MFont *, int);
448 static int xfont_open (MRealizedFont *);
449 static void xfont_close (MRealizedFont *);
450 static void xfont_find_metric (MRealizedFont *, MGlyph *);
451 static unsigned xfont_encode_char (MRealizedFont *, int, unsigned);
452 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
453 MGlyph *, MGlyph *, int, MDrawRegion);
455 MFontDriver xfont_driver =
456 { xfont_select, xfont_open, xfont_close,
457 xfont_find_metric, xfont_encode_char, xfont_render };
459 /* The X font driver function SELECT. */
461 static MRealizedFont *
462 xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size)
464 MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
465 MRealizedFont *rfont;
466 MFontList *font_list = NULL;
469 int best_score, score;
472 || ! strchr (MSYMBOL_NAME (registry), '-'))
475 /* We handles iso8859-1 and iso10646-1 fonts specially because there
476 exists so many such fonts. */
477 if (registry == M_iso8859_1 || registry == M_iso10646_1)
480 = (registry == M_iso8859_1
481 ? frame->device->display_info->iso8859_1_family_list
482 : frame->device->display_info->iso10646_1_family_list);
483 MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY);
487 font_list = (MFontList *) mplist_get (family_list, family);
489 font_list = build_font_list (frame, family, registry, family_list);
493 family = FONT_PROPERTY (request, MFONT_FAMILY);
494 font_list = (MFontList *) mplist_get (family_list, family);
496 font_list = build_font_list (frame, family, registry, family_list);
501 MPlist *registry_list
502 = frame->device->display_info->font_registry_list;
504 font_list = (MFontList *) mplist_get (registry_list, registry);
506 font_list = build_font_list (frame, Mnil, registry, registry_list);
511 for (i = 0, best_score = -1, best_font = NULL; i < font_list->nfonts; i++)
512 if ((best_score = mfont__score (font_list->fonts + i, spec, request,
517 best_font = font_list->fonts + i;
518 for (; best_score > 0 && i < font_list->nfonts ; i++)
520 score = mfont__score (font_list->fonts + i, spec, request,
522 if (score >= 0 && score < best_score)
524 best_font = font_list->fonts + i;
529 MSTRUCT_CALLOC (rfont, MERROR_WIN);
530 rfont->frame = frame;
532 rfont->request = *request;
533 rfont->font = *best_font;
534 if (best_font->property[MFONT_SIZE] == 0)
535 rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE];
536 rfont->score = best_score;
537 rfont->driver = &xfont_driver;
549 close_xfont (void *object)
551 MXFontInfo *xfont = (MXFontInfo *) object;
554 XFreeFont (FRAME_DISPLAY (xfont->frame), xfont->f);
559 /* The X font driver function OPEN. */
562 xfont_open (MRealizedFont *rfont)
566 MFrame *frame = rfont->frame;
567 int mdebug_mask = MDEBUG_FONT;
569 /* This never fail to generate a valid fontname because open_spec
570 should correspond to a font available on the system. */
571 build_font_name (&rfont->font, name, 1024);
572 M17N_OBJECT (xfont, close_xfont, MERROR_WIN);
574 xfont->frame = frame;
575 xfont->f = XLoadQueryFont (FRAME_DISPLAY (frame), name);
579 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
582 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
584 rfont->ascent = xfont->f->ascent;
585 rfont->descent = xfont->f->descent;
590 /* The X font driver function CLOSE. */
593 xfont_close (MRealizedFont *rfont)
595 M17N_OBJECT_UNREF (rfont->info);
598 /* The X font driver function FIND_METRIC. */
601 xfont_find_metric (MRealizedFont *rfont, MGlyph *g)
603 XCharStruct *pcm = NULL;
604 MXFontInfo *xfont = (MXFontInfo *) rfont->info;
605 XFontStruct *f = xfont->f;
608 if (g->code == MCHAR_INVALID_CODE)
610 g->lbearing = f->max_bounds.lbearing;
611 g->rbearing = f->max_bounds.rbearing;
612 g->width = f->max_bounds.width;
613 g->ascent = f->ascent;
614 g->descent = f->descent;
618 byte1 = g->code >> 8;
619 byte2 = g->code & 0xFF;
621 if (f->per_char != NULL)
623 if (f->min_byte1 == 0 && f->max_byte1 == 0)
626 && byte2 >= f->min_char_or_byte2
627 && byte2 <= f->max_char_or_byte2)
628 pcm = f->per_char + byte2 - f->min_char_or_byte2;
632 if (byte1 >= f->min_byte1
633 && byte1 <= f->max_byte1
634 && byte2 >= f->min_char_or_byte2
635 && byte2 <= f->max_char_or_byte2)
638 + ((f->max_char_or_byte2-f->min_char_or_byte2 + 1)
639 * (byte1 - f->min_byte1))
640 + (byte2 - f->min_char_or_byte2));
647 g->lbearing = pcm->lbearing;
648 g->rbearing = pcm->rbearing;
649 g->width = pcm->width;
650 g->ascent = pcm->ascent;
651 g->descent = pcm->descent;
655 /* If the per_char pointer is null, all glyphs between the first
656 and last character indexes inclusive have the same
657 information, as given by both min_bounds and max_bounds. */
659 g->rbearing = f->max_bounds.width;
660 g->width = f->max_bounds.width;
661 g->ascent = f->ascent;
662 g->descent = f->descent;
667 /* The X font driver function ENCODE_CHAR. */
670 xfont_encode_char (MRealizedFont *rfont, int c, unsigned code)
674 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
677 if (rfont->status < 0)
679 if (rfont->status == 0)
681 if (xfont_open (rfont) < 0)
684 xfont = (MXFontInfo *) rfont->info;
686 all_chars_exist = (! f->per_char || f->all_chars_exist == True);
687 min_byte1 = f->min_byte1;
688 max_byte1 = f->max_byte1;
689 min_byte2 = f->min_char_or_byte2;
690 max_byte2 = f->max_char_or_byte2;
692 if (min_byte1 == 0 && max_byte1 == 0)
697 return ((code >= min_byte2 && code <= max_byte2)
698 ? code : MCHAR_INVALID_CODE);
699 pcm = f->per_char + (code - min_byte2);
700 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
701 ? code : MCHAR_INVALID_CODE);
705 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
709 return ((byte1 >= min_byte1 && byte1 <= max_byte1
710 && byte2 >= min_byte2 && byte2 <= max_byte2)
711 ? code : MCHAR_INVALID_CODE);
712 pcm = f->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
713 + (byte2 - min_byte2));
714 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
715 ? code : MCHAR_INVALID_CODE);
720 set_region (Display *display, MRealizedFace *rface, GC gc, MDrawRegion region)
725 XClipBox (region, &xrect);
726 gc1 = ((GC *) rface->info)[MFACE_GC_SCRATCH];
727 XCopyGC (display, gc, GCFont | GCForeground | GCBackground, gc1);
728 XSetRegion (display, gc1, region);
732 /* The X font driver function RENDER. */
735 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
736 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
738 MRealizedFace *rface = from->rface;
741 GC *gcs = rface->info;
742 GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
749 /* It is assured that the all glyphs in the current range use the
750 same realized face. */
751 display = FRAME_DISPLAY (rface->frame);
754 gc = set_region (display, rface, gc, region);
756 if (from->code == MCHAR_INVALID_CODE)
760 for (; from < to; from++)
762 XDrawRectangle (display, (Window) win, gc,
763 x0, y - gstring->ascent + 1, from->width - 1,
764 gstring->ascent + gstring->descent - 2);
770 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
771 for (i = 0, g = from; g < to; i++, g++)
773 code[i].byte1 = g->code >> 8;
774 code[i].byte2 = g->code & 0xFF;
780 if (g->type == GLYPH_PAD)
782 else if (g->type == GLYPH_SPACE)
783 for (; g < to && g->type == GLYPH_SPACE; g++)
785 else if (! g->rface->rfont)
787 if ((g->c >= 0x200B && g->c <= 0x200F)
788 || (g->c >= 0x202A && g->c <= 0x202E))
792 /* As a font is not found for this character, draw an
794 int box_width = g->width;
795 int box_height = gstring->ascent + gstring->descent;
801 XDrawRectangle (display, (Window) win, gc,
802 x, y - gstring->ascent, box_width, box_height);
806 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
808 XDrawString16 (display, (Window) win, gc,
809 x + g->xoff, y + g->yoff, code + (g - from), 1);
816 int code_idx = g - from;
819 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
822 XDrawString16 (display, (Window) win, gc, orig_x, y,
830 /* XIM (X Input Method) handler */
832 typedef struct MInputXIMMethodInfo
838 } MInputXIMMethodInfo;
840 typedef struct MInputXIMContextInfo
844 MConverter *converter;
845 } MInputXIMContextInfo;
848 xim_open_im (MInputMethod *im)
850 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
851 MLocale *saved, *this;
852 char *save_modifier_list;
854 MInputXIMMethodInfo *im_info;
856 saved = mlocale_set (LC_CTYPE, NULL);
857 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
859 /* The specified locale is not supported. */
860 MERROR (MERROR_LOCALE, -1);
861 if (mlocale_get_prop (this, Mcoding) == Mnil)
863 /* Unable to decode the output of XIM. */
864 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
865 MERROR (MERROR_LOCALE, -1);
868 if (arg->modifier_list)
869 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
871 save_modifier_list = XSetLocaleModifiers ("");
872 if (! save_modifier_list)
874 /* The specified locale is not supported by X. */
875 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
876 MERROR (MERROR_LOCALE, -1);
879 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
882 /* No input method is available in the current locale. */
883 XSetLocaleModifiers (save_modifier_list);
884 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
885 MERROR (MERROR_WIN, -1);
888 MSTRUCT_MALLOC (im_info, MERROR_WIN);
889 im_info->display = arg->display;
891 im_info->language = mlocale_get_prop (this, Mlanguage);
892 im_info->coding = mlocale_get_prop (this, Mcoding);
895 XSetLocaleModifiers (save_modifier_list);
896 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
902 xim_close_im (MInputMethod *im)
904 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
906 XCloseIM (im_info->xim);
911 xim_create_ic (MInputContext *ic)
913 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
914 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
915 MInputXIMContextInfo *ic_info;
918 if (! arg->input_style)
920 /* By default, use Root style. */
921 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
922 arg->preedit_attrs = NULL;
923 arg->status_attrs = NULL;
926 if (! arg->preedit_attrs && ! arg->status_attrs)
927 xic = XCreateIC (im_info->xim,
928 XNInputStyle, arg->input_style,
929 XNClientWindow, arg->client_win,
930 XNFocusWindow, arg->focus_win,
932 else if (arg->preedit_attrs && ! arg->status_attrs)
933 xic = XCreateIC (im_info->xim,
934 XNInputStyle, arg->input_style,
935 XNClientWindow, arg->client_win,
936 XNFocusWindow, arg->focus_win,
937 XNPreeditAttributes, arg->preedit_attrs,
939 else if (! arg->preedit_attrs && arg->status_attrs)
940 xic = XCreateIC (im_info->xim,
941 XNInputStyle, arg->input_style,
942 XNClientWindow, arg->client_win,
943 XNFocusWindow, arg->focus_win,
944 XNStatusAttributes, arg->status_attrs,
947 xic = XCreateIC (im_info->xim,
948 XNInputStyle, arg->input_style,
949 XNClientWindow, arg->client_win,
950 XNFocusWindow, arg->focus_win,
951 XNPreeditAttributes, arg->preedit_attrs,
952 XNStatusAttributes, arg->status_attrs,
955 MERROR (MERROR_WIN, -1);
957 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
959 ic_info->win = arg->focus_win;
960 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
966 xim_destroy_ic (MInputContext *ic)
968 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
970 XDestroyIC (ic_info->xic);
971 mconv_free_converter (ic_info->converter);
977 xim_filter (MInputContext *ic, MSymbol key, void *event)
979 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
981 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
986 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
988 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
989 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
990 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
996 buf = (char *) alloca (512);
997 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
998 if (status == XBufferOverflow)
1000 buf = (char *) alloca (len);
1001 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
1004 mtext_reset (ic->produced);
1008 mconv_reset_converter (ic_info->converter);
1009 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
1010 mconv_decode (ic_info->converter, ic->produced);
1011 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1012 Mlanguage, (void *) im_info->language);
1013 mtext_cpy (mt, ic->produced);
1014 mtext_reset (ic->produced);
1022 x_error_handler (Display *display, XErrorEvent *error)
1029 x_io_error_handler (Display *display)
1041 Mdisplay = msymbol ("display");
1042 Mscreen = msymbol ("screen");
1043 Mdrawable = msymbol ("drawable");
1044 Mdepth = msymbol ("depth");
1045 Mwidget = msymbol ("widget");
1046 M_iso8859_1 = msymbol ("iso8859-1");
1047 M_iso10646_1 = msymbol ("iso10646-1");
1049 display_info_list = mplist ();
1050 device_list = mplist ();
1052 mfont__driver_list[MFONT_TYPE_WIN] = &xfont_driver;
1054 Mxim = msymbol ("xim");
1055 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
1063 M17N_OBJECT_UNREF (display_info_list);
1064 M17N_OBJECT_UNREF (device_list);
1072 Boolean reverse_video;
1073 } AppData, *AppDataPtr;
1077 mwin__parse_font_name (char *name, MFont *font)
1079 char *field[XLFD_FIELD_MAX];
1080 unsigned short size, resy;
1081 MSymbol attrs[MFONT_PROPERTY_MAX];
1082 char *copy = (char *) alloca (512);
1084 char *p, *last = NULL;
1086 len = strlen (name) + 1;
1087 for (i = 0, p = name; *p; p++)
1091 else if (p > name && *p == '*' && p[-1] == '-')
1095 memcpy (copy, name, len);
1098 memcpy (copy, name, last - name);
1100 strcat (copy, "-*");
1101 strcat (copy, last);
1104 if (split_font_name (copy, field, &size, &resy) < 0)
1106 attrs[MFONT_FOUNDRY]
1107 = *(field[XLFD_FOUNDRY]) != '*' ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
1109 = *(field[XLFD_FAMILY]) != '*' ? msymbol (field[XLFD_FAMILY]) : Mnil;
1111 = *(field[XLFD_WEIGHT]) != '*' ? msymbol (field[XLFD_WEIGHT]) : Mnil;
1113 = *(field[XLFD_SLANT]) != '*' ? msymbol (field[XLFD_SLANT]) : Mnil;
1114 attrs[MFONT_STRETCH]
1115 = *(field[XLFD_SWIDTH]) != '*' ? msymbol (field[XLFD_SWIDTH]) : Mnil;
1116 attrs[MFONT_ADSTYLE]
1117 = *(field[XLFD_ADSTYLE]) != '*' ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
1118 attrs[MFONT_REGISTRY]
1119 = *(field[XLFD_REGISTRY]) != '*' ? msymbol (field[XLFD_REGISTRY]) : Mnil;
1120 mfont__set_spec (font, attrs, size, resy);
1126 mwin__build_font_name (MFont *font)
1130 if (build_font_name (font, name, 1024) < 0)
1132 return strdup (name);
1135 /** Return an MWDevice object corresponding to a display specified in
1138 It searches device_list for a device matching the display. If
1139 found, return the found object. Otherwise, return a newly created
1143 mwin__open_device (MFrame *frame, MPlist *param)
1145 Display *display = NULL;
1146 Screen *screen = NULL;
1148 Drawable drawable = 0;
1149 Widget widget = NULL;
1151 int auto_display = 0;
1152 MDisplayInfo *disp_info = NULL;
1153 MWDevice *device = NULL;
1155 XWindowAttributes attr;
1160 for (plist = param; (key = mplist_key (plist)) != Mnil;
1161 plist = mplist_next (plist))
1163 if (key == Mdisplay)
1164 display = (Display *) mplist_value (plist);
1165 else if (key == Mscreen)
1166 screen = mplist_value (plist);
1167 else if (key == Mdrawable)
1168 drawable = (Drawable) mplist_value (plist);
1169 else if (key == Mdepth)
1170 depth = (unsigned) mplist_value (plist);
1171 else if (key == Mwidget)
1172 widget = (Widget) mplist_value (plist);
1173 else if (key == Mcolormap)
1174 cmap = (Colormap) mplist_value (plist);
1179 display = XtDisplay (widget);
1180 screen_num = XScreenNumberOfScreen (XtScreen (widget));
1181 depth = DefaultDepth (display, screen_num);
1187 unsigned width, height, border_width;
1190 MERROR (MERROR_WIN, NULL);
1191 XGetGeometry (display, drawable, &root_window,
1192 &x, &y, &width, &height, &border_width, &depth);
1193 XGetWindowAttributes (display, root_window, &attr);
1194 screen_num = XScreenNumberOfScreen (attr.screen);
1199 display = DisplayOfScreen (screen);
1204 display = XOpenDisplay (NULL);
1206 MERROR (MERROR_WIN, NULL);
1209 screen = DefaultScreenOfDisplay (display);
1211 screen_num = XScreenNumberOfScreen (screen);
1213 depth = DefaultDepth (display, screen_num);
1217 cmap = DefaultColormap (display, screen_num);
1219 for (plist = display_info_list; mplist_key (plist) != Mnil;
1220 plist = mplist_next (plist))
1222 disp_info = (MDisplayInfo *) mplist_value (plist);
1223 if (disp_info->display == display)
1227 if (mplist_key (plist) != Mnil)
1228 M17N_OBJECT_REF (disp_info);
1231 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
1232 disp_info->display = display;
1233 disp_info->auto_display = auto_display;
1234 disp_info->font_registry_list = mplist ();
1235 disp_info->iso8859_1_family_list = mplist ();
1236 disp_info->iso10646_1_family_list = mplist ();
1237 disp_info->realized_font_list = mplist ();
1238 find_modifier_bits (disp_info);
1239 mplist_add (display_info_list, Mt, disp_info);
1242 for (plist = device_list; mplist_key (plist) != Mnil;
1243 plist = mplist_next (plist))
1245 device = (MWDevice *) mplist_value (plist);
1246 if (device->display_info == disp_info
1247 && device->depth == depth
1248 && device->cmap == cmap)
1252 if (mplist_key (plist) != Mnil)
1253 M17N_OBJECT_REF (device);
1256 M17N_OBJECT (device, free_device, MERROR_WIN);
1257 device->display_info = disp_info;
1258 device->screen_num = screen_num;
1259 /* A drawable on which to create GCs. */
1260 device->drawable = XCreatePixmap (display,
1261 RootWindow (display, screen_num),
1263 device->depth = depth;
1264 device->cmap = cmap;
1265 device->realized_face_list = mplist ();
1266 device->realized_fontset_list = mplist ();
1267 device->foreground = BlackPixel (display, screen_num);
1268 device->background = WhitePixel (display, screen_num);
1271 frame->realized_font_list = disp_info->realized_font_list;
1272 frame->realized_face_list = device->realized_face_list;
1273 frame->realized_fontset_list = device->realized_fontset_list;
1278 XtResource resources[] = {
1279 { XtNfont, XtCFont, XtRString, sizeof (String),
1280 XtOffset (AppDataPtr, font), XtRString,
1281 "-misc-fixed-medium-r-normal--*-120-*-*-*-*-iso8859-1" },
1282 { XtNforeground, XtCForeground, XtRString, sizeof (String),
1283 XtOffset (AppDataPtr, foreground), XtRString, "black" },
1284 { XtNbackground, XtCBackground, XtRString, sizeof (String),
1285 XtOffset (AppDataPtr, background), XtRString, "white" },
1286 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
1287 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
1294 XtGetApplicationResources (widget, &app_data,
1295 resources, XtNumber (resources), NULL, 0);
1296 names = XListFonts (display, app_data.font, 1, &nfonts);
1299 if (mwin__parse_font_name (names[0], &font) >= 0)
1300 face = mface_from_font (&font);
1303 /* The font name does not conform to XLFD. Try to open the
1304 font and get XA_FONT property. */
1305 XFontStruct *xfont = XLoadQueryFont (display, names[0]);
1309 unsigned long value;
1312 if (XGetFontProperty (xfont, XA_FONT, &value)
1313 && (name = ((char *)
1314 XGetAtomName (display, (Atom) value))))
1316 if (mwin__parse_font_name (name, &font) >= 0)
1317 face = mface_from_font (&font);
1319 XFreeFont (display, xfont);
1322 XFreeFontNames (names);
1325 if (app_data.reverse_video == True)
1329 mface_put_prop (face, Mvideomode, Mreverse);
1333 mplist_push (param, Mface, face);
1334 M17N_OBJECT_UNREF (face);
1337 = get_color (display, cmap, msymbol (app_data.foreground), Mnil,
1338 device->foreground);
1340 = get_color (display, cmap, msymbol (app_data.background), Mnil,
1341 device->background);
1343 XSetErrorHandler (x_error_handler);
1344 /* XSetIOErrorHandler (x_io_error_handler); */
1350 mwin__close_device (MFrame *frame)
1352 M17N_OBJECT_UNREF (frame->device);
1356 mwin__device_get_prop (MWDevice *device, MSymbol key)
1358 if (key == Mdisplay)
1359 return (void *) device->display_info->display;
1361 return (void *) ScreenOfDisplay(device->display_info->display,
1362 device->screen_num);
1363 if (key == Mcolormap)
1364 return (void *) device->cmap;
1366 return (void *) device->depth;
1371 int size, inc, used;
1375 #define REGISTER_GC(gc) \
1377 if (! gc_list.size) \
1378 MLIST_INIT1 (&gc_list, gc_table, 100); \
1379 MLIST_APPEND1 (&gc_list, gc_table, gc, MERROR_WIN); \
1383 #define UNREGISTER_GC(gc) \
1386 for (j = 0; j < gc_list.used; j++) \
1387 if (gc_list.gc_table[j] == gc) \
1388 gc_list.gc_table[j] = (GC) NULL; \
1393 mwin__realize_face (MRealizedFace *rface)
1395 MFrame *frame = rface->frame;
1396 MWDevice *device = frame->device;
1397 Display *display = FRAME_DISPLAY (frame);
1399 int mask = GCForeground | GCBackground;
1400 MSymbol foreground = rface->face.property[MFACE_FOREGROUND];
1401 MSymbol background = rface->face.property[MFACE_BACKGROUND];
1402 MFaceHLineProp *hline = rface->hline;
1403 MFaceBoxProp *box = rface->box;
1404 MFaceHookFunc func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
1405 MSymbol default_foreground
1406 = (MSymbol) mface_get_prop (frame->face, Mforeground);
1407 MSymbol default_background
1408 = (MSymbol) mface_get_prop (frame->face, Mbackground);
1410 unsigned long pixel;
1412 MTABLE_CALLOC (gcs, MFACE_GCS, MERROR_WIN);
1414 values.foreground = get_color (display, device->cmap, foreground,
1415 default_foreground, device->foreground);
1416 values.background = get_color (display, device->cmap, background,
1417 default_background, device->background);
1418 if (rface->face.property[MFACE_VIDEOMODE] == Mreverse)
1419 pixel = values.foreground,
1420 values.foreground = values.background,
1421 values.background = pixel;
1424 && rface->rfont->font.property[MFONT_TYPE] - 1 == MFONT_TYPE_WIN)
1426 values.font = ((MXFontInfo *) (rface->rfont->info))->f->fid;
1430 gcs[MFACE_GC_NORMAL] = XCreateGC (display, device->drawable, mask, &values);
1431 REGISTER_GC (gcs[MFACE_GC_NORMAL]);
1433 gcs[MFACE_GC_SCRATCH] = XCreateGC (display, device->drawable, mask, &values);
1434 REGISTER_GC (gcs[MFACE_GC_SCRATCH]);
1436 pixel = values.foreground;
1437 values.foreground = values.background;
1438 values.background = pixel;
1439 gcs[MFACE_GC_INVERSE] = XCreateGC (display, device->drawable, mask, &values);
1440 REGISTER_GC (gcs[MFACE_GC_INVERSE]);
1441 values.background = values.foreground;
1442 values.foreground = pixel;
1446 if (rface == rface->ascii_rface)
1448 /* This realized face is for ASCII. Setup GCs for hline and
1450 if (hline && hline->color != foreground)
1453 = get_color (display, device->cmap, hline->color,
1454 default_foreground, device->foreground);
1456 = XCreateGC (display, device->drawable, mask, &values);
1457 REGISTER_GC (gcs[MFACE_GC_HLINE]);
1458 values.foreground = pixel;
1466 = get_color (display, device->cmap, box->color_top,
1467 default_foreground, device->foreground);
1468 gcs[MFACE_GC_BOX_TOP]
1469 = XCreateGC (display, device->drawable, mask, &values);
1470 REGISTER_GC (gcs[MFACE_GC_BOX_TOP]);
1474 && box->color_left != box->color_top)
1477 = get_color (display, device->cmap, box->color_left,
1478 default_foreground, device->foreground);
1479 gcs[MFACE_GC_BOX_LEFT]
1480 = XCreateGC (display, device->drawable, mask, &values);
1481 REGISTER_GC (gcs[MFACE_GC_BOX_LEFT]);
1484 if (box->color_right
1485 && box->color_right != box->color_top)
1488 = get_color (display, device->cmap, box->color_right,
1489 default_foreground, device->foreground);
1490 gcs[MFACE_GC_BOX_RIGHT]
1491 = XCreateGC (display, device->drawable, mask, &values);
1492 REGISTER_GC (gcs[MFACE_GC_BOX_RIGHT]);
1495 if (box->color_bottom
1496 && box->color_bottom != box->color_top)
1499 = get_color (display, device->cmap, box->color_bottom,
1500 default_foreground, device->foreground);
1501 gcs[MFACE_GC_BOX_BOTTOM]
1502 = XCreateGC (display, device->drawable, mask, &values);
1503 REGISTER_GC (gcs[MFACE_GC_BOX_BOTTOM]);
1509 /* This realized face is not for ASCII. GCs for hline and box
1510 are shared with that of the corresponding ASCII face. */
1511 GC *ascii_gcs = rface->ascii_rface->info;
1514 for (i = MFACE_GC_HLINE; i < MFACE_GCS; i++)
1515 gcs[i] = ascii_gcs[i];
1520 (func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]);
1525 mwin__free_realized_face (MRealizedFace *rface)
1527 GC *gcs = rface->info;
1529 = rface == rface->ascii_rface ? MFACE_GCS : MFACE_GC_HLINE;
1532 for (i = 0; i < limit; i++)
1535 UNREGISTER_GC (gcs[i]);
1536 XFreeGC (FRAME_DISPLAY (rface->frame), gcs[i]);
1543 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1545 int x, int y, int width, int height, MDrawRegion region)
1547 GC *gcs = rface->info;
1548 GC gc = gcs[reverse ? MFACE_GC_NORMAL : MFACE_GC_INVERSE];
1551 gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
1553 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1554 x, y, width, height);
1559 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1560 MRealizedFace *rface, int reverse,
1561 int x, int y, int width, MDrawRegion region)
1563 enum MFaceHLineType type = rface->hline->type;
1564 GC *gcs = rface->info;
1568 y = (type == MFACE_HLINE_BOTTOM
1569 ? y + gstring->text_descent - rface->hline->width
1570 : type == MFACE_HLINE_UNDER
1572 : type == MFACE_HLINE_STRIKE_THROUGH
1573 ? y - ((gstring->ascent + gstring->descent) / 2)
1574 : y - gstring->text_ascent);
1576 gc = gcs[MFACE_GC_INVERSE];
1577 else if (gcs[MFACE_GC_HLINE])
1578 gc = gcs[MFACE_GC_HLINE];
1580 gc = gcs[MFACE_GC_NORMAL];
1583 gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
1585 for (i = 0; i < rface->hline->width; i++)
1586 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1587 x, y + i, x + width - 1, y + i);
1592 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1593 MGlyph *g, int x, int y, int width, MDrawRegion region)
1595 Display *display = FRAME_DISPLAY (frame);
1596 MRealizedFace *rface = g->rface;
1597 MFaceBoxProp *box = rface->box;
1598 GC *gcs = rface->info;
1599 GC gc_top, gc_left, gc_right, gc_btm;
1603 y0 = y - (gstring->text_ascent
1604 + rface->box->inner_vmargin + rface->box->width);
1605 y1 = y + (gstring->text_descent
1606 + rface->box->inner_vmargin + rface->box->width - 1);
1608 gc_top = gcs[MFACE_GC_BOX_TOP];
1610 gc_top = gcs[MFACE_GC_NORMAL];
1612 gc_top = set_region (FRAME_DISPLAY (frame), rface, gc_top, region);
1613 gc_btm = gcs[MFACE_GC_BOX_BOTTOM];
1617 if (g->type == GLYPH_BOX)
1621 if (g->left_padding)
1622 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1624 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1626 /* Draw the top side. */
1627 for (i = 0; i < box->width; i++)
1628 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1630 /* Draw the bottom side. */
1632 gc_btm = set_region (display, rface, gc_btm, region);
1633 for (i = 0; i < box->width; i++)
1634 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1636 if (g->left_padding > 0)
1638 /* Draw the left side. */
1639 gc_left = gcs[MFACE_GC_BOX_LEFT];
1643 gc_left = set_region (display, rface, gc_left, region);
1644 for (i = 0; i < rface->box->width; i++)
1645 XDrawLine (display, (Window) win, gc_left,
1646 x0 + i, y0 + i, x0 + i, y1 - i);
1650 /* Draw the right side. */
1651 gc_right = gcs[MFACE_GC_BOX_RIGHT];
1655 gc_right = set_region (display, rface, gc_right, region);
1656 for (i = 0; i < rface->box->width; i++)
1657 XDrawLine (display, (Window) win, gc_right,
1658 x1 - i, y0 + i, x1 - i, y1 - i);
1663 /* Draw the top side. */
1664 for (i = 0; i < box->width; i++)
1665 XDrawLine (display, (Window) win, gc_top,
1666 x, y0 + i, x + width - 1, y0 + i);
1668 /* Draw the bottom side. */
1670 gc_btm = set_region (display, rface, gc_btm, region);
1671 for (i = 0; i < box->width; i++)
1672 XDrawLine (display, (Window) win, gc_btm,
1673 x, y1 - i, x + width - 1, y1 - i);
1679 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1680 int reverse, int x, int y,
1681 int width, int height, int row_bytes, unsigned char *bmp,
1684 Display *display = FRAME_DISPLAY (frame);
1686 GC *gcs = rface->info;
1687 GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
1690 gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
1692 for (i = 0; i < height; i++, bmp += row_bytes)
1693 for (j = 0; j < width; j++)
1694 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1695 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1700 mwin__region_from_rect (MDrawMetric *rect)
1702 MDrawRegion region1 = XCreateRegion ();
1703 MDrawRegion region2 = XCreateRegion ();
1708 xrect.width = rect->width;
1709 xrect.height = rect->height;
1710 XUnionRectWithRegion (&xrect, region1, region2);
1711 XDestroyRegion (region1);
1716 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1718 MDrawRegion region1 = XCreateRegion ();
1723 xrect.width = rect->width;
1724 xrect.height = rect->height;
1726 XUnionRegion (region, region, region1);
1727 XUnionRectWithRegion (&xrect, region1, region);
1728 XDestroyRegion (region1);
1732 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1734 MDrawRegion region = XCreateRegion ();
1736 XUnionRegion (region1, region1, region);
1737 XIntersectRegion (region, region2, region1);
1738 XDestroyRegion (region);
1742 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1744 MDrawRegion region1 = XCreateRegion ();
1749 xrect.width = rect->width;
1750 xrect.height = rect->height;
1751 XUnionRectWithRegion (&xrect, region1, region);
1752 XDestroyRegion (region1);
1756 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1760 XClipBox (region, &xrect);
1763 rect->width = xrect.width;
1764 rect->height = xrect.height;
1768 mwin__free_region (MDrawRegion region)
1770 XDestroyRegion (region);
1774 mwin__dump_region (MDrawRegion region)
1777 XClipBox (region, &rect);
1778 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1782 mwin__verify_region (MFrame *frame, MDrawRegion region)
1784 set_region (FRAME_DISPLAY (frame), frame->rface,
1785 ((GC *) frame->rface->info)[MFACE_GC_NORMAL], region);
1789 mwin__create_window (MFrame *frame, MDrawWindow parent)
1791 MWDevice *device = frame->device;
1792 Display *display = FRAME_DISPLAY (frame);
1793 int screen = FRAME_SCREEN (frame);
1795 XWMHints wm_hints = { InputHint, False };
1796 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1797 XSetWindowAttributes attrs;
1799 MSymbol background = mface_get_prop (frame->face, Mbackground);
1801 attrs.background_pixel = get_color (display, device->cmap,
1802 background, background,
1803 WhitePixel (display, screen));
1804 attrs.backing_store = Always;
1805 attrs.override_redirect = True;
1806 attrs.save_under = True;
1807 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1809 parent = (MDrawWindow) RootWindow (display, screen);
1810 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1811 CopyFromParent, InputOutput, CopyFromParent,
1813 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1814 NULL, &wm_hints, &class_hints);
1815 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1816 return (MDrawWindow) win;
1820 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1822 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1827 mwin__event_window (void *event)
1829 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1833 mwin__print_event (void *arg, char *win_name)
1836 XEvent *event = (XEvent *) arg;
1838 switch (event->xany.type)
1840 case 2: event_name = "KeyPress"; break;
1841 case 3: event_name = "KeyRelease"; break;
1842 case 4: event_name = "ButtonPress"; break;
1843 case 5: event_name = "ButtonRelease"; break;
1844 case 6: event_name = "MotionNotify"; break;
1845 case 7: event_name = "EnterNotify"; break;
1846 case 8: event_name = "LeaveNotify"; break;
1847 case 9: event_name = "FocusIn"; break;
1848 case 10: event_name = "FocusOut"; break;
1849 case 11: event_name = "KeymapNotify"; break;
1850 case 12: event_name = "Expose"; break;
1851 case 13: event_name = "GraphicsExpose"; break;
1852 case 14: event_name = "NoExpose"; break;
1853 case 15: event_name = "VisibilityNotify"; break;
1854 case 16: event_name = "CreateNotify"; break;
1855 case 17: event_name = "DestroyNotify"; break;
1856 case 18: event_name = "UnmapNotify"; break;
1857 case 19: event_name = "MapNotify"; break;
1858 case 20: event_name = "MapRequest"; break;
1859 case 21: event_name = "ReparentNotify"; break;
1860 case 22: event_name = "ConfigureNotify"; break;
1861 case 23: event_name = "ConfigureRequest"; break;
1862 case 24: event_name = "GravityNotify"; break;
1863 case 25: event_name = "ResizeRequest"; break;
1864 case 26: event_name = "CirculateNotify"; break;
1865 case 27: event_name = "CirculateRequest"; break;
1866 case 28: event_name = "PropertyNotify"; break;
1867 case 29: event_name = "SelectionClear"; break;
1868 case 30: event_name = "SelectionRequest"; break;
1869 case 31: event_name = "SelectionNotify"; break;
1870 case 32: event_name = "ColormapNotify"; break;
1871 case 33: event_name = "ClientMessage"; break;
1872 case 34: event_name = "MappingNotify"; break;
1873 default: event_name = "unknown";
1876 fprintf (stderr, "%s: %s\n", win_name, event_name);
1881 mwin__map_window (MFrame *frame, MDrawWindow win)
1883 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1887 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1889 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1893 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1894 MDrawMetric *geometry)
1896 Display *display = FRAME_DISPLAY (frame);
1897 XWindowAttributes attr;
1898 Window parent = (Window) parent_win, root;
1900 XGetWindowAttributes (display, (Window) win, &attr);
1901 geometry->x = attr.x + attr.border_width;
1902 geometry->y = attr.y + attr.border_width;
1903 geometry->width = attr.width;
1904 geometry->height = attr.height;
1907 parent = RootWindow (display, FRAME_SCREEN (frame));
1910 Window this_parent, *children;
1913 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1916 if (this_parent == parent || this_parent == root)
1918 win = (MDrawWindow) this_parent;
1919 XGetWindowAttributes (display, (Window) win, &attr);
1920 geometry->x += attr.x + attr.border_width;
1921 geometry->y += attr.y + attr.border_width;
1926 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1927 MDrawMetric *current, MDrawMetric *new)
1929 Display *display = FRAME_DISPLAY (frame);
1930 unsigned int mask = 0;
1931 XWindowChanges values;
1933 if (current->width != new->width)
1936 if (new->width <= 0)
1938 values.width = current->width = new->width;
1940 if (current->height != new->height)
1943 if (new->height <= 0)
1945 values.height = current->height = new->height;
1947 if (current->x != new->x)
1950 values.x = current->x = new->x;
1952 if (current->y != new->y)
1955 current->y = new->y;
1956 values.y = current->y = new->y;
1959 XConfigureWindow (display, (Window) win, mask, &values);
1963 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1965 XEvent *event = (XEvent *) arg;
1966 MDisplayInfo *disp_info = frame->device->display_info;
1973 if (event->xany.type != KeyPress
1974 /* && event->xany.type != KeyRelease */
1977 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
1984 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
1985 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1986 if (((XKeyEvent *) event)->state & ControlMask)
1989 if (((XKeyEvent *) event)->state & ShiftMask)
1990 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1992 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
1994 key = minput__char_to_key (c);
1996 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
2000 char *str = XKeysymToString (keysym);
2004 key = msymbol (str);
2005 if (((XKeyEvent *) event)->state & ShiftMask)
2006 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2007 if (((XKeyEvent *) event)->state & ControlMask)
2008 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2010 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
2011 *modifiers |= MINPUT_KEY_META_MODIFIER;
2012 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
2013 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
2014 if (((XKeyEvent *) event)->state & disp_info->super_mask)
2015 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
2016 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
2017 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
2024 mwin__get_selection_text (MFrame *frame)
2031 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
2033 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
2035 Display *display = FRAME_DISPLAY (frame);
2036 GC *gcs = rface->info;
2039 for (i = 0; i <= MFACE_GC_SCRATCH; i++)
2041 XGetGCValues (display, gcs[i], valuemask, &values);
2042 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
2043 values.foreground, values.background);
2044 fprintf (stderr, "\n");
2049 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2054 /*** @addtogroup m17nFrame */
2059 @name Variables: Keys of frame parameter (X specific).
2061 These are the symbols to use as parameter keys for the function
2062 mframe () (which see). They are also keys of a frame property
2063 (except for #Mwidget). */
2066 /* Keywords for mwin__open_device (). */
2067 MSymbol Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap;
2073 /*** @addtogroup m17nInputMethodWin */
2078 @brief Input driver for XIM.
2080 The input driver #minput_xim_driver is for the foreign input
2081 method of name #Mxim. It uses XIM (X Input Methods) as a
2082 background input engine.
2084 As the symbol #Mxim has property #Minput_driver whose value is
2085 a pointer to this driver, the input method of language #Mnil
2086 and name #Mxim uses this driver.
2088 Therefore, for such input methods, the driver dependent arguments
2089 to the functions whose name begin with minput_ must be as follows.
2091 The argument $ARG of the function minput_open_im () must be a
2092 pointer to the structure #MInputXIMArgIM. See the documentation
2093 of #MInputXIMArgIM for more detail.
2095 The argument $ARG of the function minput_create_ic () must be a
2096 pointer to the structure #MInputXIMArgIC. See the documentation
2097 of #MInputXIMArgIC for more detail.
2099 The argument $ARG of the function minput_filter () must be a
2100 pointer to the structure @c XEvent. The argument $KEY is ignored.
2102 The argument $ARG of the function minput_lookup () must be the
2103 same one as that of the function minput_filter (). The argument
2107 @brief XIMÍÑÆþÎϥɥ饤¥Ð
2109 ÆþÎϥɥ饤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°Éô
2110 ÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤Î
2111 ÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2113 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2114 #Minput_driver ¤ò»ý¤Ä¤¿¤á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç
2115 ¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2117 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤˤϡ¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä
2118 °Ê²¼¤Î´Ø¿ô·²¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é
2121 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM ¤Ø¤Î
2122 ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤Î¥É
2123 ¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
2125 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC ¤Ø
2126 ¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤Î
2127 ¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
2129 ´Ø¿ô minput_filter () ¤Î°ú¿ô %ARG ¤Ï¹½Â¤ÂÎ @c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿
2130 ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2132 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2133 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì
2136 MInputDriver minput_xim_driver =
2137 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2138 xim_filter, xim_lookup, NULL };
2143 @brief Symbol of the name "xim".
2145 The variable Mxim is a symbol of name "xim". It is a name of the
2146 input method driver #minput_xim_driver. */