1 /* m17n-X.c -- implementation of the GUI API on X Windows.
2 Copyright (C) 2003, 2004
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
24 /*** @addtogroup m17nInternal
36 #include <X11/keysym.h>
37 #include <X11/Xlocale.h>
38 #include <X11/Xutil.h>
39 #include <X11/Xresource.h>
40 #include <X11/Xatom.h>
41 #include <X11/StringDefs.h>
42 #include <X11/Intrinsic.h>
45 #include <X11/Xft/Xft.h>
46 #endif /* HAVE_XFT2 */
50 #include "m17n-misc.h"
52 #include "internal-gui.h"
61 /* Common header for the m17n object. */
66 /* If nonzero, <display> is opened by this library. Thus it should
67 be closed on freeing this structure. */
70 /** List of available fonts on the display (except for iso8859-1 and
71 iso10646-1 fonts). Keys are font registries, values are
73 MPlist *font_registry_list;
75 MPlist *iso8859_1_family_list;
77 MPlist *iso10646_1_family_list;
79 /* List of information about each font. Keys are font registries,
80 values are (MFontInfo *). */
81 MPlist *realized_font_list;
83 /** Modifier bit masks of the display. */
90 /* Anchor of the chain of MDisplayInfo objects. */
91 static MPlist *display_info_list;
94 /* Color value and the corresponding GC. */
97 unsigned int rgb; /* (red << 16) | (green << 8) | blue */
104 GC_NORMAL = GC_INVERSE + 7,
117 /* The first 8 elements are indexed by an intensity for
118 anti-aliasing. The 2nd to 7th are created on demand. */
121 XftColor xft_color_fore, xft_color_back;
127 /* Common header for the m17n object. */
130 MDisplayInfo *display_info;
146 /** List of pointers to realized faces on the frame. */
147 MPlist *realized_face_list;
149 /** List of pointers to realized fontsets on the frame. */
150 MPlist *realized_fontset_list;
152 /** List of XColors vs GCs on the frame. */
156 static MPlist *device_list;
158 static MSymbol M_iso8859_1, M_iso10646_1;
160 #define FRAME_DEVICE(frame) ((MWDevice *) (frame)->device)
161 #define FRAME_DISPLAY(frame) (FRAME_DEVICE (frame)->display_info->display)
162 #define FRAME_SCREEN(frame) (FRAME_DEVICE (frame)->screen_num)
163 #define FRAME_CMAP(frame) (FRAME_DEVICE (frame)->cmap)
164 #define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \
165 FRAME_SCREEN (frame))
167 #define DEFAULT_FONT "-misc-fixed-medium-r-normal--*-120-*-*-*-*-iso8859-1"
168 #define FALLBACK_FONT "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1"
175 Boolean reverse_video;
176 } AppData, *AppDataPtr;
179 free_display_info (void *object)
181 MDisplayInfo *disp_info = (MDisplayInfo *) object;
184 MPLIST_DO (plist, disp_info->font_registry_list)
186 MFontList *registry_list = MPLIST_VAL (plist);
188 if (registry_list->fonts)
189 free (registry_list->fonts);
190 free (registry_list);
192 M17N_OBJECT_UNREF (disp_info->font_registry_list);
194 MPLIST_DO (plist, disp_info->iso8859_1_family_list)
196 MFontList *family_list = MPLIST_VAL (plist);
198 if (family_list->fonts)
199 free (family_list->fonts);
202 M17N_OBJECT_UNREF (disp_info->iso8859_1_family_list);
204 MPLIST_DO (plist, disp_info->iso10646_1_family_list)
206 MFontList *family_list = MPLIST_VAL (plist);
208 if (family_list->fonts)
209 free (family_list->fonts);
212 M17N_OBJECT_UNREF (disp_info->iso10646_1_family_list);
214 MPLIST_DO (plist, disp_info->realized_font_list)
215 mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist));
216 M17N_OBJECT_UNREF (disp_info->realized_font_list);
218 if (disp_info->auto_display)
219 XCloseDisplay (disp_info->display);
225 free_device (void *object)
227 MWDevice *device = object;
230 for (plist = device->realized_fontset_list;
231 mplist_key (plist) != Mnil; plist = mplist_next (plist))
232 mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist));
233 M17N_OBJECT_UNREF (device->realized_fontset_list);
235 MPLIST_DO (plist, device->realized_face_list)
237 MRealizedFace *rface = MPLIST_VAL (plist);
240 mface__free_realized (rface);
242 M17N_OBJECT_UNREF (device->realized_face_list);
244 MPLIST_DO (plist, device->gc_list)
246 XFreeGC (device->display_info->display,
247 ((RGB_GC *) MPLIST_VAL (plist))->gc);
248 free (MPLIST_VAL (plist));
250 M17N_OBJECT_UNREF (device->gc_list);
251 XFreeGC (device->display_info->display, device->scratch_gc);
254 XftDrawDestroy (device->xft_draw);
257 XFreePixmap (device->display_info->display, device->drawable);
258 M17N_OBJECT_UNREF (device->display_info);
264 find_modifier_bits (MDisplayInfo *disp_info)
266 Display *display = disp_info->display;
267 XModifierKeymap *mods;
268 KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
269 KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
270 KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
271 KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
272 KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
273 KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
274 KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
275 KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
278 mods = XGetModifierMapping (display);
279 /* We skip the first three sets for Shift, Lock, and Control. The
280 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
281 for (i = 3; i < 8; i++)
282 for (j = 0; j < mods->max_keypermod; j++)
284 KeyCode code = mods->modifiermap[i * mods->max_keypermod + j];
288 if (code == meta_l || code == meta_r)
289 disp_info->meta_mask |= (1 << i);
290 else if (code == alt_l || code == alt_r)
291 disp_info->alt_mask |= (1 << i);
292 else if (code == super_l || code == super_r)
293 disp_info->super_mask |= (1 << i);
294 else if (code == hyper_l || code == hyper_r)
295 disp_info->hyper_mask |= (1 << i);
298 /* If meta keys are not in any modifier, use alt keys as meta
300 if (! disp_info->meta_mask)
302 disp_info->meta_mask = disp_info->alt_mask;
303 disp_info->alt_mask = 0;
305 /* If both meta and alt are assigned to the same modifier, give meta
307 if (disp_info->meta_mask & disp_info->alt_mask)
308 disp_info->alt_mask &= ~disp_info->meta_mask;
310 XFreeModifiermap (mods);
314 get_rgb_gc (MWDevice *device, XColor *xcolor)
316 int rgb = (((xcolor->red >> 8) << 16) | ((xcolor->green >> 8) << 8)
317 | (xcolor->blue >> 8));
320 unsigned long valuemask = GCForeground;
323 MPLIST_DO (plist, device->gc_list)
325 rgb_gc = MPLIST_VAL (plist);
327 if (rgb_gc->rgb == rgb)
329 if (rgb_gc->rgb > rgb)
333 if (! XAllocColor (device->display_info->display, device->cmap, xcolor))
336 rgb_gc = malloc (sizeof (RGB_GC));
338 values.foreground = xcolor->pixel;
339 rgb_gc->gc = XCreateGC (device->display_info->display,
340 device->drawable, valuemask, &values);
341 mplist_push (plist, Mt, rgb_gc);
346 get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret)
348 MWDevice *device = FRAME_DEVICE (frame);
356 color = for_foreground ? frame->foreground : frame->background;
358 if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
359 msymbol_name (color), &xcolor))
361 rgb_gc = get_rgb_gc (device, &xcolor);
365 *rgb_ret = rgb_gc->rgb;
370 GCInfo *info = frame->rface->info;
375 rgb = info->rgb_fore, gc = info->gc[GC_NORMAL];
377 rgb = info->rgb_back, gc = info->gc[GC_INVERSE];
385 get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity)
387 int rgb_fore, rgb_back;
392 if (info->gc[intensity])
393 return info->gc[intensity];
395 rgb_fore = info->rgb_fore, rgb_back = info->rgb_back;
396 xcolor.red = ((((rgb_fore & 0xFF0000) >> 16) * intensity
397 + ((rgb_back & 0xFF0000) >> 16) * (7 - intensity)) / 7) << 8;
398 xcolor.green = ((((rgb_fore & 0xFF00) >> 8) * intensity
399 + ((rgb_back & 0xFF00) >> 8) * (7 - intensity)) / 7) << 8;
400 xcolor.blue = (((rgb_fore & 0xFF) * intensity
401 + (rgb_back & 0xFF) * (7 - intensity)) / 7) << 8;
402 rgb_gc = get_rgb_gc (device, &xcolor);
406 gc =get_gc_for_anti_alias (device, info,
407 intensity < 4 ? intensity - 1 : intensity + 1);
408 return (info->gc[intensity] = gc);
412 set_region (MFrame *frame, GC gc, MDrawRegion region)
414 unsigned long valuemask = GCForeground;
416 XCopyGC (FRAME_DISPLAY (frame), gc, valuemask,
417 FRAME_DEVICE (frame)->scratch_gc);
418 XSetRegion (FRAME_DISPLAY (frame), FRAME_DEVICE (frame)->scratch_gc, region);
419 return FRAME_DEVICE (frame)->scratch_gc;
423 /* Functions for the device driver. */
426 mwin__close_device (MFrame *frame)
428 M17N_OBJECT_UNREF (FRAME_DEVICE (frame));
432 mwin__device_get_prop (MFrame *frame, MSymbol key)
434 MWDevice *device = FRAME_DEVICE (frame);
437 return (void *) device->display_info->display;
439 return (void *) ScreenOfDisplay(device->display_info->display,
441 if (key == Mcolormap)
442 return (void *) device->cmap;
444 return (void *) device->depth;
449 mwin__realize_face (MRealizedFace *rface)
452 MSymbol foreground, background, videomode;
453 MFaceHLineProp *hline;
457 if (rface != rface->ascii_rface)
459 rface->info = rface->ascii_rface->info;
463 frame = rface->frame;
464 MSTRUCT_CALLOC (info, MERROR_WIN);
466 foreground = rface->face.property[MFACE_FOREGROUND];
467 background = rface->face.property[MFACE_BACKGROUND];
468 videomode = rface->face.property[MFACE_VIDEOMODE];
470 videomode = frame->videomode;
471 if (videomode != Mreverse)
473 info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
474 info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
478 info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore);
479 info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back);
482 if (foreground == Mnil)
483 foreground = frame->foreground;
484 if (background == Mnil)
485 background = frame->background;
486 if (videomode == Mreverse)
488 MSymbol temp = foreground;
489 foreground = background;
492 if (! XftColorAllocName (FRAME_DISPLAY (frame),
493 FRAME_VISUAL (frame),
495 MSYMBOL_NAME (foreground),
496 &info->xft_color_fore))
498 if (! XftColorAllocName (FRAME_DISPLAY (frame),
499 FRAME_VISUAL (frame),
501 MSYMBOL_NAME (background),
502 &info->xft_color_back))
506 hline = rface->hline;
510 info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
512 info->gc[GC_HLINE] = info->gc[GC_NORMAL];
519 info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL);
521 info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL];
523 if (box->color_left && box->color_left != box->color_top)
524 info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL);
526 info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP];
528 if (box->color_bottom && box->color_bottom != box->color_top)
529 info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL);
531 info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP];
533 if (box->color_right && box->color_right != box->color_bottom)
534 info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL);
536 info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM];
544 mwin__free_realized_face (MRealizedFace *rface)
546 if (rface == rface->ascii_rface)
552 mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
554 int x, int y, int width, int height, MDrawRegion region)
556 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
559 gc = set_region (frame, gc, region);
561 XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
562 x, y, width, height);
566 void mwin__draw_empty_boxes (MDrawWindow win, int x, int y,
567 MGlyphString *gstring, MGlyph *from, MGlyph *to,
568 int reverse, MDrawRegion region)
570 MRealizedFace *rface = from->rface;
571 Display *display = FRAME_DISPLAY (rface->frame);
572 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
578 gc = set_region (rface->frame, gc, region);
579 for (; from < to; from++)
581 XDrawRectangle (display, (Window) win, gc,
582 x, y - gstring->ascent + 1, from->width - 1,
583 gstring->ascent + gstring->descent - 2);
590 mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
591 MRealizedFace *rface, int reverse,
592 int x, int y, int width, MDrawRegion region)
594 enum MFaceHLineType type = rface->hline->type;
595 GCInfo *info = rface->info;
596 GC gc = gc = info->gc[GC_HLINE];
599 y = (type == MFACE_HLINE_BOTTOM
600 ? y + gstring->text_descent - rface->hline->width
601 : type == MFACE_HLINE_UNDER
603 : type == MFACE_HLINE_STRIKE_THROUGH
604 ? y - ((gstring->ascent + gstring->descent) / 2)
605 : y - gstring->text_ascent);
607 gc = set_region (frame, gc, region);
609 for (i = 0; i < rface->hline->width; i++)
610 XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
611 x, y + i, x + width - 1, y + i);
616 mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
617 MGlyph *g, int x, int y, int width, MDrawRegion region)
619 Display *display = FRAME_DISPLAY (frame);
620 MRealizedFace *rface = g->rface;
621 MFaceBoxProp *box = rface->box;
622 GCInfo *info = rface->info;
623 GC gc_top, gc_left, gc_right, gc_btm;
627 y0 = y - (gstring->text_ascent
628 + rface->box->inner_vmargin + rface->box->width);
629 y1 = y + (gstring->text_descent
630 + rface->box->inner_vmargin + rface->box->width - 1);
632 gc_top = info->gc[GC_BOX_TOP];
634 gc_top = set_region (frame, gc_top, region);
635 if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM])
638 gc_btm = info->gc[GC_BOX_BOTTOM];
640 if (g->type == GLYPH_BOX)
645 x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
647 x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
649 /* Draw the top side. */
650 for (i = 0; i < box->width; i++)
651 XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
653 /* Draw the bottom side. */
654 if (region && gc_btm != gc_top)
655 gc_btm = set_region (frame, gc_btm, region);
656 for (i = 0; i < box->width; i++)
657 XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
659 if (g->left_padding > 0)
661 /* Draw the left side. */
662 if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
666 gc_left = info->gc[GC_BOX_LEFT];
668 gc_left = set_region (frame, gc_left, region);
670 for (i = 0; i < rface->box->width; i++)
671 XDrawLine (display, (Window) win, gc_left,
672 x0 + i, y0 + i, x0 + i, y1 - i);
676 /* Draw the right side. */
677 if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP])
681 gc_right = info->gc[GC_BOX_RIGHT];
683 gc_right = set_region (frame, gc_right, region);
685 for (i = 0; i < rface->box->width; i++)
686 XDrawLine (display, (Window) win, gc_right,
687 x1 - i, y0 + i, x1 - i, y1 - i);
692 /* Draw the top side. */
693 for (i = 0; i < box->width; i++)
694 XDrawLine (display, (Window) win, gc_top,
695 x, y0 + i, x + width - 1, y0 + i);
697 /* Draw the bottom side. */
698 if (region && gc_btm != gc_top)
699 gc_btm = set_region (frame, gc_btm, region);
700 for (i = 0; i < box->width; i++)
701 XDrawLine (display, (Window) win, gc_btm,
702 x, y1 - i, x + width - 1, y1 - i);
709 mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
710 int reverse, int x, int y,
711 int width, int height, int row_bytes, unsigned char *bmp,
714 Display *display = FRAME_DISPLAY (frame);
716 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
719 gc = set_region (frame, gc, region);
721 for (i = 0; i < height; i++, bmp += row_bytes)
722 for (j = 0; j < width; j++)
723 if (bmp[j / 8] & (1 << (7 - (j % 8))))
724 XDrawPoint (display, (Window) win, gc, x + j, y + i);
729 mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
730 int intensity, MDrawPoint *points, int num,
733 GCInfo *info = rface->info;
736 if (! (gc = info->gc[intensity]))
737 gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame),
740 gc = set_region (frame, gc, region);
742 XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
743 (XPoint *) points, num, CoordModeOrigin);
748 mwin__region_from_rect (MDrawMetric *rect)
750 MDrawRegion region1 = XCreateRegion ();
751 MDrawRegion region2 = XCreateRegion ();
756 xrect.width = rect->width;
757 xrect.height = rect->height;
758 XUnionRectWithRegion (&xrect, region1, region2);
759 XDestroyRegion (region1);
764 mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
766 MDrawRegion region1 = XCreateRegion ();
771 xrect.width = rect->width;
772 xrect.height = rect->height;
774 XUnionRegion (region, region, region1);
775 XUnionRectWithRegion (&xrect, region1, region);
776 XDestroyRegion (region1);
780 mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
782 MDrawRegion region = XCreateRegion ();
784 XUnionRegion (region1, region1, region);
785 XIntersectRegion (region, region2, region1);
786 XDestroyRegion (region);
790 mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
792 MDrawRegion region1 = XCreateRegion ();
797 xrect.width = rect->width;
798 xrect.height = rect->height;
799 XUnionRectWithRegion (&xrect, region1, region);
800 XDestroyRegion (region1);
804 mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
808 XClipBox (region, &xrect);
811 rect->width = xrect.width;
812 rect->height = xrect.height;
816 mwin__free_region (MDrawRegion region)
818 XDestroyRegion (region);
822 mwin__dump_region (MDrawRegion region)
825 XClipBox (region, &rect);
826 fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
831 mwin__create_window (MFrame *frame, MDrawWindow parent)
833 Display *display = FRAME_DISPLAY (frame);
835 XWMHints wm_hints = { InputHint, False };
836 XClassHint class_hints = { "M17N-IM", "m17n-im" };
837 XSetWindowAttributes set_attrs;
840 GCInfo *info = frame->rface->info;
843 parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
845 XGetGCValues (display, info->gc[GC_INVERSE], mask, &values);
846 set_attrs.background_pixel = values.foreground;
847 set_attrs.backing_store = Always;
848 set_attrs.override_redirect = True;
849 set_attrs.save_under = True;
850 mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
851 win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
852 CopyFromParent, InputOutput, CopyFromParent,
854 XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
855 NULL, &wm_hints, &class_hints);
856 XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
857 return (MDrawWindow) win;
861 mwin__destroy_window (MFrame *frame, MDrawWindow win)
863 XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
868 mwin__event_window (void *event)
870 return ((MDrawWindow) ((XEvent *) event)->xany.window);
874 mwin__print_event (void *arg, char *win_name)
877 XEvent *event = (XEvent *) arg;
879 switch (event->xany.type)
881 case 2: event_name = "KeyPress"; break;
882 case 3: event_name = "KeyRelease"; break;
883 case 4: event_name = "ButtonPress"; break;
884 case 5: event_name = "ButtonRelease"; break;
885 case 6: event_name = "MotionNotify"; break;
886 case 7: event_name = "EnterNotify"; break;
887 case 8: event_name = "LeaveNotify"; break;
888 case 9: event_name = "FocusIn"; break;
889 case 10: event_name = "FocusOut"; break;
890 case 11: event_name = "KeymapNotify"; break;
891 case 12: event_name = "Expose"; break;
892 case 13: event_name = "GraphicsExpose"; break;
893 case 14: event_name = "NoExpose"; break;
894 case 15: event_name = "VisibilityNotify"; break;
895 case 16: event_name = "CreateNotify"; break;
896 case 17: event_name = "DestroyNotify"; break;
897 case 18: event_name = "UnmapNotify"; break;
898 case 19: event_name = "MapNotify"; break;
899 case 20: event_name = "MapRequest"; break;
900 case 21: event_name = "ReparentNotify"; break;
901 case 22: event_name = "ConfigureNotify"; break;
902 case 23: event_name = "ConfigureRequest"; break;
903 case 24: event_name = "GravityNotify"; break;
904 case 25: event_name = "ResizeRequest"; break;
905 case 26: event_name = "CirculateNotify"; break;
906 case 27: event_name = "CirculateRequest"; break;
907 case 28: event_name = "PropertyNotify"; break;
908 case 29: event_name = "SelectionClear"; break;
909 case 30: event_name = "SelectionRequest"; break;
910 case 31: event_name = "SelectionNotify"; break;
911 case 32: event_name = "ColormapNotify"; break;
912 case 33: event_name = "ClientMessage"; break;
913 case 34: event_name = "MappingNotify"; break;
914 default: event_name = "unknown";
917 fprintf (stderr, "%s: %s\n", win_name, event_name);
922 mwin__map_window (MFrame *frame, MDrawWindow win)
924 XMapRaised (FRAME_DISPLAY (frame), (Window) win);
928 mwin__unmap_window (MFrame *frame, MDrawWindow win)
930 XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
934 mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
935 MDrawMetric *geometry)
937 Display *display = FRAME_DISPLAY (frame);
938 XWindowAttributes attr;
939 Window parent = (Window) parent_win, root;
941 XGetWindowAttributes (display, (Window) win, &attr);
942 geometry->x = attr.x + attr.border_width;
943 geometry->y = attr.y + attr.border_width;
944 geometry->width = attr.width;
945 geometry->height = attr.height;
948 parent = RootWindow (display, FRAME_SCREEN (frame));
951 Window this_parent, *children;
954 XQueryTree (display, (Window) win, &root, &this_parent, &children, &n);
957 if (this_parent == parent || this_parent == root)
959 win = (MDrawWindow) this_parent;
960 XGetWindowAttributes (display, (Window) win, &attr);
961 geometry->x += attr.x + attr.border_width;
962 geometry->y += attr.y + attr.border_width;
967 mwin__adjust_window (MFrame *frame, MDrawWindow win,
968 MDrawMetric *current, MDrawMetric *new)
970 Display *display = FRAME_DISPLAY (frame);
971 unsigned int mask = 0;
972 XWindowChanges values;
974 if (current->width != new->width)
979 values.width = current->width = new->width;
981 if (current->height != new->height)
984 if (new->height <= 0)
986 values.height = current->height = new->height;
988 if (current->x != new->x)
991 values.x = current->x = new->x;
993 if (current->y != new->y)
997 values.y = current->y = new->y;
1000 XConfigureWindow (display, (Window) win, mask, &values);
1001 XClearWindow (display, (Window) win);
1005 mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
1007 XEvent *event = (XEvent *) arg;
1008 MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
1015 if (event->xany.type != KeyPress
1016 /* && event->xany.type != KeyRelease */
1019 len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL);
1026 if (c < XK_space || c > XK_asciitilde)
1028 if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask)
1029 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1030 if (((XKeyEvent *) event)->state & ControlMask)
1032 if (c >= 'a' && c <= 'z')
1034 if (c >= ' ' && c < 127)
1035 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1037 key = minput__char_to_key (c);
1039 else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
1043 char *str = XKeysymToString (keysym);
1047 key = msymbol (str);
1048 if (((XKeyEvent *) event)->state & ShiftMask)
1049 *modifiers |= MINPUT_KEY_SHIFT_MODIFIER;
1050 if (((XKeyEvent *) event)->state & ControlMask)
1051 *modifiers |= MINPUT_KEY_CONTROL_MODIFIER;
1053 if (((XKeyEvent *) event)->state & disp_info->meta_mask)
1054 *modifiers |= MINPUT_KEY_META_MODIFIER;
1055 if (((XKeyEvent *) event)->state & disp_info->alt_mask)
1056 *modifiers |= MINPUT_KEY_ALT_MODIFIER;
1057 if (((XKeyEvent *) event)->state & disp_info->super_mask)
1058 *modifiers |= MINPUT_KEY_SUPER_MODIFIER;
1059 if (((XKeyEvent *) event)->state & disp_info->hyper_mask)
1060 *modifiers |= MINPUT_KEY_HYPER_MODIFIER;
1067 mwin__get_selection_text (MFrame *frame)
1074 mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
1076 unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
1078 Display *display = FRAME_DISPLAY (frame);
1079 GCInfo *info = rface->info;
1082 for (i = 0; i <= GC_INVERSE; i++)
1084 XGetGCValues (display, info->gc[i], valuemask, &values);
1085 fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
1086 values.foreground, values.background);
1087 fprintf (stderr, "\n");
1091 static MDeviceDriver x_driver =
1094 mwin__device_get_prop,
1096 mwin__free_realized_face,
1098 mwin__draw_empty_boxes,
1102 mwin__region_from_rect,
1103 mwin__union_rect_with_region,
1104 mwin__intersect_region,
1105 mwin__region_add_rect,
1106 mwin__region_to_rect,
1109 mwin__create_window,
1110 mwin__destroy_window,
1113 mwin__window_geometry,
1114 mwin__adjust_window,
1119 /** X font handler */
1121 static MRealizedFont *xfont_select (MFrame *, MFont *, MFont *, int);
1122 static int xfont_open (MRealizedFont *);
1123 static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int);
1124 static unsigned xfont_encode_char (MRealizedFont *, unsigned);
1125 static void xfont_render (MDrawWindow, int, int, MGlyphString *,
1126 MGlyph *, MGlyph *, int, MDrawRegion);
1128 static MFontDriver xfont_driver =
1129 { xfont_select, xfont_open,
1130 xfont_find_metric, xfont_encode_char, xfont_render };
1140 build_font_list (MFrame *frame, MSymbol family, MSymbol registry,
1144 MFontList *font_list;
1149 MSTRUCT_CALLOC (font_list, MERROR_WIN);
1153 sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s",
1154 msymbol_name (registry));
1155 font_list->tag = registry;
1159 sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s",
1160 msymbol_name (family), msymbol_name (registry));
1161 font_list->tag = family;
1164 fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts);
1167 MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN);
1168 for (i = j = 0; i < nfonts; i++)
1169 if ((mfont__parse_name_into_font (fontnames[i], Mx,
1170 font_list->fonts + j)
1172 && (font_list->fonts[j].property[MFONT_SIZE] != 0
1173 || font_list->fonts[j].property[MFONT_RESY] == 0))
1175 XFreeFontNames (fontnames);
1176 font_list->nfonts = j;
1178 mplist_add (plist, font_list->tag, font_list);
1179 return (nfonts > 0 ? font_list : NULL);
1182 /* The X font driver function SELECT. */
1184 static MRealizedFont *
1185 xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size)
1187 MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1188 MRealizedFont *rfont;
1189 MFontList *font_list = NULL;
1192 int best_score, score;
1194 if (registry == Mnil
1195 || ! strchr (MSYMBOL_NAME (registry), '-'))
1198 /* We handles iso8859-1 and iso10646-1 fonts specially because there
1199 exists so many such fonts. */
1200 if (registry == M_iso8859_1 || registry == M_iso10646_1)
1203 = (registry == M_iso8859_1
1204 ? FRAME_DEVICE (frame)->display_info->iso8859_1_family_list
1205 : FRAME_DEVICE (frame)->display_info->iso10646_1_family_list);
1206 MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY);
1210 font_list = (MFontList *) mplist_get (family_list, family);
1212 font_list = build_font_list (frame, family, registry, family_list);
1216 family = FONT_PROPERTY (request, MFONT_FAMILY);
1217 font_list = (MFontList *) mplist_get (family_list, family);
1219 font_list = build_font_list (frame, family, registry, family_list);
1224 MPlist *registry_list
1225 = FRAME_DEVICE (frame)->display_info->font_registry_list;
1227 font_list = (MFontList *) mplist_get (registry_list, registry);
1229 font_list = build_font_list (frame, Mnil, registry, registry_list);
1234 for (i = 0, best_score = -1, best_font = NULL; i < font_list->nfonts; i++)
1235 if ((best_score = mfont__score (font_list->fonts + i, spec, request,
1236 limited_size)) >= 0)
1240 best_font = font_list->fonts + i;
1241 for (; best_score > 0 && i < font_list->nfonts ; i++)
1243 score = mfont__score (font_list->fonts + i, spec, request,
1245 if (score >= 0 && score < best_score)
1247 best_font = font_list->fonts + i;
1252 MSTRUCT_CALLOC (rfont, MERROR_WIN);
1253 rfont->frame = frame;
1254 rfont->spec = *spec;
1255 rfont->request = *request;
1256 rfont->font = *best_font;
1257 if (best_font->property[MFONT_SIZE] == 0)
1258 rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE];
1259 rfont->score = best_score;
1264 /* The X font driver function CLOSE. */
1267 close_xfont (void *object)
1269 MXFontInfo *xfont_info = object;
1271 XFreeFont (xfont_info->display, xfont_info->xfont);
1276 /* The X font driver function OPEN. */
1279 xfont_open (MRealizedFont *rfont)
1282 MXFontInfo *xfont_info;
1283 MFrame *frame = rfont->frame;
1284 int mdebug_mask = MDEBUG_FONT;
1286 /* This never fail to generate a valid fontname because open_spec
1287 should correspond to a font available on the system. */
1288 name = mfont_unparse_name (&rfont->font, Mx);
1289 M17N_OBJECT (xfont_info, close_xfont, MERROR_WIN);
1290 xfont_info->display = FRAME_DISPLAY (frame);
1291 xfont_info->xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name);
1292 if (! xfont_info->xfont)
1296 MDEBUG_PRINT1 (" [XFONT] x %s\n", name);
1300 rfont->info = xfont_info;
1301 MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
1304 rfont->ascent = xfont_info->xfont->ascent;
1305 rfont->descent = xfont_info->xfont->descent;
1310 /* The X font driver function FIND_METRIC. */
1313 xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1316 MXFontInfo *xfont_info = rfont->info;
1317 XFontStruct *xfont = xfont_info->xfont;
1318 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1320 for (; g != gend; g++)
1322 if (g->code == MCHAR_INVALID_CODE)
1324 g->lbearing = xfont->max_bounds.lbearing;
1325 g->rbearing = xfont->max_bounds.rbearing;
1326 g->width = xfont->max_bounds.width;
1327 g->ascent = xfont->ascent;
1328 g->descent = xfont->descent;
1332 int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
1333 XCharStruct *pcm = NULL;
1335 if (xfont->per_char != NULL)
1337 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
1340 && byte2 >= xfont->min_char_or_byte2
1341 && byte2 <= xfont->max_char_or_byte2)
1342 pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
1346 if (byte1 >= xfont->min_byte1
1347 && byte1 <= xfont->max_byte1
1348 && byte2 >= xfont->min_char_or_byte2
1349 && byte2 <= xfont->max_char_or_byte2)
1351 pcm = (xfont->per_char
1352 + ((xfont->max_char_or_byte2
1353 - xfont->min_char_or_byte2 + 1)
1354 * (byte1 - xfont->min_byte1))
1355 + (byte2 - xfont->min_char_or_byte2));
1362 g->lbearing = pcm->lbearing;
1363 g->rbearing = pcm->rbearing;
1364 g->width = pcm->width;
1365 g->ascent = pcm->ascent;
1366 g->descent = pcm->descent;
1370 /* If the per_char pointer is null, all glyphs between
1371 the first and last character indexes inclusive have
1372 the same information, as given by both min_bounds and
1375 g->rbearing = xfont->max_bounds.width;
1376 g->width = xfont->max_bounds.width;
1377 g->ascent = xfont->ascent;
1378 g->descent = xfont->descent;
1385 /* The X font driver function GET_GLYPH_ID. */
1388 xfont_encode_char (MRealizedFont *rfont, unsigned code)
1390 MXFontInfo *xfont_info;
1392 unsigned min_byte1, max_byte1, min_byte2, max_byte2;
1393 int all_chars_exist;
1395 if (rfont->status < 0 || code >= 0x10000)
1396 return MCHAR_INVALID_CODE;
1397 if (rfont->status == 0)
1399 if (xfont_open (rfont) < 0)
1400 return MCHAR_INVALID_CODE;
1402 xfont_info = rfont->info;
1403 xfont = xfont_info->xfont;
1404 all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True);
1405 min_byte1 = xfont->min_byte1;
1406 max_byte1 = xfont->max_byte1;
1407 min_byte2 = xfont->min_char_or_byte2;
1408 max_byte2 = xfont->max_char_or_byte2;
1410 if (min_byte1 == 0 && max_byte1 == 0)
1414 if (code < min_byte2 || code > max_byte2)
1415 return MCHAR_INVALID_CODE;
1416 if (all_chars_exist)
1418 pcm = xfont->per_char + (code - min_byte2);
1419 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
1420 ? code : MCHAR_INVALID_CODE);
1424 unsigned byte1 = code >> 8, byte2 = code & 0xFF;
1427 if (byte1 < min_byte1 || byte1 > max_byte1
1428 || byte2 < min_byte2 || byte2 > max_byte2)
1429 return MCHAR_INVALID_CODE;
1431 if (all_chars_exist)
1433 pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1)
1434 + (byte2 - min_byte2));
1435 return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing)
1436 ? code : MCHAR_INVALID_CODE);
1440 /* The X font driver function RENDER. */
1443 xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring,
1444 MGlyph *from, MGlyph *to, int reverse, MDrawRegion region)
1446 MRealizedFace *rface = from->rface;
1447 MXFontInfo *xfont_info = rface->rfont->info;
1450 GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL];
1457 /* It is assured that the all glyphs in the current range use the
1458 same realized face. */
1459 display = FRAME_DISPLAY (rface->frame);
1462 gc = set_region (rface->frame, gc, region);
1463 XSetFont (display, gc, xfont_info->xfont->fid);
1464 code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
1465 for (i = 0, g = from; g < to; i++, g++)
1467 code[i].byte1 = g->code >> 8;
1468 code[i].byte2 = g->code & 0xFF;
1474 if (g->type == GLYPH_PAD)
1476 else if (g->type == GLYPH_SPACE)
1477 for (; g < to && g->type == GLYPH_SPACE; g++)
1479 else if (! g->rface->rfont)
1481 if ((g->c >= 0x200B && g->c <= 0x200F)
1482 || (g->c >= 0x202A && g->c <= 0x202E))
1486 /* As a font is not found for this character, draw an
1488 int box_width = g->width;
1489 int box_height = gstring->ascent + gstring->descent;
1495 XDrawRectangle (display, (Window) win, gc,
1496 x, y - gstring->ascent, box_width, box_height);
1500 else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
1502 XDrawString16 (display, (Window) win, gc,
1503 x + g->xoff, y + g->yoff, code + (g - from), 1);
1510 int code_idx = g - from;
1513 g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
1516 XDrawString16 (display, (Window) win, gc, orig_x, y,
1517 code + code_idx, i);
1532 XftFont *font_no_aa;
1535 static int xft_open (MRealizedFont *);
1536 static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int);
1537 static void xft_render (MDrawWindow, int, int, MGlyphString *,
1538 MGlyph *, MGlyph *, int, MDrawRegion);
1540 MFontDriver xft_driver =
1541 { NULL, /* Set to ft_select in mwin__init (). */
1542 xft_open, xft_find_metric,
1543 NULL, /* Set to ft_encode_char in mwin__init (). */
1548 close_xft (void *object)
1550 MXftFontInfo *font_info = object;
1552 XftFontClose (font_info->display, font_info->font_aa);
1553 XftFontClose (font_info->display, font_info->font_no_aa);
1559 xft_open_font (MFrame *frame, MFTInfo *ft_info, int size, int anti_alias)
1561 XftPattern *pattern;
1562 XftFontInfo *xft_font_info;
1565 pattern = XftPatternCreate ();
1566 XftPatternAddString (pattern, XFT_FILE, ft_info->filename);
1567 XftPatternAddDouble (pattern, XFT_PIXEL_SIZE, (double) size);
1568 XftPatternAddBool (pattern, XFT_ANTIALIAS, anti_alias);
1569 xft_font_info = XftFontInfoCreate (FRAME_DISPLAY (frame), pattern);
1570 if (! xft_font_info)
1572 font = XftFontOpenInfo (FRAME_DISPLAY (frame), pattern, xft_font_info);
1573 XftFontInfoDestroy (FRAME_DISPLAY (frame), xft_font_info);
1579 xft_open (MRealizedFont *rfont)
1583 MXftFontInfo *font_info;
1586 if ((mfont__ft_driver.open) (rfont) < 0)
1589 size = rfont->font.property[MFONT_SIZE] / 10;
1590 frame = rfont->frame;
1592 ft_info = rfont->info;
1593 M17N_OBJECT (font_info, close_xft, MERROR_WIN);
1594 ft_info->extra_info = font_info;
1595 font_info->display = FRAME_DISPLAY (frame);
1596 font_info->font_aa = xft_open_font (frame, ft_info, size, 1);
1597 if (font_info->font_aa)
1599 font_info->font_no_aa = xft_open_font (frame, ft_info, size, 0);
1600 if (font_info->font_no_aa)
1602 XftFontClose (FRAME_DISPLAY (rfont->frame), font_info->font_aa);
1605 ft_info->extra_info = NULL;
1612 xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
1615 MFTInfo *ft_info = rfont->info;
1616 MXftFontInfo *font_info = ft_info->extra_info;
1617 FT_Face ft_face = ft_info->ft_face;
1618 MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
1620 for (; g != gend; g++)
1622 if (g->code == MCHAR_INVALID_CODE)
1624 MGlyph *start = g++;
1626 while (g != gend && g->code == MCHAR_INVALID_CODE) g++;
1627 (mfont__ft_driver.find_metric) (rfont, gstring, GLYPH_INDEX (start),
1635 XftGlyphExtents (FRAME_DISPLAY (rfont->frame),
1636 font_info->font_aa, &g->code, 1, &extents);
1637 g->lbearing = - extents.x;
1638 g->rbearing = extents.width - extents.x;
1639 g->width = extents.xOff;
1640 g->ascent = extents.y;
1641 g->descent = extents.height - extents.y;
1648 xft_render (MDrawWindow win, int x, int y,
1649 MGlyphString *gstring, MGlyph *from, MGlyph *to,
1650 int reverse, MDrawRegion region)
1652 MRealizedFace *rface = from->rface;
1653 MFrame *frame = rface->frame;
1654 MFTInfo *ft_info = rface->rfont->info;
1655 MXftFontInfo *font_info = ft_info->extra_info;
1656 XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw;
1657 XftColor *xft_color = (! reverse
1658 ? &((GCInfo *) rface->info)->xft_color_fore
1659 : &((GCInfo *) rface->info)->xft_color_back);
1660 XftFont *xft_font = (gstring->control.anti_alias
1661 && FRAME_DEVICE (frame)->depth > 1
1662 ? font_info->font_aa : font_info->font_no_aa);
1671 XftDrawChange (xft_draw, (Drawable) win);
1672 XftDrawSetClip (xft_draw, (Region) region);
1674 glyphs = alloca (sizeof (FT_UInt) * (to - from));
1675 for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
1677 if (g->xoff == 0 && g->yoff == 0)
1678 glyphs[nglyphs++] = g->code;
1682 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1683 last_x, y, glyphs, nglyphs);
1685 XftDrawGlyphs (xft_draw, xft_color, xft_font,
1686 x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
1687 last_x = x + g->width;
1691 XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
1698 /* XIM (X Input Method) handler */
1700 typedef struct MInputXIMMethodInfo
1706 } MInputXIMMethodInfo;
1708 typedef struct MInputXIMContextInfo
1712 MConverter *converter;
1713 } MInputXIMContextInfo;
1716 xim_open_im (MInputMethod *im)
1718 MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg;
1719 MLocale *saved, *this;
1720 char *save_modifier_list;
1722 MInputXIMMethodInfo *im_info;
1724 saved = mlocale_set (LC_CTYPE, NULL);
1725 this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : "");
1727 /* The specified locale is not supported. */
1728 MERROR (MERROR_LOCALE, -1);
1729 if (mlocale_get_prop (this, Mcoding) == Mnil)
1731 /* Unable to decode the output of XIM. */
1732 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1733 MERROR (MERROR_LOCALE, -1);
1736 if (arg->modifier_list)
1737 save_modifier_list = XSetLocaleModifiers (arg->modifier_list);
1739 save_modifier_list = XSetLocaleModifiers ("");
1740 if (! save_modifier_list)
1742 /* The specified locale is not supported by X. */
1743 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1744 MERROR (MERROR_LOCALE, -1);
1747 xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class);
1750 /* No input method is available in the current locale. */
1751 XSetLocaleModifiers (save_modifier_list);
1752 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1753 MERROR (MERROR_WIN, -1);
1756 MSTRUCT_MALLOC (im_info, MERROR_WIN);
1757 im_info->display = arg->display;
1759 im_info->language = mlocale_get_prop (this, Mlanguage);
1760 im_info->coding = mlocale_get_prop (this, Mcoding);
1763 XSetLocaleModifiers (save_modifier_list);
1764 mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname)));
1770 xim_close_im (MInputMethod *im)
1772 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
1774 XCloseIM (im_info->xim);
1779 xim_create_ic (MInputContext *ic)
1781 MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
1782 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1783 MInputXIMContextInfo *ic_info;
1786 if (! arg->input_style)
1788 /* By default, use Root style. */
1789 arg->input_style = XIMPreeditNothing | XIMStatusNothing;
1790 arg->preedit_attrs = NULL;
1791 arg->status_attrs = NULL;
1794 if (! arg->preedit_attrs && ! arg->status_attrs)
1795 xic = XCreateIC (im_info->xim,
1796 XNInputStyle, arg->input_style,
1797 XNClientWindow, arg->client_win,
1798 XNFocusWindow, arg->focus_win,
1800 else if (arg->preedit_attrs && ! arg->status_attrs)
1801 xic = XCreateIC (im_info->xim,
1802 XNInputStyle, arg->input_style,
1803 XNClientWindow, arg->client_win,
1804 XNFocusWindow, arg->focus_win,
1805 XNPreeditAttributes, arg->preedit_attrs,
1807 else if (! arg->preedit_attrs && arg->status_attrs)
1808 xic = XCreateIC (im_info->xim,
1809 XNInputStyle, arg->input_style,
1810 XNClientWindow, arg->client_win,
1811 XNFocusWindow, arg->focus_win,
1812 XNStatusAttributes, arg->status_attrs,
1815 xic = XCreateIC (im_info->xim,
1816 XNInputStyle, arg->input_style,
1817 XNClientWindow, arg->client_win,
1818 XNFocusWindow, arg->focus_win,
1819 XNPreeditAttributes, arg->preedit_attrs,
1820 XNStatusAttributes, arg->status_attrs,
1823 MERROR (MERROR_WIN, -1);
1825 MSTRUCT_MALLOC (ic_info, MERROR_WIN);
1827 ic_info->win = arg->focus_win;
1828 ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0);
1834 xim_destroy_ic (MInputContext *ic)
1836 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1838 XDestroyIC (ic_info->xic);
1839 mconv_free_converter (ic_info->converter);
1845 xim_filter (MInputContext *ic, MSymbol key, void *event)
1847 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1849 return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
1854 xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
1856 MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
1857 MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
1858 XKeyPressedEvent *ev = (XKeyPressedEvent *) arg;
1864 buf = (char *) alloca (512);
1865 len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status);
1866 if (status == XBufferOverflow)
1868 buf = (char *) alloca (len);
1869 len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status);
1872 mtext_reset (ic->produced);
1876 mconv_reset_converter (ic_info->converter);
1877 mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len);
1878 mconv_decode (ic_info->converter, ic->produced);
1879 mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced),
1880 Mlanguage, (void *) im_info->language);
1881 mtext_cpy (mt, ic->produced);
1882 mtext_reset (ic->produced);
1888 #ifdef X_SET_ERROR_HANDLER
1890 x_error_handler (Display *display, XErrorEvent *error)
1897 x_io_error_handler (Display *display)
1906 /* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
1911 M_iso8859_1 = msymbol ("iso8859-1");
1912 M_iso10646_1 = msymbol ("iso10646-1");
1914 display_info_list = mplist ();
1915 device_list = mplist ();
1918 xft_driver.select = mfont__ft_driver.select;
1919 xft_driver.encode_char = mfont__ft_driver.encode_char;
1922 Mxim = msymbol ("xim");
1923 msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
1931 M17N_OBJECT_UNREF (display_info_list);
1932 M17N_OBJECT_UNREF (device_list);
1936 /** Return an MWDevice object corresponding to a display specified in
1939 It searches device_list for a device matching the display. If
1940 found, return the found object. Otherwise, return a newly created
1944 device_open (MFrame *frame, MPlist *param)
1946 Display *display = NULL;
1947 Screen *screen = NULL;
1949 Drawable drawable = 0;
1950 Widget widget = NULL;
1952 int auto_display = 0;
1953 MDisplayInfo *disp_info = NULL;
1954 MWDevice *device = NULL;
1956 XWindowAttributes attr;
1962 for (plist = param; (key = mplist_key (plist)) != Mnil;
1963 plist = mplist_next (plist))
1965 if (key == Mdisplay)
1966 display = (Display *) mplist_value (plist);
1967 else if (key == Mscreen)
1968 screen = mplist_value (plist);
1969 else if (key == Mdrawable)
1970 drawable = (Drawable) mplist_value (plist);
1971 else if (key == Mdepth)
1972 depth = (unsigned) mplist_value (plist);
1973 else if (key == Mwidget)
1974 widget = (Widget) mplist_value (plist);
1975 else if (key == Mcolormap)
1976 cmap = (Colormap) mplist_value (plist);
1981 display = XtDisplay (widget);
1982 screen_num = XScreenNumberOfScreen (XtScreen (widget));
1983 depth = DefaultDepth (display, screen_num);
1989 unsigned width, height, border_width;
1992 MERROR (MERROR_WIN, NULL);
1993 XGetGeometry (display, drawable, &root_window,
1994 &x, &y, &width, &height, &border_width, &depth);
1995 XGetWindowAttributes (display, root_window, &attr);
1996 screen_num = XScreenNumberOfScreen (attr.screen);
2001 display = DisplayOfScreen (screen);
2006 display = XOpenDisplay (NULL);
2008 MERROR (MERROR_WIN, NULL);
2011 screen = DefaultScreenOfDisplay (display);
2013 screen_num = XScreenNumberOfScreen (screen);
2015 depth = DefaultDepth (display, screen_num);
2019 cmap = DefaultColormap (display, screen_num);
2021 for (plist = display_info_list; mplist_key (plist) != Mnil;
2022 plist = mplist_next (plist))
2024 disp_info = (MDisplayInfo *) mplist_value (plist);
2025 if (disp_info->display == display)
2029 if (mplist_key (plist) != Mnil)
2030 M17N_OBJECT_REF (disp_info);
2033 M17N_OBJECT (disp_info, free_display_info, MERROR_WIN);
2034 disp_info->display = display;
2035 disp_info->auto_display = auto_display;
2036 disp_info->font_registry_list = mplist ();
2037 disp_info->iso8859_1_family_list = mplist ();
2038 disp_info->iso10646_1_family_list = mplist ();
2039 disp_info->realized_font_list = mplist ();
2040 find_modifier_bits (disp_info);
2041 mplist_add (display_info_list, Mt, disp_info);
2044 for (plist = device_list; mplist_key (plist) != Mnil;
2045 plist = mplist_next (plist))
2047 device = (MWDevice *) mplist_value (plist);
2048 if (device->display_info == disp_info
2049 && device->depth == depth
2050 && device->cmap == cmap)
2054 if (mplist_key (plist) != Mnil)
2055 M17N_OBJECT_REF (device);
2058 unsigned long valuemask = GCForeground;
2061 M17N_OBJECT (device, free_device, MERROR_WIN);
2062 device->display_info = disp_info;
2063 device->screen_num = screen_num;
2064 /* A drawable on which to create GCs. */
2065 device->drawable = XCreatePixmap (display,
2066 RootWindow (display, screen_num),
2068 device->depth = depth;
2069 device->cmap = cmap;
2070 device->realized_face_list = mplist ();
2071 device->realized_fontset_list = mplist ();
2072 device->gc_list = mplist ();
2073 values.foreground = BlackPixel (display, screen_num);
2074 device->scratch_gc = XCreateGC (display, device->drawable,
2075 valuemask, &values);
2077 device->xft_draw = XftDrawCreate (display, device->drawable,
2078 DefaultVisual (display, screen_num),
2083 frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
2084 frame->driver = &x_driver;
2085 frame->font_driver_list = mplist ();
2086 mplist_add (frame->font_driver_list, Mx, &xfont_driver);
2088 mplist_add (frame->font_driver_list, Mfreetype, &xft_driver);
2090 mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
2092 frame->realized_font_list = disp_info->realized_font_list;
2093 frame->realized_face_list = device->realized_face_list;
2094 frame->realized_fontset_list = device->realized_fontset_list;
2098 XtResource resources[] = {
2099 { XtNfont, XtCFont, XtRString, sizeof (String),
2100 XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT },
2101 { XtNforeground, XtCForeground, XtRString, sizeof (String),
2102 XtOffset (AppDataPtr, foreground), XtRString, "black" },
2103 { XtNbackground, XtCBackground, XtRString, sizeof (String),
2104 XtOffset (AppDataPtr, background), XtRString, "white" },
2105 { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
2106 XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE }
2109 XtGetApplicationResources (widget, &app_data,
2110 resources, XtNumber (resources), NULL, 0);
2111 frame->foreground = msymbol (app_data.foreground);
2112 frame->background = msymbol (app_data.background);
2113 frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal;
2117 app_data.font = DEFAULT_FONT;
2118 frame->foreground = msymbol ("black");
2119 frame->background = msymbol ("white");
2120 frame->videomode = Mnormal;
2125 char **names = XListFonts (display, app_data.font, 1, &nfonts);
2129 if (! (frame->font = mfont_parse_name (names[0], Mx)))
2131 /* The font name does not conform to XLFD. Try to open the
2132 font and get XA_FONT property. */
2133 XFontStruct *xfont = XLoadQueryFont (display, names[0]);
2138 unsigned long value;
2141 if (XGetFontProperty (xfont, XA_FONT, &value)
2142 && (name = ((char *)
2143 XGetAtomName (display, (Atom) value))))
2145 if ((frame->font = mfont_parse_name (name, Mx)))
2148 XFreeFont (display, xfont);
2151 XFreeFontNames (names);
2154 frame->font = mfont_parse_name (FALLBACK_FONT, Mx);
2157 face = mface_from_font (frame->font);
2158 face->property[MFACE_FONTSET] = mfontset (NULL);
2159 face->property[MFACE_FOREGROUND] = frame->foreground;
2160 face->property[MFACE_BACKGROUND] = frame->background;
2161 mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline));
2162 mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox));
2163 face->property[MFACE_VIDEOMODE] = frame->videomode;
2164 mface_put_prop (face, Mhook_func,
2165 mface_get_prop (mface__default, Mhook_func));
2166 face->property[MFACE_RATIO] = (void *) 100;
2167 mplist_push (param, Mface, face);
2168 M17N_OBJECT_UNREF (face);
2170 #ifdef X_SET_ERROR_HANDLER
2171 XSetErrorHandler (x_error_handler);
2172 XSetIOErrorHandler (x_io_error_handler);
2179 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
2184 /*** @addtogroup m17nInputMethodWin */
2189 @brief Input method driver for XIM.
2191 The driver #minput_xim_driver is for the foreign input method of
2192 name #Mxim. It uses XIM (X Input Methods) as a background input
2195 As the symbol #Mxim has property #Minput_driver whose value is
2196 a pointer to this driver, the input method of language #Mnil
2197 and name #Mxim uses this driver.
2199 Therefore, for such input methods, the driver dependent arguments
2200 to the functions whose name begin with minput_ must be as follows.
2202 The argument $ARG of the function minput_open_im () must be a
2203 pointer to the structure #MInputXIMArgIM. See the documentation
2204 of #MInputXIMArgIM for more details.
2206 The argument $ARG of the function minput_create_ic () must be a
2207 pointer to the structure #MInputXIMArgIC. See the documentation
2208 of #MInputXIMArgIC for more details.
2210 The argument $ARG of the function minput_filter () must be a
2211 pointer to the structure @c XEvent. The argument $KEY is ignored.
2213 The argument $ARG of the function minput_lookup () must be the
2214 same one as that of the function minput_filter (). The argument
2218 @brief XIMÍÑÆþÎϥɥ饤¥Ð.
2220 ¥É¥é¥¤¥Ð #minput_xim_driver ¤Ï #Mxim ¤ò̾Á°¤È¤·¤Æ»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã
2221 ¥ÉÍѤǤ¢¤ê¡¢ XIM (X Input Methods) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨¥ó¥¸
2224 ¥·¥ó¥Ü¥ë #Mxim ¤Ï¤³¤Î¥É¥é¥¤¥Ð¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥×¥í¥Ñ¥Æ¥£
2225 #Minput_driver ¤ò»ý¤Á¡¢LANGUAGE ¤¬ #Mnil ¤Ç̾Á°¤¬ #Mxim ¤Ç¤¢¤ëÆþÎÏ
2226 ¥á¥½¥Ã¥É¤Ï¤³¤Î¥É¥é¥¤¥Ð¤òÍøÍѤ¹¤ë¡£
2228 ¤·¤¿¤¬¤Ã¤Æ¡¢¤½¤ì¤é¤ÎÆþÎϥ᥽¥Ã¥É¤Ç¤Ï¡¢minput_ ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø
2229 ¿ô¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ê¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2231 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIM ¤Ø¤Î¥Ý
2232 ¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIM ¤ÎÀâÌÀ¤ò
2235 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ #MInputXIMArgIC ¤Ø¤Î
2236 ¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï #MInputXIMArgIC ¤ÎÀâÌÀ
2239 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c XEvent ¤Ø¤Î¥Ý¥¤¥ó¥¿
2240 ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£°ú¿ô $KEY ¤Ï̵»ë¤µ¤ì¤ë¡£
2242 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô function minput_filter ()
2243 ¤Î°ú¿ô $ARG ¤ÈƱ¤¸¤â¤Î¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ °ú¿ô $KEY ¤Ï¡¢Ìµ»ë¤µ¤ì
2246 MInputDriver minput_xim_driver =
2247 { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic,
2248 xim_filter, xim_lookup, NULL };