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)
833 return ((code >= min_byte2 && code <= max_byte2)
834 ? code : MCHAR_INVALID_CODE);
835 pcm = f->per_char + (code - min_byte2);
836 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
837 ? code : MCHAR_INVALID_CODE);
841 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
845 return ((byte1 >= min_byte1 && byte1 <= max_byte1
846 && byte2 >= min_byte2 && byte2 <= max_byte2)
847 ? code : MCHAR_INVALID_CODE);
848 pcm = f->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
849 + (byte2 - min_byte2));
850 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
851 ? code : MCHAR_INVALID_CODE);
856 set_region (MFrame *frame, GC gc, MDrawRegion region)
858 unsigned long valuemask = GCForeground;
860 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
861 frame->device->scratch_gc);
862 XSetRegion (FRAME_DISPLAY (frame), frame->device->scratch_gc, region);
863 return frame->device->scratch_gc;
866 /* The X font driver function RENDER. */
869 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
870 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
872 MRealizedFace *rface = from->rface;
875 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
882 /* It is assured that the all glyphs in the current range use the
883 same realized face. */
884 display = FRAME_DISPLAY (rface->frame);
887 gc = set_region (rface->frame, gc, region);
888 if (! rface->rfont || from->code == MCHAR_INVALID_CODE)
892 for (; from < to; from++)
894 XDrawRectangle (display, (Window) win, gc,
895 x0, y - gstring->ascent + 1, from->width - 1,
896 gstring->ascent + gstring->descent - 2);
902 XSetFont (display, gc, ((MXFontInfo *) (rface->rfont->info))->f->fid);
903 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
904 for (i = 0, g = from; g < to; i++, g++)
906 code[i].byte1 = g->code >> 8;
907 code[i].byte2 = g->code & 0xFF;
913 if (g->type == GLYPH_PAD)
915 else if (g->type == GLYPH_SPACE)
916 for (; g < to && g->type == GLYPH_SPACE; g++)
918 else if (! g->rface->rfont)
920 if ((g->c >= 0x200B && g->c <= 0x200F)
921 || (g->c >= 0x202A && g->c <= 0x202E))
925 /* As a font is not found for this character, draw an
927 int box_width = g->width;
928 int box_height = gstring->ascent + gstring->descent;
934 XDrawRectangle (display, (Window) win, gc,
935 x, y - gstring->ascent, box_width, box_height);
939 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
941 XDrawString16 (display, (Window) win, gc,
942 x + g->xoff, y + g->yoff, code + (g - from), 1);
949 int code_idx = g - from;
952 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
955 XDrawString16 (display, (Window) win, gc, orig_x, y,
963 /* XIM (X Input Method) handler */
965 typedef struct MInputXIMMethodInfo
971 } MInputXIMMethodInfo;
973 typedef struct MInputXIMContextInfo
977 MConverter *converter;
978 } MInputXIMContextInfo;
981 xim_open_im (MInputMethod *im)
983 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
984 MLocale *saved, *this;
985 char *save_modifier_list;
987 MInputXIMMethodInfo *im_info;
989 saved = mlocale_set (LC_CTYPE, NULL);
990 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
992 /* The specified locale is not supported. */
993 MERROR (MERROR_LOCALE, -1);
994 if (mlocale_get_prop (this, Mcoding) == Mnil)
996 /* Unable to decode the output of XIM. */
997 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
998 MERROR (MERROR_LOCALE, -1);
1001 if (arg->modifier_list)
1002 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
1004 save_modifier_list = XSetLocaleModifiers ("");
1005 if (! save_modifier_list)
1007 /* The specified locale is not supported by X. */
1008 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1009 MERROR (MERROR_LOCALE, -1);
1012 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
1015 /* No input method is available in the current locale. */
1016 XSetLocaleModifiers (save_modifier_list);
1017 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1018 MERROR (MERROR_WIN, -1);
1021 MSTRUCT_MALLOC (im_info, MERROR_WIN);
1022 im_info->display = arg->display;
1024 im_info->language = mlocale_get_prop (this, Mlanguage);
1025 im_info->coding = mlocale_get_prop (this, Mcoding);
1028 XSetLocaleModifiers (save_modifier_list);
1029 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1035 xim_close_im (MInputMethod *im)
1037 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
1039 XCloseIM (im_info->xim);
1044 xim_create_ic (MInputContext *ic)
1046 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
1047 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1048 MInputXIMContextInfo *ic_info;
1051 if (! arg->input_style)
1053 /* By default, use Root style. */
1054 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
1055 arg->preedit_attrs = NULL;
1056 arg->status_attrs = NULL;
1059 if (! arg->preedit_attrs && ! arg->status_attrs)
1060 xic = XCreateIC (im_info->xim,
1061 XNInputStyle, arg->input_style,
1062 XNClientWindow, arg->client_win,
1063 XNFocusWindow, arg->focus_win,
1065 else if (arg->preedit_attrs && ! arg->status_attrs)
1066 xic = XCreateIC (im_info->xim,
1067 XNInputStyle, arg->input_style,
1068 XNClientWindow, arg->client_win,
1069 XNFocusWindow, arg->focus_win,
1070 XNPreeditAttributes, arg->preedit_attrs,
1072 else if (! arg->preedit_attrs && arg->status_attrs)
1073 xic = XCreateIC (im_info->xim,
1074 XNInputStyle, arg->input_style,
1075 XNClientWindow, arg->client_win,
1076 XNFocusWindow, arg->focus_win,
1077 XNStatusAttributes, arg->status_attrs,
1080 xic = XCreateIC (im_info->xim,
1081 XNInputStyle, arg->input_style,
1082 XNClientWindow, arg->client_win,
1083 XNFocusWindow, arg->focus_win,
1084 XNPreeditAttributes, arg->preedit_attrs,
1085 XNStatusAttributes, arg->status_attrs,
1088 MERROR (MERROR_WIN, -1);
1090 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
1092 ic_info->win = arg->focus_win;
1093 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
1099 xim_destroy_ic (MInputContext *ic)
1101 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1103 XDestroyIC (ic_info->xic);
1104 mconv_free_converter (ic_info->converter);
1110 xim_filter (MInputContext *ic, MSymbol key, void *event)
1112 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1114 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
1119 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1121 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1122 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1123 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
1129 buf = (char *) alloca (512);
1130 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
1131 if (status == XBufferOverflow)
1133 buf = (char *) alloca (len);
1134 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
1137 mtext_reset (ic->produced);
1141 mconv_reset_converter (ic_info->converter);
1142 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
1143 mconv_decode (ic_info->converter, ic->produced);
1144 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1145 Mlanguage, (void *) im_info->language);
1146 mtext_cpy (mt, ic->produced);
1147 mtext_reset (ic->produced);
1153 #ifdef X_SET_ERROR_HANDLER
1155 x_error_handler (Display *display, XErrorEvent *error)
1162 x_io_error_handler (Display *display)
1174 Mdisplay = msymbol ("display");
1175 Mscreen = msymbol ("screen");
1176 Mdrawable = msymbol ("drawable");
1177 Mdepth = msymbol ("depth");
1178 Mwidget = msymbol ("widget");
1179 M_iso8859_1 = msymbol ("iso8859-1");
1180 M_iso10646_1 = msymbol ("iso10646-1");
1182 display_info_list = mplist ();
1183 device_list = mplist ();
1185 mfont__driver_list[MFONT_TYPE_WIN] = &xfont_driver;
1187 Mxim = msymbol ("xim");
1188 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
1196 M17N_OBJECT_UNREF (display_info_list);
1197 M17N_OBJECT_UNREF (device_list);
1201 mwin__parse_font_name (char *name, MFont *font)
1203 char *field[XLFD_FIELD_MAX];
1204 unsigned short size, resy;
1205 MSymbol attrs[MFONT_PROPERTY_MAX];
1206 char *copy = (char *) alloca (512);
1208 char *p, *last = NULL;
1210 len = strlen (name) + 1;
1211 for (i = 0, p = name; *p; p++)
1215 else if (p > name && *p == '*' && p[-1] == '-')
1219 memcpy (copy, name, len);
1222 memcpy (copy, name, last - name);
1224 strcat (copy, "-*");
1225 strcat (copy, last);
1228 if (split_font_name (copy, field, &size, &resy) < 0)
1230 attrs[MFONT_FOUNDRY]
1231 = *(field[XLFD_FOUNDRY]) != '*' ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
1233 = *(field[XLFD_FAMILY]) != '*' ? msymbol (field[XLFD_FAMILY]) : Mnil;
1235 = *(field[XLFD_WEIGHT]) != '*' ? msymbol (field[XLFD_WEIGHT]) : Mnil;
1237 = *(field[XLFD_SLANT]) != '*' ? msymbol (field[XLFD_SLANT]) : Mnil;
1238 attrs[MFONT_STRETCH]
1239 = *(field[XLFD_SWIDTH]) != '*' ? msymbol (field[XLFD_SWIDTH]) : Mnil;
1240 attrs[MFONT_ADSTYLE]
1241 = *(field[XLFD_ADSTYLE]) != '*' ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
1242 attrs[MFONT_REGISTRY]
1243 = *(field[XLFD_REGISTRY]) != '*' ? msymbol (field[XLFD_REGISTRY]) : Mnil;
1244 mfont__set_spec (font, attrs, size, resy);
1250 mwin__build_font_name (MFont *font)
1254 if (build_font_name (font, name, 1024) < 0)
1256 return strdup (name);
1259 /** Return an MWDevice object corresponding to a display specified in
1262 It searches device_list for a device matching the display. If
1263 found, return the found object. Otherwise, return a newly created
1267 mwin__open_device (MFrame *frame, MPlist *param)
1269 Display *display = NULL;
1270 Screen *screen = NULL;
1272 Drawable drawable = 0;
1273 Widget widget = NULL;
1275 int auto_display = 0;
1276 MDisplayInfo *disp_info = NULL;
1277 MWDevice *device = NULL;
1279 XWindowAttributes attr;
1285 for (plist = param; (key = mplist_key (plist)) != Mnil;
1286 plist = mplist_next (plist))
1288 if (key == Mdisplay)
1289 display = (Display *) mplist_value (plist);
1290 else if (key == Mscreen)
1291 screen = mplist_value (plist);
1292 else if (key == Mdrawable)
1293 drawable = (Drawable) mplist_value (plist);
1294 else if (key == Mdepth)
1295 depth = (unsigned) mplist_value (plist);
1296 else if (key == Mwidget)
1297 widget = (Widget) mplist_value (plist);
1298 else if (key == Mcolormap)
1299 cmap = (Colormap) mplist_value (plist);
1304 display = XtDisplay (widget);
1305 screen_num = XScreenNumberOfScreen (XtScreen (widget));
1306 depth = DefaultDepth (display, screen_num);
1312 unsigned width, height, border_width;
1315 MERROR (MERROR_WIN, NULL);
1316 XGetGeometry (display, drawable, &root_window,
1317 &x, &y, &width, &height, &border_width, &depth);
1318 XGetWindowAttributes (display, root_window, &attr);
1319 screen_num = XScreenNumberOfScreen (attr.screen);
1324 display = DisplayOfScreen (screen);
1329 display = XOpenDisplay (NULL);
1331 MERROR (MERROR_WIN, NULL);
1334 screen = DefaultScreenOfDisplay (display);
1336 screen_num = XScreenNumberOfScreen (screen);
1338 depth = DefaultDepth (display, screen_num);
1342 cmap = DefaultColormap (display, screen_num);
1344 for (plist = display_info_list; mplist_key (plist) != Mnil;
1345 plist = mplist_next (plist))
1347 disp_info = (MDisplayInfo *) mplist_value (plist);
1348 if (disp_info->display == display)
1352 if (mplist_key (plist) != Mnil)
1353 M17N_OBJECT_REF (disp_info);
1356 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
1357 disp_info->display = display;
1358 disp_info->auto_display = auto_display;
1359 disp_info->font_registry_list = mplist ();
1360 disp_info->iso8859_1_family_list = mplist ();
1361 disp_info->iso10646_1_family_list = mplist ();
1362 disp_info->realized_font_list = mplist ();
1363 find_modifier_bits (disp_info);
1364 mplist_add (display_info_list, Mt, disp_info);
1367 for (plist = device_list; mplist_key (plist) != Mnil;
1368 plist = mplist_next (plist))
1370 device = (MWDevice *) mplist_value (plist);
1371 if (device->display_info == disp_info
1372 && device->depth == depth
1373 && device->cmap == cmap)
1377 if (mplist_key (plist) != Mnil)
1378 M17N_OBJECT_REF (device);
1381 unsigned long valuemask = GCForeground;
1384 M17N_OBJECT (device, free_device, MERROR_WIN);
1385 device->display_info = disp_info;
1386 device->screen_num = screen_num;
1387 /* A drawable on which to create GCs. */
1388 device->drawable = XCreatePixmap (display,
1389 RootWindow (display, screen_num),
1391 device->depth = depth;
1392 device->cmap = cmap;
1393 device->realized_face_list = mplist ();
1394 device->realized_fontset_list = mplist ();
1395 device->gc_list = mplist ();
1396 values.foreground = BlackPixel (display, screen_num);
1397 device->scratch_gc = XCreateGC (display, device->drawable,
1398 valuemask, &values);
1401 frame->realized_font_list = disp_info->realized_font_list;
1402 frame->realized_face_list = device->realized_face_list;
1403 frame->realized_fontset_list = device->realized_fontset_list;
1407 XtResource resources[] = {
1408 { XtNfont, XtCFont, XtRString, sizeof (String),
1409 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
1410 { XtNforeground, XtCForeground, XtRString, sizeof (String),
1411 XtOffset (AppDataPtr, foreground), XtRString, "black" },
1412 { XtNbackground, XtCBackground, XtRString, sizeof (String),
1413 XtOffset (AppDataPtr, background), XtRString, "white" },
1414 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
1415 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
1418 XtGetApplicationResources (widget, &app_data,
1419 resources, XtNumber (resources), NULL, 0);
1420 frame->foreground = msymbol (app_data.foreground);
1421 frame->background = msymbol (app_data.background);
1422 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
1426 app_data.font = DEFAULT_FONT;
1427 frame->foreground = msymbol ("black");
1428 frame->background = msymbol ("white");
1429 frame->videomode = Mnormal;
1432 frame->font = mfont ();
1435 char **names = XListFonts (display, app_data.font, 1, &nfonts);
1439 if (mwin__parse_font_name (names[0], frame->font) < 0)
1441 /* The font name does not conform to XLFD. Try to open the
1442 font and get XA_FONT property. */
1443 XFontStruct *xfont = XLoadQueryFont (display, names[0]);
1448 unsigned long value;
1451 if (XGetFontProperty (xfont, XA_FONT, &value)
1452 && (name = ((char *)
1453 XGetAtomName (display, (Atom) value))))
1455 if (mwin__parse_font_name (name, frame->font) >= 0)
1458 XFreeFont (display, xfont);
1461 XFreeFontNames (names);
1464 mwin__parse_font_name (FALLBACK_FONT, frame->font);
1467 #ifdef X_SET_ERROR_HANDLER
1468 XSetErrorHandler (x_error_handler);
1469 XSetIOErrorHandler (x_io_error_handler);
1476 mwin__close_device (MFrame *frame)
1478 M17N_OBJECT_UNREF (frame->device);
1482 mwin__device_get_prop (MWDevice *device, MSymbol key)
1484 if (key == Mdisplay)
1485 return (void *) device->display_info->display;
1487 return (void *) ScreenOfDisplay(device->display_info->display,
1488 device->screen_num);
1489 if (key == Mcolormap)
1490 return (void *) device->cmap;
1492 return (void *) device->depth;
1497 mwin__realize_face (MRealizedFace *rface)
1500 MSymbol foreground, background, videomode;
1501 MFaceHLineProp *hline;
1506 if (rface != rface->ascii_rface)
1508 rface->info = rface->ascii_rface->info;
1512 frame = rface->frame;
1513 MSTRUCT_CALLOC (info, MERROR_WIN);
1515 foreground = rface->face.property[MFACE_FOREGROUND];
1516 background = rface->face.property[MFACE_BACKGROUND];
1517 videomode = rface->face.property[MFACE_VIDEOMODE];
1519 videomode = frame->videomode;
1520 if (videomode != Mreverse)
1522 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
1523 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
1527 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
1528 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
1531 hline = rface->hline;
1535 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
1537 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
1544 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
1546 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
1548 if (box->color_left && box->color_left != box->color_top)
1549 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
1551 info->gc[GC_BOX_LEFT] = info->gc[GC_NORMAL];
1553 if (box->color_bottom && box->color_bottom != box->color_top)
1554 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
1556 info->gc[GC_BOX_BOTTOM] = info->gc[GC_NORMAL];
1558 if (box->color_right && box->color_right != box->color_top)
1559 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
1561 info->gc[GC_BOX_RIGHT] = info->gc[GC_NORMAL];
1566 func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
1568 (func) (&(rface->face), rface->info, rface->face.property[MFACE_HOOK_ARG]);
1573 mwin__free_realized_face (MRealizedFace *rface)
1575 if (rface == rface->ascii_rface)
1581 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1583 int x, int y, int width, int height, MDrawRegion region)
1585 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
1588 gc = set_region (frame, gc, region);
1590 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
1591 x, y, width, height);
1596 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1597 MRealizedFace *rface, int reverse,
1598 int x, int y, int width, MDrawRegion region)
1600 enum MFaceHLineType type = rface->hline->type;
1601 GCInfo *info = rface->info;
1602 GC gc = gc = info->gc[GC_HLINE];
1605 y = (type == MFACE_HLINE_BOTTOM
1606 ? y + gstring->text_descent - rface->hline->width
1607 : type == MFACE_HLINE_UNDER
1609 : type == MFACE_HLINE_STRIKE_THROUGH
1610 ? y - ((gstring->ascent + gstring->descent) / 2)
1611 : y - gstring->text_ascent);
1613 gc = set_region (frame, gc, region);
1615 for (i = 0; i < rface->hline->width; i++)
1616 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
1617 x, y + i, x + width - 1, y + i);
1622 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
1623 MGlyph *g, int x, int y, int width, MDrawRegion region)
1625 Display *display = FRAME_DISPLAY (frame);
1626 MRealizedFace *rface = g->rface;
1627 MFaceBoxProp *box = rface->box;
1628 GCInfo *info = rface->info;
1629 GC gc_top, gc_left, gc_right, gc_btm;
1633 y0 = y - (gstring->text_ascent
1634 + rface->box->inner_vmargin + rface->box->width);
1635 y1 = y + (gstring->text_descent
1636 + rface->box->inner_vmargin + rface->box->width - 1);
1638 gc_top = info->gc[GC_BOX_TOP];
1640 gc_top = set_region (frame, gc_top, region);
1641 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
1644 gc_btm = info->gc[GC_BOX_BOTTOM];
1646 if (g->type == GLYPH_BOX)
1650 if (g->left_padding)
1651 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
1653 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
1655 /* Draw the top side. */
1656 for (i = 0; i < box->width; i++)
1657 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
1659 /* Draw the bottom side. */
1660 if (region && gc_btm != gc_top)
1661 gc_btm = set_region (frame, gc_btm, region);
1662 for (i = 0; i < box->width; i++)
1663 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
1665 if (g->left_padding > 0)
1667 /* Draw the left side. */
1668 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
1672 gc_left = info->gc[GC_BOX_LEFT];
1674 gc_left = set_region (frame, gc_left, region);
1676 for (i = 0; i < rface->box->width; i++)
1677 XDrawLine (display, (Window) win, gc_left,
1678 x0 + i, y0 + i, x0 + i, y1 - i);
1682 /* Draw the right side. */
1683 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
1687 gc_right = info->gc[GC_BOX_RIGHT];
1689 gc_right = set_region (frame, gc_right, region);
1691 for (i = 0; i < rface->box->width; i++)
1692 XDrawLine (display, (Window) win, gc_right,
1693 x1 - i, y0 + i, x1 - i, y1 - i);
1698 /* Draw the top side. */
1699 for (i = 0; i < box->width; i++)
1700 XDrawLine (display, (Window) win, gc_top,
1701 x, y0 + i, x + width - 1, y0 + i);
1703 /* Draw the bottom side. */
1704 if (region && gc_btm != gc_top)
1705 gc_btm = set_region (frame, gc_btm, region);
1706 for (i = 0; i < box->width; i++)
1707 XDrawLine (display, (Window) win, gc_btm,
1708 x, y1 - i, x + width - 1, y1 - i);
1715 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1716 int reverse, int x, int y,
1717 int width, int height, int row_bytes, unsigned char *bmp,
1720 Display *display = FRAME_DISPLAY (frame);
1722 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1725 gc = set_region (frame, gc, region);
1727 for (i = 0; i < height; i++, bmp += row_bytes)
1728 for (j = 0; j < width; j++)
1729 if (bmp[j / 8] & (1 << (7 - (j % 8))))
1730 XDrawPoint (display, (Window) win, gc, x + j, y + i);
1735 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
1736 int intensity, MDrawPoint *points, int num,
1739 GCInfo *info = rface->info;
1742 if (! (gc = info->gc[intensity]))
1743 gc = info->gc[intensity] = get_gc_for_anti_alias (frame->device, info,
1746 gc = set_region (frame, gc, region);
1748 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
1749 (XPoint *) points, num, CoordModeOrigin);
1754 mwin__region_from_rect (MDrawMetric *rect)
1756 MDrawRegion region1 = XCreateRegion ();
1757 MDrawRegion region2 = XCreateRegion ();
1762 xrect.width = rect->width;
1763 xrect.height = rect->height;
1764 XUnionRectWithRegion (&xrect, region1, region2);
1765 XDestroyRegion (region1);
1770 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
1772 MDrawRegion region1 = XCreateRegion ();
1777 xrect.width = rect->width;
1778 xrect.height = rect->height;
1780 XUnionRegion (region, region, region1);
1781 XUnionRectWithRegion (&xrect, region1, region);
1782 XDestroyRegion (region1);
1786 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
1788 MDrawRegion region = XCreateRegion ();
1790 XUnionRegion (region1, region1, region);
1791 XIntersectRegion (region, region2, region1);
1792 XDestroyRegion (region);
1796 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
1798 MDrawRegion region1 = XCreateRegion ();
1803 xrect.width = rect->width;
1804 xrect.height = rect->height;
1805 XUnionRectWithRegion (&xrect, region1, region);
1806 XDestroyRegion (region1);
1810 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
1814 XClipBox (region, &xrect);
1817 rect->width = xrect.width;
1818 rect->height = xrect.height;
1822 mwin__free_region (MDrawRegion region)
1824 XDestroyRegion (region);
1828 mwin__dump_region (MDrawRegion region)
1831 XClipBox (region, &rect);
1832 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
1836 mwin__verify_region (MFrame *frame, MDrawRegion region)
1838 set_region (frame, ((GCInfo *) frame->rface->info)->gc[GC_NORMAL], region);
1842 mwin__create_window (MFrame *frame, MDrawWindow parent)
1844 Display *display = FRAME_DISPLAY (frame);
1846 XWMHints wm_hints = { InputHint, False };
1847 XClassHint class_hints = { "M17N-IM", "m17n-im" };
1848 XSetWindowAttributes set_attrs;
1851 GCInfo *info = frame->rface->info;
1854 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
1855 mask = GCForeground;
1856 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
1857 set_attrs.background_pixel = values.foreground;
1858 set_attrs.backing_store = Always;
1859 set_attrs.override_redirect = True;
1860 set_attrs.save_under = True;
1861 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
1862 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
1863 CopyFromParent, InputOutput, CopyFromParent,
1865 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
1866 NULL, &wm_hints, &class_hints);
1867 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
1868 return (MDrawWindow) win;
1872 mwin__destroy_window (MFrame *frame, MDrawWindow win)
1874 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
1879 mwin__event_window (void *event)
1881 return ((MDrawWindow) ((XEvent *) event)->xany.window);
1885 mwin__print_event (void *arg, char *win_name)
1888 XEvent *event = (XEvent *) arg;
1890 switch (event->xany.type)
1892 case 2: event_name = "KeyPress"; break;
1893 case 3: event_name = "KeyRelease"; break;
1894 case 4: event_name = "ButtonPress"; break;
1895 case 5: event_name = "ButtonRelease"; break;
1896 case 6: event_name = "MotionNotify"; break;
1897 case 7: event_name = "EnterNotify"; break;
1898 case 8: event_name = "LeaveNotify"; break;
1899 case 9: event_name = "FocusIn"; break;
1900 case 10: event_name = "FocusOut"; break;
1901 case 11: event_name = "KeymapNotify"; break;
1902 case 12: event_name = "Expose"; break;
1903 case 13: event_name = "GraphicsExpose"; break;
1904 case 14: event_name = "NoExpose"; break;
1905 case 15: event_name = "VisibilityNotify"; break;
1906 case 16: event_name = "CreateNotify"; break;
1907 case 17: event_name = "DestroyNotify"; break;
1908 case 18: event_name = "UnmapNotify"; break;
1909 case 19: event_name = "MapNotify"; break;
1910 case 20: event_name = "MapRequest"; break;
1911 case 21: event_name = "ReparentNotify"; break;
1912 case 22: event_name = "ConfigureNotify"; break;
1913 case 23: event_name = "ConfigureRequest"; break;
1914 case 24: event_name = "GravityNotify"; break;
1915 case 25: event_name = "ResizeRequest"; break;
1916 case 26: event_name = "CirculateNotify"; break;
1917 case 27: event_name = "CirculateRequest"; break;
1918 case 28: event_name = "PropertyNotify"; break;
1919 case 29: event_name = "SelectionClear"; break;
1920 case 30: event_name = "SelectionRequest"; break;
1921 case 31: event_name = "SelectionNotify"; break;
1922 case 32: event_name = "ColormapNotify"; break;
1923 case 33: event_name = "ClientMessage"; break;
1924 case 34: event_name = "MappingNotify"; break;
1925 default: event_name = "unknown";
1928 fprintf (stderr, "%s: %s\n", win_name, event_name);
1933 mwin__map_window (MFrame *frame, MDrawWindow win)
1935 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
1939 mwin__unmap_window (MFrame *frame, MDrawWindow win)
1941 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
1945 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
1946 MDrawMetric *geometry)
1948 Display *display = FRAME_DISPLAY (frame);
1949 XWindowAttributes attr;
1950 Window parent = (Window) parent_win, root;
1952 XGetWindowAttributes (display, (Window) win, &attr);
1953 geometry->x = attr.x + attr.border_width;
1954 geometry->y = attr.y + attr.border_width;
1955 geometry->width = attr.width;
1956 geometry->height = attr.height;
1959 parent = RootWindow (display, FRAME_SCREEN (frame));
1962 Window this_parent, *children;
1965 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
1968 if (this_parent == parent || this_parent == root)
1970 win = (MDrawWindow) this_parent;
1971 XGetWindowAttributes (display, (Window) win, &attr);
1972 geometry->x += attr.x + attr.border_width;
1973 geometry->y += attr.y + attr.border_width;
1978 mwin__adjust_window (MFrame *frame, MDrawWindow win,
1979 MDrawMetric *current, MDrawMetric *new)
1981 Display *display = FRAME_DISPLAY (frame);
1982 unsigned int mask = 0;
1983 XWindowChanges values;
1985 if (current->width != new->width)
1988 if (new->width <= 0)
1990 values.width = current->width = new->width;
1992 if (current->height != new->height)
1995 if (new->height <= 0)
1997 values.height = current->height = new->height;
1999 if (current->x != new->x)
2002 values.x = current->x = new->x;
2004 if (current->y != new->y)
2007 current->y = new->y;
2008 values.y = current->y = new->y;
2011 XConfigureWindow (display, (Window) win, mask, &values);
2012 XClearWindow (display, (Window) win);
2016 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
2018 XEvent *event = (XEvent *) arg;
2019 MDisplayInfo *disp_info = frame->device->display_info;
2026 if (event->xany.type != KeyPress
2027 /* && event->xany.type != KeyRelease */
2030 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
2037 if (c < XK_space || c > XK_asciitilde)
2039 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
2040 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2041 if (((XKeyEvent *) event)->state & ControlMask)
2043 if (c >= 'a' && c <= 'z')
2045 if (c >= ' ' && c < 127)
2046 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2048 key = minput__char_to_key (c);
2050 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
2054 char *str = XKeysymToString (keysym);
2058 key = msymbol (str);
2059 if (((XKeyEvent *) event)->state & ShiftMask)
2060 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
2061 if (((XKeyEvent *) event)->state & ControlMask)
2062 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
2064 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
2065 *modifiers |= MINPUT_KEY_META_MODIFIER;
2066 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
2067 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
2068 if (((XKeyEvent *) event)->state & disp_info->super_mask)
2069 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
2070 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
2071 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
2078 mwin__get_selection_text (MFrame *frame)
2085 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
2087 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
2089 Display *display = FRAME_DISPLAY (frame);
2090 GCInfo *info = rface->info;
2093 for (i = 0; i <= GC_INVERSE; i++)
2095 XGetGCValues (display, info->gc[i], valuemask, &values);
2096 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
2097 values.foreground, values.background);
2098 fprintf (stderr, "\n");
2103 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2108 /*** @addtogroup m17nFrame */
2113 @name Variables: Keys of frame parameter (X specific).
2115 These are the symbols to use as parameter keys for the function
2116 mframe () (which see). They are also keys of a frame property
2117 (except for #Mwidget). */
2120 /* Keywords for mwin__open_device (). */
2121 MSymbol Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap;
2127 /*** @addtogroup m17nInputMethodWin */
2132 @brief Input driver for XIM.
2134 The input driver #minput_xim_driver is for the foreign input
2135 method of name #Mxim. It uses XIM (X Input Methods) as a
2136 background input engine.
2138 As the symbol #Mxim has property #Minput_driver whose value is
2139 a pointer to this driver, the input method of language #Mnil
2140 and name #Mxim uses this driver.
2142 Therefore, for such input methods, the driver dependent arguments
2143 to the functions whose name begin with minput_ must be as follows.
2145 The argument $ARG of the function minput_open_im () must be a
2146 pointer to the structure #MInputXIMArgIM. See the documentation
2147 of #MInputXIMArgIM for more detail.
2149 The argument $ARG of the function minput_create_ic () must be a
2150 pointer to the structure #MInputXIMArgIC. See the documentation
2151 of #MInputXIMArgIC for more detail.
2153 The argument $ARG of the function minput_filter () must be a
2154 pointer to the structure @c XEvent. The argument $KEY is ignored.
2156 The argument $ARG of the function minput_lookup () must be the
2157 same one as that of the function minput_filter (). The argument
2161 @brief XIMÍÑÆþÎϥɥ饤¥Ð
2163 ÆþÎϥɥ饤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°Éô
2164 ÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤Î
2165 ÆþÎÏ¥¨¥ó¥¸¥ó¤È¤·¤Æ»ÈÍѤ¹¤ë¡£
2167 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2168 #Minput_driver ¤ò»ý¤Ä¤¿¤á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç
2169 ¤¢¤ëÆþÎϥ᥽¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2171 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥ÉÍѤˤϡ¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä
2172 °Ê²¼¤Î´Ø¿ô·²¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é
2175 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM ¤Ø¤Î
2176 ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤Î¥É
2177 ¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
2179 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC ¤Ø
2180 ¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤Î
2181 ¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
2183 ´Ø¿ô minput_filter () ¤Î°ú¿ô %ARG ¤Ï¹½Â¤ÂÎ @c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿
2184 ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2186 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2187 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì
2190 MInputDriver minput_xim_driver =
2191 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2192 xim_filter, xim_lookup, NULL };
2197 @brief Symbol of the name "xim".
2199 The variable Mxim is a symbol of name "xim". It is a name of the
2200 input method driver #minput_xim_driver. */