From: handa Date: Thu, 27 May 2004 09:06:17 +0000 (+0000) Subject: (FRAME_DEVICE): New macro. X-Git-Tag: withdl~172 X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=5477050393b47d285ceba856581c7c933eff8b73;p=m17n%2Fm17n-lib.git (FRAME_DEVICE): New macro. (FRAME_DISPLAY, FRAME_SCREEN, FRAME_CMAP): Use FRAME_DEVICE. (free_display_info): Use MPLIST_DO. (free_device): Free rface->info. (xft_close): Delete it. (device_init): Renamed from mwin__init. (device_fini): Renamed from mwin__fini. (device_open): Renamed from mwin__open_device. (x_driver): New variable. (MXFontInfo): Delete member frame, add member display. (Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap, Mxim): Don't declare them here. --- diff --git a/src/m17n-X.c b/src/m17n-X.c index 7d28516..ddffeea 100644 --- a/src/m17n-X.c +++ b/src/m17n-X.c @@ -122,7 +122,7 @@ typedef struct #endif } GCInfo; -struct MWDevice +typedef struct { /* Common header for the m17n object. */ M17NObject control; @@ -151,15 +151,16 @@ struct MWDevice /** List of XColors vs GCs on the frame. */ MPlist *gc_list; -}; +} MWDevice; static MPlist *device_list; static MSymbol M_iso8859_1, M_iso10646_1; -#define FRAME_DISPLAY(frame) ((frame)->device->display_info->display) -#define FRAME_SCREEN(frame) ((frame)->device->screen_num) -#define FRAME_CMAP(frame) ((frame)->device->cmap) +#define FRAME_DEVICE(frame) ((MWDevice *) (frame)->device) +#define FRAME_DISPLAY(frame) (FRAME_DEVICE (frame)->display_info->display) +#define FRAME_SCREEN(frame) (FRAME_DEVICE (frame)->screen_num) +#define FRAME_CMAP(frame) (FRAME_DEVICE (frame)->cmap) #define FRAME_VISUAL(frame) DefaultVisual (FRAME_DISPLAY (frame), \ FRAME_SCREEN (frame)) @@ -180,10 +181,9 @@ free_display_info (void *object) MDisplayInfo *disp_info = (MDisplayInfo *) object; MPlist *plist; - for (plist = disp_info->font_registry_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) + MPLIST_DO (plist, disp_info->font_registry_list) { - MFontList *registry_list = mplist_value (plist); + MFontList *registry_list = MPLIST_VAL (plist); if (registry_list->fonts) free (registry_list->fonts); @@ -191,10 +191,9 @@ free_display_info (void *object) } M17N_OBJECT_UNREF (disp_info->font_registry_list); - for (plist = disp_info->iso8859_1_family_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) + MPLIST_DO (plist, disp_info->iso8859_1_family_list) { - MFontList *family_list = mplist_value (plist); + MFontList *family_list = MPLIST_VAL (plist); if (family_list->fonts) free (family_list->fonts); @@ -202,10 +201,9 @@ free_display_info (void *object) } M17N_OBJECT_UNREF (disp_info->iso8859_1_family_list); - for (plist = disp_info->iso10646_1_family_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) + MPLIST_DO (plist, disp_info->iso10646_1_family_list) { - MFontList *family_list = mplist_value (plist); + MFontList *family_list = MPLIST_VAL (plist); if (family_list->fonts) free (family_list->fonts); @@ -213,9 +211,8 @@ free_display_info (void *object) } M17N_OBJECT_UNREF (disp_info->iso10646_1_family_list); - for (plist = disp_info->realized_font_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) - mfont__free_realized ((MRealizedFont *) mplist_value (plist)); + MPLIST_DO (plist, disp_info->realized_font_list) + mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist)); M17N_OBJECT_UNREF (disp_info->realized_font_list); if (disp_info->auto_display) @@ -227,7 +224,7 @@ free_display_info (void *object) static void free_device (void *object) { - MWDevice *device = (MWDevice *) object; + MWDevice *device = object; MPlist *plist; for (plist = device->realized_fontset_list; @@ -235,9 +232,13 @@ free_device (void *object) mfont__free_realized_fontset ((MRealizedFontset *) mplist_value (plist)); M17N_OBJECT_UNREF (device->realized_fontset_list); - for (plist = device->realized_face_list; - mplist_key (plist) != Mnil; plist = mplist_next (plist)) - mface__free_realized ((MRealizedFace *) mplist_value (plist)); + MPLIST_DO (plist, device->realized_face_list) + { + MRealizedFace *rface = MPLIST_VAL (plist); + + free (rface->info); + mface__free_realized (rface); + } M17N_OBJECT_UNREF (device->realized_face_list); MPLIST_DO (plist, device->gc_list) @@ -344,7 +345,7 @@ get_rgb_gc (MWDevice *device, XColor *xcolor) static GC get_gc (MFrame *frame, MSymbol color, int for_foreground, int *rgb_ret) { - MWDevice *device = frame->device; + MWDevice *device = FRAME_DEVICE (frame); XColor xcolor; RGB_GC *rgb_gc; @@ -407,1986 +408,1983 @@ get_gc_for_anti_alias (MWDevice *device, GCInfo *info, int intensity) return (info->gc[intensity] = gc); } - -/** X font handler */ +static GC +set_region (MFrame *frame, GC gc, MDrawRegion region) +{ + unsigned long valuemask = GCForeground; -/** Indices to each field of split font name. */ + XCopyGC (FRAME_DISPLAY (frame), gc, valuemask, + FRAME_DEVICE (frame)->scratch_gc); + XSetRegion (FRAME_DISPLAY (frame), FRAME_DEVICE (frame)->scratch_gc, region); + return FRAME_DEVICE (frame)->scratch_gc; +} -enum xlfd_field_idx - { - XLFD_FOUNDRY, - XLFD_FAMILY, - XLFD_WEIGHT, - XLFD_SLANT, - XLFD_SWIDTH, - XLFD_ADSTYLE, - XLFD_PIXEL, - XLFD_POINT, - XLFD_RESX, - XLFD_RESY, - XLFD_SPACING, - XLFD_AVGWIDTH, - XLFD_REGISTRY, - XLFD_ENCODING, - /* anchor */ - XLFD_FIELD_MAX - }; + +/* Functions for the device driver. */ -/** Split the fontname NAME into each XLFD field destructively. Set - each element of the table pointed by PROPERTY_IDX to a pointer to - the corresponding font property name. Store the point size and - the resolution-Y of the font to the place pointed by POINT and - RESY respectively. +void +mwin__close_device (MFrame *frame) +{ + M17N_OBJECT_UNREF (FRAME_DEVICE (frame)); +} - If NAME does not contain all XLFD fields, the unspecified fields is - treated as wild cards. */ +void * +mwin__device_get_prop (MFrame *frame, MSymbol key) +{ + MWDevice *device = FRAME_DEVICE (frame); -static int -split_font_name (char *name, char **field, - unsigned short *size, unsigned short *resy) + if (key == Mdisplay) + return (void *) device->display_info->display; + if (key == Mscreen) + return (void *) ScreenOfDisplay(device->display_info->display, + device->screen_num); + if (key == Mcolormap) + return (void *) device->cmap; + if (key == Mdepth) + return (void *) device->depth; + return NULL; +} + +void +mwin__realize_face (MRealizedFace *rface) { - int i; - char *p; + MFrame *frame; + MSymbol foreground, background, videomode; + MFaceHLineProp *hline; + MFaceBoxProp *box; + GCInfo *info; - for (i = 0, p = name; *p; p++) + if (rface != rface->ascii_rface) { - *p = tolower (*p); - if (*p == '-' && i < XLFD_FIELD_MAX) - { - field[i] = p + 1; - if (i != XLFD_ENCODING) - *p = '\0'; - i++; - } + rface->info = rface->ascii_rface->info; + return; } - if (i < XLFD_REGISTRY) - return -1; - for (; i < XLFD_FIELD_MAX; i++) - field[i] = "*"; - if (*(field[XLFD_RESY]) == '*') - *resy = 0; + frame = rface->frame; + MSTRUCT_CALLOC (info, MERROR_WIN); + + foreground = rface->face.property[MFACE_FOREGROUND]; + background = rface->face.property[MFACE_BACKGROUND]; + videomode = rface->face.property[MFACE_VIDEOMODE]; + if (! videomode) + videomode = frame->videomode; + if (videomode != Mreverse) + { + info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore); + info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back); + } else - *resy = atoi (field[XLFD_RESY]); - if (*(field[XLFD_PIXEL]) == '*') { - if (*(field[XLFD_POINT]) != '*') - *size = atoi (field[XLFD_POINT]) * *resy / 72; - else - *size = 0; + info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore); + info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back); } - else if (*(field[XLFD_PIXEL]) == '[') +#ifdef HAVE_XFT2 + if (foreground == Mnil) + foreground = frame->foreground; + if (background == Mnil) + background = frame->background; + if (videomode == Mreverse) { - /* The pixel size field specifies a transformation matrix of the - form "[A B C D]". The XLFD spec says that the scalar value N - for the pixel size is equivalent to D. */ - char *p0 = field[XLFD_PIXEL] + 1, *p1; - double d; - - for (i = 0; i < 4; i++, p0 = p1) - d = strtod (p0, &p1); - *size = d * 10; + MSymbol temp = foreground; + foreground = background; + background = temp; } - else - *size = atoi (field[XLFD_PIXEL]) * 10; - if (*size == 0 && *(field[XLFD_POINT]) != '*') + if (! XftColorAllocName (FRAME_DISPLAY (frame), + FRAME_VISUAL (frame), + FRAME_CMAP (frame), + MSYMBOL_NAME (foreground), + &info->xft_color_fore)) + mdebug_hook (); + if (! XftColorAllocName (FRAME_DISPLAY (frame), + FRAME_VISUAL (frame), + FRAME_CMAP (frame), + MSYMBOL_NAME (background), + &info->xft_color_back)) + mdebug_hook (); +#endif + + hline = rface->hline; + if (hline) { - *size = atoi (field[XLFD_POINT]); - if (*resy) - *size = *size * *resy / 72; + if (hline->color) + info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL); else - *size = *size * 100 / 72; + info->gc[GC_HLINE] = info->gc[GC_NORMAL]; } - return 0; -} + box = rface->box; + if (box) + { + if (box->color_top) + info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL); + else + info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL]; -static int -build_font_name (MFont *font, char *name, int limit) -{ - MSymbol prop[7]; - char *str[7]; - int len, i; - unsigned short size, resy; + if (box->color_left && box->color_left != box->color_top) + info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL); + else + info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP]; - prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry); - prop[1] = (MSymbol) mfont_get_prop (font, Mfamily); - prop[2] = (MSymbol) mfont_get_prop (font, Mweight); - prop[3] = (MSymbol) mfont_get_prop (font, Mstyle); - prop[4] = (MSymbol) mfont_get_prop (font, Mstretch); - prop[5] = (MSymbol) mfont_get_prop (font, Madstyle); - prop[6] = (MSymbol) mfont_get_prop (font, Mregistry); - for (len = 0, i = 0; i < 7; i++) - { - if (prop[i] != Mnil) - { - str[i] = msymbol_name (prop[i]); - len += strlen (str[i]); - } + if (box->color_bottom && box->color_bottom != box->color_top) + info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL); else - { - str[i] = "*"; - len++; - } + info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP]; + + if (box->color_right && box->color_right != box->color_bottom) + info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL); + else + info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM]; } - if ((len - + 12 /* 12 dashes */ - + 3 /* 3 asterisks */ - + 30 /* 3 integers (each 10 digits) */ - + 1) /* '\0' terminal */ - > limit) - return -1; - size = (int) mfont_get_prop (font, Msize); - if ((size % 10) < 5) - size /= 10; - else - size = size / 10 + 1; - resy = (int) mfont_get_prop (font, Mresolution); + rface->info = info; +} - sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s", - str[0], str[1], str[2], str[3], str[4], str[5], - size, resy, resy, str[6]); - return 0; + +void +mwin__free_realized_face (MRealizedFace *rface) +{ + if (rface == rface->ascii_rface) + free (rface->info); } -static MFontList * -build_font_list (MFrame *frame, MSymbol family, MSymbol registry, - MPlist *plist) + +void +mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface, + int reverse, + int x, int y, int width, int height, MDrawRegion region) { - char pattern[1024]; - MFontList *font_list; - char **fontnames; - int nfonts; - int i, j; + GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE]; - MSTRUCT_CALLOC (font_list, MERROR_WIN); + if (region) + gc = set_region (frame, gc, region); - if (family == Mnil) - { - sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", - msymbol_name (registry)); - font_list->tag = registry; - } - else - { - sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s", - msymbol_name (family), msymbol_name (registry)); - font_list->tag = family; - } + XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc, + x, y, width, height); +} - fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts); - if (nfonts > 0) + +void mwin__draw_empty_boxes (MDrawWindow win, int x, int y, + MGlyphString *gstring, MGlyph *from, MGlyph *to, + int reverse, MDrawRegion region) +{ + MRealizedFace *rface = from->rface; + Display *display = FRAME_DISPLAY (rface->frame); + GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL]; + + if (from == to) + return; + + if (region) + gc = set_region (rface->frame, gc, region); + for (; from < to; from++) { - MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN); - for (i = j = 0; i < nfonts; i++) - if (mwin__parse_font_name (fontnames[i], font_list->fonts + j) >= 0 - && (font_list->fonts[j].property[MFONT_SIZE] != 0 - || font_list->fonts[j].property[MFONT_RESY] == 0)) - j++; - XFreeFontNames (fontnames); - font_list->nfonts = j; + XDrawRectangle (display, (Window) win, gc, + x, y - gstring->ascent + 1, from->width - 1, + gstring->ascent + gstring->descent - 2); + x += from->width; } - mplist_add (plist, font_list->tag, font_list); - return (nfonts > 0 ? font_list : NULL); } -static MRealizedFont *xfont_select (MFrame *, MFont *, MFont *, int); -static int xfont_open (MRealizedFont *); -static void xfont_close (MRealizedFont *); -static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int); -static unsigned xfont_encode_char (MRealizedFont *, int, unsigned); -static void xfont_render (MDrawWindow, int, int, MGlyphString *, - MGlyph *, MGlyph *, int, MDrawRegion); +void +mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring, + MRealizedFace *rface, int reverse, + int x, int y, int width, MDrawRegion region) +{ + enum MFaceHLineType type = rface->hline->type; + GCInfo *info = rface->info; + GC gc = gc = info->gc[GC_HLINE]; + int i; -static MFontDriver xfont_driver = - { xfont_select, xfont_open, xfont_close, - xfont_find_metric, xfont_encode_char, xfont_render }; + y = (type == MFACE_HLINE_BOTTOM + ? y + gstring->text_descent - rface->hline->width + : type == MFACE_HLINE_UNDER + ? y + 1 + : type == MFACE_HLINE_STRIKE_THROUGH + ? y - ((gstring->ascent + gstring->descent) / 2) + : y - gstring->text_ascent); + if (region) + gc = set_region (frame, gc, region); -/* The X font driver function SELECT. */ + for (i = 0; i < rface->hline->width; i++) + XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc, + x, y + i, x + width - 1, y + i); +} -static MRealizedFont * -xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size) + +void +mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring, + MGlyph *g, int x, int y, int width, MDrawRegion region) { - MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY); - MRealizedFont *rfont; - MFontList *font_list = NULL; + Display *display = FRAME_DISPLAY (frame); + MRealizedFace *rface = g->rface; + MFaceBoxProp *box = rface->box; + GCInfo *info = rface->info; + GC gc_top, gc_left, gc_right, gc_btm; + int y0, y1; int i; - MFont *best_font; - int best_score, score; - if (registry == Mnil - || ! strchr (MSYMBOL_NAME (registry), '-')) - return NULL; + y0 = y - (gstring->text_ascent + + rface->box->inner_vmargin + rface->box->width); + y1 = y + (gstring->text_descent + + rface->box->inner_vmargin + rface->box->width - 1); - /* We handles iso8859-1 and iso10646-1 fonts specially because there - exists so many such fonts. */ - if (registry == M_iso8859_1 || registry == M_iso10646_1) + gc_top = info->gc[GC_BOX_TOP]; + if (region) + gc_top = set_region (frame, gc_top, region); + if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM]) + gc_btm = gc_top; + else + gc_btm = info->gc[GC_BOX_BOTTOM]; + + if (g->type == GLYPH_BOX) { - MPlist *family_list - = (registry == M_iso8859_1 - ? frame->device->display_info->iso8859_1_family_list - : frame->device->display_info->iso10646_1_family_list); - MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY); + int x0, x1; - if (family != Mnil) + if (g->left_padding) + x0 = x + box->outer_hmargin, x1 = x + g->width - 1; + else + x0 = x, x1 = x + g->width - box->outer_hmargin - 1; + + /* Draw the top side. */ + for (i = 0; i < box->width; i++) + XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i); + + /* Draw the bottom side. */ + if (region && gc_btm != gc_top) + gc_btm = set_region (frame, gc_btm, region); + for (i = 0; i < box->width; i++) + XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i); + + if (g->left_padding > 0) { - font_list = (MFontList *) mplist_get (family_list, family); - if (! font_list) - font_list = build_font_list (frame, family, registry, family_list); + /* Draw the left side. */ + if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP]) + gc_left = gc_top; + else + { + gc_left = info->gc[GC_BOX_LEFT]; + if (region) + gc_left = set_region (frame, gc_left, region); + } + for (i = 0; i < rface->box->width; i++) + XDrawLine (display, (Window) win, gc_left, + x0 + i, y0 + i, x0 + i, y1 - i); } - if (! font_list) + else { - family = FONT_PROPERTY (request, MFONT_FAMILY); - font_list = (MFontList *) mplist_get (family_list, family); - if (! font_list) - font_list = build_font_list (frame, family, registry, family_list); + /* Draw the right side. */ + if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP]) + gc_right = gc_top; + else + { + gc_right = info->gc[GC_BOX_RIGHT]; + if (region) + gc_right = set_region (frame, gc_right, region); + } + for (i = 0; i < rface->box->width; i++) + XDrawLine (display, (Window) win, gc_right, + x1 - i, y0 + i, x1 - i, y1 - i); } } - if (! font_list) + else { - MPlist *registry_list - = frame->device->display_info->font_registry_list; + /* Draw the top side. */ + for (i = 0; i < box->width; i++) + XDrawLine (display, (Window) win, gc_top, + x, y0 + i, x + width - 1, y0 + i); - font_list = (MFontList *) mplist_get (registry_list, registry); - if (! font_list) - font_list = build_font_list (frame, Mnil, registry, registry_list); + /* Draw the bottom side. */ + if (region && gc_btm != gc_top) + gc_btm = set_region (frame, gc_btm, region); + for (i = 0; i < box->width; i++) + XDrawLine (display, (Window) win, gc_btm, + x, y1 - i, x + width - 1, y1 - i); } - if (! font_list) - return NULL; +} - for (i = 0, best_score = -1, best_font = NULL; i < font_list->nfonts; i++) - if ((best_score = mfont__score (font_list->fonts + i, spec, request, - limited_size)) >= 0) - break; - if (best_score < 0) - return NULL; - best_font = font_list->fonts + i; - for (; best_score > 0 && i < font_list->nfonts ; i++) - { - score = mfont__score (font_list->fonts + i, spec, request, - limited_size); - if (score >= 0 && score < best_score) - { - best_font = font_list->fonts + i; - best_score = score; - } - } - MSTRUCT_CALLOC (rfont, MERROR_WIN); - rfont->frame = frame; - rfont->spec = *spec; - rfont->request = *request; - rfont->font = *best_font; - if (best_font->property[MFONT_SIZE] == 0) - rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE]; - rfont->score = best_score; - rfont->driver = &xfont_driver; - return rfont; +#if 0 +void +mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface, + int reverse, int x, int y, + int width, int height, int row_bytes, unsigned char *bmp, + MDrawRegion region) +{ + Display *display = FRAME_DISPLAY (frame); + int i, j; + GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL]; + + if (region) + gc = set_region (frame, gc, region); + + for (i = 0; i < height; i++, bmp += row_bytes) + for (j = 0; j < width; j++) + if (bmp[j / 8] & (1 << (7 - (j % 8)))) + XDrawPoint (display, (Window) win, gc, x + j, y + i); } +#endif -typedef struct +void +mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface, + int intensity, MDrawPoint *points, int num, + MDrawRegion region) { - M17NObject control; - MFrame *frame; - XFontStruct *f; -} MXFontInfo; + GCInfo *info = rface->info; + GC gc; -static void -close_xfont (void *object) -{ - MXFontInfo *xfont = (MXFontInfo *) object; + if (! (gc = info->gc[intensity])) + gc = info->gc[intensity] = get_gc_for_anti_alias (FRAME_DEVICE (frame), + info, intensity); + if (region) + gc = set_region (frame, gc, region); - if (xfont->f) - XFreeFont (FRAME_DISPLAY (xfont->frame), xfont->f); - free (object); + XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc, + (XPoint *) points, num, CoordModeOrigin); } -/* The X font driver function OPEN. */ - -static int -xfont_open (MRealizedFont *rfont) +MDrawRegion +mwin__region_from_rect (MDrawMetric *rect) { - char name[1024]; - MXFontInfo *xfont; - MFrame *frame = rfont->frame; - int mdebug_mask = MDEBUG_FONT; + MDrawRegion region1 = XCreateRegion (); + MDrawRegion region2 = XCreateRegion (); + XRectangle xrect; - /* This never fail to generate a valid fontname because open_spec - should correspond to a font available on the system. */ - build_font_name (&rfont->font, name, 1024); - M17N_OBJECT (xfont, close_xfont, MERROR_WIN); - rfont->info = xfont; - xfont->frame = frame; - xfont->f = XLoadQueryFont (FRAME_DISPLAY (frame), name); - if (! xfont->f) - { - rfont->status = -1; - MDEBUG_PRINT1 (" [XFONT] x %s\n", name); - return -1; - } - MDEBUG_PRINT1 (" [XFONT] o %s\n", name); - rfont->status = 1; - rfont->ascent = xfont->f->ascent; - rfont->descent = xfont->f->descent; - return 0; + xrect.x = rect->x; + xrect.y = rect->y; + xrect.width = rect->width; + xrect.height = rect->height; + XUnionRectWithRegion (&xrect, region1, region2); + XDestroyRegion (region1); + return region2; } +void +mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect) +{ + MDrawRegion region1 = XCreateRegion (); + XRectangle xrect; -/* The X font driver function CLOSE. */ + xrect.x = rect->x; + xrect.y = rect->y; + xrect.width = rect->width; + xrect.height = rect->height; -static void -xfont_close (MRealizedFont *rfont) -{ - M17N_OBJECT_UNREF (rfont->info); + XUnionRegion (region, region, region1); + XUnionRectWithRegion (&xrect, region1, region); + XDestroyRegion (region1); } -/* The X font driver function FIND_METRIC. */ - -static void -xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring, - int from, int to) +void +mwin__intersect_region (MDrawRegion region1, MDrawRegion region2) { - MXFontInfo *xfont = (MXFontInfo *) rfont->info; - XFontStruct *f = xfont->f; - MGlyph *g = MGLYPH (from), *gend = MGLYPH (to); - - for (; g != gend; g++) - { - if (g->code == MCHAR_INVALID_CODE) - { - g->lbearing = f->max_bounds.lbearing; - g->rbearing = f->max_bounds.rbearing; - g->width = f->max_bounds.width; - g->ascent = f->ascent; - g->descent = f->descent; - } - else - { - int byte1 = g->code >> 8, byte2 = g->code & 0xFF; - XCharStruct *pcm = NULL; - - if (f->per_char != NULL) - { - if (f->min_byte1 == 0 && f->max_byte1 == 0) - { - if (byte1 == 0 - && byte2 >= f->min_char_or_byte2 - && byte2 <= f->max_char_or_byte2) - pcm = f->per_char + byte2 - f->min_char_or_byte2; - } - else - { - if (byte1 >= f->min_byte1 - && byte1 <= f->max_byte1 - && byte2 >= f->min_char_or_byte2 - && byte2 <= f->max_char_or_byte2) - { - pcm = (f->per_char - + ((f->max_char_or_byte2-f->min_char_or_byte2 + 1) - * (byte1 - f->min_byte1)) - + (byte2 - f->min_char_or_byte2)); - } - } - } + MDrawRegion region = XCreateRegion (); - if (pcm) - { - g->lbearing = pcm->lbearing; - g->rbearing = pcm->rbearing; - g->width = pcm->width; - g->ascent = pcm->ascent; - g->descent = pcm->descent; - } - else - { - /* If the per_char pointer is null, all glyphs between - the first and last character indexes inclusive have - the same information, as given by both min_bounds and - max_bounds. */ - g->lbearing = 0; - g->rbearing = f->max_bounds.width; - g->width = f->max_bounds.width; - g->ascent = f->ascent; - g->descent = f->descent; - } - } - } + XUnionRegion (region1, region1, region); + XIntersectRegion (region, region2, region1); + XDestroyRegion (region); } - -/* The X font driver function ENCODE_CHAR. */ - -static unsigned -xfont_encode_char (MRealizedFont *rfont, int c, unsigned code) +void +mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect) { - MXFontInfo *xfont; - XFontStruct *f; - unsigned min_byte1, max_byte1, min_byte2, max_byte2; - int all_chars_exist; - - if (rfont->status < 0 || code >= 0x10000) - return MCHAR_INVALID_CODE; - if (rfont->status == 0) - { - if (xfont_open (rfont) < 0) - return MCHAR_INVALID_CODE; - } - xfont = (MXFontInfo *) rfont->info; - f = xfont->f; - all_chars_exist = (! f->per_char || f->all_chars_exist == True); - min_byte1 = f->min_byte1; - max_byte1 = f->max_byte1; - min_byte2 = f->min_char_or_byte2; - max_byte2 = f->max_char_or_byte2; - - if (min_byte1 == 0 && max_byte1 == 0) - { - XCharStruct *pcm; + MDrawRegion region1 = XCreateRegion (); + XRectangle xrect; - if (code < min_byte2 || code > max_byte2) - return MCHAR_INVALID_CODE; - if (all_chars_exist) - return code; - pcm = f->per_char + (code - min_byte2); - return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing) - ? code : MCHAR_INVALID_CODE); - } - else - { - unsigned byte1 = code >> 8, byte2 = code & 0xFF; - XCharStruct *pcm; + xrect.x = rect->x; + xrect.y = rect->y; + xrect.width = rect->width; + xrect.height = rect->height; + XUnionRectWithRegion (&xrect, region1, region); + XDestroyRegion (region1); +} - if (byte1 < min_byte1 || byte1 > max_byte1 - || byte2 < min_byte2 || byte2 > max_byte2) - return MCHAR_INVALID_CODE; +void +mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect) +{ + XRectangle xrect; - if (all_chars_exist) - return code; - pcm = f->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1) - + (byte2 - min_byte2)); - return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing) - ? code : MCHAR_INVALID_CODE); - } + XClipBox (region, &xrect); + rect->x = xrect.x; + rect->y = xrect.y; + rect->width = xrect.width; + rect->height = xrect.height; } -static GC -set_region (MFrame *frame, GC gc, MDrawRegion region) +void +mwin__free_region (MDrawRegion region) { - unsigned long valuemask = GCForeground; + XDestroyRegion (region); +} - XCopyGC (FRAME_DISPLAY (frame), gc, valuemask, - frame->device->scratch_gc); - XSetRegion (FRAME_DISPLAY (frame), frame->device->scratch_gc, region); - return frame->device->scratch_gc; +void +mwin__dump_region (MDrawRegion region) +{ + XRectangle rect; + XClipBox (region, &rect); + fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height); } -/* The X font driver function RENDER. */ -static void -xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring, - MGlyph *from, MGlyph *to, int reverse, MDrawRegion region) +MDrawWindow +mwin__create_window (MFrame *frame, MDrawWindow parent) { - MRealizedFace *rface = from->rface; - Display *display; - XChar2b *code; - GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL]; - MGlyph *g; - int i; + Display *display = FRAME_DISPLAY (frame); + Window win; + XWMHints wm_hints = { InputHint, False }; + XClassHint class_hints = { "M17N-IM", "m17n-im" }; + XSetWindowAttributes set_attrs; + unsigned long mask; + XGCValues values; + GCInfo *info = frame->rface->info; - if (from == to) - return; + if (! parent) + parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame)); + mask = GCForeground; + XGetGCValues (display, info->gc[GC_INVERSE], mask, &values); + set_attrs.background_pixel = values.foreground; + set_attrs.backing_store = Always; + set_attrs.override_redirect = True; + set_attrs.save_under = True; + mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder; + win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0, + CopyFromParent, InputOutput, CopyFromParent, + mask, &set_attrs); + XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0, + NULL, &wm_hints, &class_hints); + XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask); + return (MDrawWindow) win; +} - /* It is assured that the all glyphs in the current range use the - same realized face. */ - display = FRAME_DISPLAY (rface->frame); +void +mwin__destroy_window (MFrame *frame, MDrawWindow win) +{ + XDestroyWindow (FRAME_DISPLAY (frame), (Window) win); +} - if (region) - gc = set_region (rface->frame, gc, region); - if (! rface->rfont || from->code == MCHAR_INVALID_CODE) - { - int x0 = x; +#if 0 +MDrawWindow +mwin__event_window (void *event) +{ + return ((MDrawWindow) ((XEvent *) event)->xany.window); +} - for (; from < to; from++) - { - XDrawRectangle (display, (Window) win, gc, - x0, y - gstring->ascent + 1, from->width - 1, - gstring->ascent + gstring->descent - 2); - x0 += from->width; - } - return; - } +void +mwin__print_event (void *arg, char *win_name) +{ + char *event_name; + XEvent *event = (XEvent *) arg; - XSetFont (display, gc, ((MXFontInfo *) (rface->rfont->info))->f->fid); - code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from)); - for (i = 0, g = from; g < to; i++, g++) + switch (event->xany.type) { - code[i].byte1 = g->code >> 8; - code[i].byte2 = g->code & 0xFF; + case 2: event_name = "KeyPress"; break; + case 3: event_name = "KeyRelease"; break; + case 4: event_name = "ButtonPress"; break; + case 5: event_name = "ButtonRelease"; break; + case 6: event_name = "MotionNotify"; break; + case 7: event_name = "EnterNotify"; break; + case 8: event_name = "LeaveNotify"; break; + case 9: event_name = "FocusIn"; break; + case 10: event_name = "FocusOut"; break; + case 11: event_name = "KeymapNotify"; break; + case 12: event_name = "Expose"; break; + case 13: event_name = "GraphicsExpose"; break; + case 14: event_name = "NoExpose"; break; + case 15: event_name = "VisibilityNotify"; break; + case 16: event_name = "CreateNotify"; break; + case 17: event_name = "DestroyNotify"; break; + case 18: event_name = "UnmapNotify"; break; + case 19: event_name = "MapNotify"; break; + case 20: event_name = "MapRequest"; break; + case 21: event_name = "ReparentNotify"; break; + case 22: event_name = "ConfigureNotify"; break; + case 23: event_name = "ConfigureRequest"; break; + case 24: event_name = "GravityNotify"; break; + case 25: event_name = "ResizeRequest"; break; + case 26: event_name = "CirculateNotify"; break; + case 27: event_name = "CirculateRequest"; break; + case 28: event_name = "PropertyNotify"; break; + case 29: event_name = "SelectionClear"; break; + case 30: event_name = "SelectionRequest"; break; + case 31: event_name = "SelectionNotify"; break; + case 32: event_name = "ColormapNotify"; break; + case 33: event_name = "ClientMessage"; break; + case 34: event_name = "MappingNotify"; break; + default: event_name = "unknown"; } - g = from; - while (g < to) - { - if (g->type == GLYPH_PAD) - x += g++->width; - else if (g->type == GLYPH_SPACE) - for (; g < to && g->type == GLYPH_SPACE; g++) - x += g->width; - else if (! g->rface->rfont) - { - if ((g->c >= 0x200B && g->c <= 0x200F) - || (g->c >= 0x202A && g->c <= 0x202E)) - x += g++->width; - else - { - /* As a font is not found for this character, draw an - empty box. */ - int box_width = g->width; - int box_height = gstring->ascent + gstring->descent; - - if (box_width > 4) - box_width -= 2; - if (box_height > 4) - box_height -= 2; - XDrawRectangle (display, (Window) win, gc, - x, y - gstring->ascent, box_width, box_height); - x += g++->width; - } - } - else if (g->xoff != 0 || g->yoff != 0 || g->right_padding) - { - XDrawString16 (display, (Window) win, gc, - x + g->xoff, y + g->yoff, code + (g - from), 1); - x += g->width; - g++; - } - else - { - int orig_x = x; - int code_idx = g - from; + fprintf (stderr, "%s: %s\n", win_name, event_name); +} +#endif - for (i = 0; - g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0; - i++, g++) - x += g->width; - XDrawString16 (display, (Window) win, gc, orig_x, y, - code + code_idx, i); - } - } +void +mwin__map_window (MFrame *frame, MDrawWindow win) +{ + XMapRaised (FRAME_DISPLAY (frame), (Window) win); } - -/* Xft Handler */ +void +mwin__unmap_window (MFrame *frame, MDrawWindow win) +{ + XUnmapWindow (FRAME_DISPLAY (frame), (Window) win); +} -#ifdef HAVE_XFT2 +void +mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win, + MDrawMetric *geometry) +{ + Display *display = FRAME_DISPLAY (frame); + XWindowAttributes attr; + Window parent = (Window) parent_win, root; -typedef struct { - M17NObject control; - MFrame *frame; - XftFont *font_aa; - XftFont *font_no_aa; -} MXftFontInfo; + XGetWindowAttributes (display, (Window) win, &attr); + geometry->x = attr.x + attr.border_width; + geometry->y = attr.y + attr.border_width; + geometry->width = attr.width; + geometry->height = attr.height; -static MRealizedFont *xft_select (MFrame *, MFont *, MFont *, int); -static int xft_open (MRealizedFont *); -static void xft_close (MRealizedFont *); -static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int); -static void xft_render (MDrawWindow, int, int, MGlyphString *, - MGlyph *, MGlyph *, int, MDrawRegion); + if (! parent) + parent = RootWindow (display, FRAME_SCREEN (frame)); + while (1) + { + Window this_parent, *children; + unsigned n; -MFontDriver xft_driver = - { xft_select, xft_open, xft_close, - xft_find_metric, - NULL, /* Set to ft_encode_char in mwin__init (). */ - xft_render }; + XQueryTree (display, (Window) win, &root, &this_parent, &children, &n); + if (children) + XFree (children); + if (this_parent == parent || this_parent == root) + break; + win = (MDrawWindow) this_parent; + XGetWindowAttributes (display, (Window) win, &attr); + geometry->x += attr.x + attr.border_width; + geometry->y += attr.y + attr.border_width; + } +} -static MRealizedFont * -xft_select (MFrame *frame, MFont *spec, MFont *request, int limited_size) +void +mwin__adjust_window (MFrame *frame, MDrawWindow win, + MDrawMetric *current, MDrawMetric *new) { - MRealizedFont *rfont; + Display *display = FRAME_DISPLAY (frame); + unsigned int mask = 0; + XWindowChanges values; - rfont = (mfont__ft_driver.select) (frame, spec, request, limited_size); - if (rfont) - rfont->driver = &xft_driver; - return rfont; + if (current->width != new->width) + { + mask |= CWWidth; + if (new->width <= 0) + new->width = 1; + values.width = current->width = new->width; + } + if (current->height != new->height) + { + mask |= CWHeight; + if (new->height <= 0) + new->height = 1; + values.height = current->height = new->height; + } + if (current->x != new->x) + { + mask |= CWX; + values.x = current->x = new->x; + } + if (current->y != new->y) + { + mask |= CWY; + current->y = new->y; + values.y = current->y = new->y; + } + if (mask) + XConfigureWindow (display, (Window) win, mask, &values); + XClearWindow (display, (Window) win); } - -static void -close_xft (void *object) +MSymbol +mwin__parse_event (MFrame *frame, void *arg, int *modifiers) { - MXftFontInfo *font_info = object; + XEvent *event = (XEvent *) arg; + MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info; + int len; + char buf[512]; + KeySym keysym; + MSymbol key; - if (font_info->font_aa) - XftFontClose (FRAME_DISPLAY (font_info->frame), font_info->font_aa); - if (font_info->font_no_aa) - XftFontClose (FRAME_DISPLAY (font_info->frame), font_info->font_no_aa); - free (object); -} + *modifiers = 0; + if (event->xany.type != KeyPress + /* && event->xany.type != KeyRelease */ + ) + return Mnil; + len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL); + if (len > 1) + return Mnil; + if (len == 1) + { + int c = keysym; + if (c < XK_space || c > XK_asciitilde) + c = buf[0]; + if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask) + *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; + if (((XKeyEvent *) event)->state & ControlMask) + { + if (c >= 'a' && c <= 'z') + c += 'A' - 'a'; + if (c >= ' ' && c < 127) + *modifiers |= MINPUT_KEY_CONTROL_MODIFIER; + } + key = minput__char_to_key (c); + } + else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R) + return Mnil; + else + { + char *str = XKeysymToString (keysym); -static XftFont * -xft_open_font (MFrame *frame, MFTInfo *ft_info, int size, int anti_alias) -{ - XftPattern *pattern; - XftFontInfo *xft_font_info; - XftFont *font; + if (! str) + return Mnil; + key = msymbol (str); + if (((XKeyEvent *) event)->state & ShiftMask) + *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; + if (((XKeyEvent *) event)->state & ControlMask) + *modifiers |= MINPUT_KEY_CONTROL_MODIFIER; + } + if (((XKeyEvent *) event)->state & disp_info->meta_mask) + *modifiers |= MINPUT_KEY_META_MODIFIER; + if (((XKeyEvent *) event)->state & disp_info->alt_mask) + *modifiers |= MINPUT_KEY_ALT_MODIFIER; + if (((XKeyEvent *) event)->state & disp_info->super_mask) + *modifiers |= MINPUT_KEY_SUPER_MODIFIER; + if (((XKeyEvent *) event)->state & disp_info->hyper_mask) + *modifiers |= MINPUT_KEY_HYPER_MODIFIER; - pattern = XftPatternCreate (); - XftPatternAddString (pattern, XFT_FILE, ft_info->filename); - XftPatternAddDouble (pattern, XFT_PIXEL_SIZE, (double) size); - XftPatternAddBool (pattern, XFT_ANTIALIAS, anti_alias); - xft_font_info = XftFontInfoCreate (FRAME_DISPLAY (frame), pattern); - if (! xft_font_info) - return NULL; - font = XftFontOpenInfo (FRAME_DISPLAY (frame), pattern, xft_font_info); - XftFontInfoDestroy (FRAME_DISPLAY (frame), xft_font_info); - return font; + return key; } -static int -xft_open (MRealizedFont *rfont) +MText * +mwin__get_selection_text (MFrame *frame) { - MFrame *frame; - MFTInfo *ft_info; - MXftFontInfo *font_info; - int size; + return NULL; +} - if ((mfont__ft_driver.open) (rfont) < 0) - return -1; - size = rfont->font.property[MFONT_SIZE] / 10; - frame = rfont->frame; +void +mwin__dump_gc (MFrame *frame, MRealizedFace *rface) +{ + unsigned long valuemask = GCForeground | GCBackground | GCClipMask; + XGCValues values; + Display *display = FRAME_DISPLAY (frame); + GCInfo *info = rface->info; + int i; - ft_info = rfont->info; - M17N_OBJECT (font_info, close_xft, MERROR_WIN); - ft_info->extra_info = font_info; - font_info->frame = frame; - font_info->font_aa = xft_open_font (frame, ft_info, size, 1); - if (font_info->font_aa) + for (i = 0; i <= GC_INVERSE; i++) { - font_info->font_no_aa = xft_open_font (frame, ft_info, size, 0); - if (font_info->font_no_aa) - return 0; + XGetGCValues (display, info->gc[i], valuemask, &values); + fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i, + values.foreground, values.background); + fprintf (stderr, "\n"); } - M17N_OBJECT_UNREF (font_info); - ft_info->extra_info = NULL; - rfont->status = -1; - return -1; } +static MDeviceDriver x_driver = + { + mwin__close_device, + mwin__device_get_prop, + mwin__realize_face, + mwin__free_realized_face, + mwin__fill_space, + mwin__draw_empty_boxes, + mwin__draw_hline, + mwin__draw_box, + mwin__draw_points, + mwin__region_from_rect, + mwin__union_rect_with_region, + mwin__intersect_region, + mwin__region_add_rect, + mwin__region_to_rect, + mwin__free_region, + mwin__dump_region, + mwin__create_window, + mwin__destroy_window, + mwin__map_window, + mwin__unmap_window, + mwin__window_geometry, + mwin__adjust_window, + mwin__parse_event + }; -static void -xft_close (MRealizedFont *rfont) -{ - M17N_OBJECT_UNREF (rfont->info); -} - - -static void -xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring, - int from, int to) -{ - MFTInfo *ft_info = rfont->info; - MXftFontInfo *font_info = ft_info->extra_info; - FT_Face ft_face = ft_info->ft_face; - MGlyph *g = MGLYPH (from), *gend = MGLYPH (to); - - for (; g != gend; g++) - { - if (g->code == MCHAR_INVALID_CODE) - { - MGlyph *start = g++; - - while (g != gend && g->code == MCHAR_INVALID_CODE) g++; - (mfont__ft_driver.find_metric) (rfont, gstring, GLYPH_INDEX (start), - GLYPH_INDEX (g)); - g--; - } - else - { - XGlyphInfo extents; - unsigned code; - - if (g->otf_encoded) - code = g->code; - else - code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code); + +/** X font handler */ - XftGlyphExtents (FRAME_DISPLAY (font_info->frame), - font_info->font_aa, &code, 1, &extents); - g->lbearing = extents.x; - g->rbearing = extents.width - extents.x; - g->width = extents.xOff; - g->ascent = extents.y; - g->descent = extents.height - extents.y; - } - } -} +static MRealizedFont *xfont_select (MFrame *, MFont *, MFont *, int); +static int xfont_open (MRealizedFont *); +static void xfont_find_metric (MRealizedFont *, MGlyphString *, int, int); +static unsigned xfont_encode_char (MRealizedFont *, int, unsigned); +static void xfont_render (MDrawWindow, int, int, MGlyphString *, + MGlyph *, MGlyph *, int, MDrawRegion); +static MFont *xfont_parse_name (char *name, MFont *font); +static char *xfont_build_name (MFont *font); +static MFontDriver xfont_driver = + { xfont_select, xfont_open, + xfont_find_metric, xfont_encode_char, xfont_render, + xfont_parse_name, xfont_build_name }; -void -xft_render (MDrawWindow win, int x, int y, - MGlyphString *gstring, MGlyph *from, MGlyph *to, - int reverse, MDrawRegion region) +typedef struct { - MRealizedFace *rface = from->rface; - MFrame *frame = rface->frame; - MFTInfo *ft_info = rface->rfont->info; - MXftFontInfo *font_info = ft_info->extra_info; - FT_Face ft_face = ft_info->ft_face; - XftDraw *xft_draw = frame->device->xft_draw; - XftColor *xft_color = (! reverse - ? &((GCInfo *) rface->info)->xft_color_fore - : &((GCInfo *) rface->info)->xft_color_back); - XftFont *xft_font = (gstring->control.anti_alias && frame->device->depth > 1 - ? font_info->font_aa : font_info->font_no_aa); - MGlyph *g; - FT_UInt *glyphs; - int last_x; - int nglyphs; - - if (from == to) - return; - - XftDrawChange (xft_draw, (Drawable) win); - XftDrawSetClip (xft_draw, (Region) region); - - glyphs = alloca (sizeof (FT_UInt) * (to - from)); - for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width) - { - unsigned code; - - if (g->otf_encoded) - code = g->code; - else - code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code); - if (g->xoff == 0 && g->yoff == 0) - glyphs[nglyphs++] = code; - else - { - if (nglyphs > 0) - XftDrawGlyphs (xft_draw, xft_color, xft_font, - last_x, y, glyphs, nglyphs); - nglyphs = 0; - XftDrawGlyphs (xft_draw, xft_color, xft_font, - x + g->xoff, y + g->yoff, (FT_UInt *) &code, 1); - last_x = x + g->width; - } - } - if (nglyphs > 0) - XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs); -} - -#endif + M17NObject control; + Display *display; + XFontStruct *xfont; +} MXFontInfo; - +/** Indices to each field of split font name. */ -/* XIM (X Input Method) handler */ +enum xlfd_field_idx + { + XLFD_FOUNDRY, + XLFD_FAMILY, + XLFD_WEIGHT, + XLFD_SLANT, + XLFD_SWIDTH, + XLFD_ADSTYLE, + XLFD_PIXEL, + XLFD_POINT, + XLFD_RESX, + XLFD_RESY, + XLFD_SPACING, + XLFD_AVGWIDTH, + XLFD_REGISTRY, + XLFD_ENCODING, + /* anchor */ + XLFD_FIELD_MAX + }; -typedef struct MInputXIMMethodInfo -{ - Display *display; - XIM xim; - MSymbol language; - MSymbol coding; -} MInputXIMMethodInfo; +/** Split the fontname NAME into each XLFD field destructively. Set + each element of the table pointed by PROPERTY_IDX to a pointer to + the corresponding font property name. Store the point size and + the resolution-Y of the font to the place pointed by POINT and + RESY respectively. -typedef struct MInputXIMContextInfo -{ - XIC xic; - Window win; - MConverter *converter; -} MInputXIMContextInfo; + If NAME does not contain all XLFD fields, the unspecified fields is + treated as wild cards. */ static int -xim_open_im (MInputMethod *im) +split_font_name (char *name, char **field, + unsigned short *size, unsigned short *resy) { - MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg; - MLocale *saved, *this; - char *save_modifier_list; - XIM xim; - MInputXIMMethodInfo *im_info; + int i; + char *p; - saved = mlocale_set (LC_CTYPE, NULL); - this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : ""); - if (! this) - /* The specified locale is not supported. */ - MERROR (MERROR_LOCALE, -1); - if (mlocale_get_prop (this, Mcoding) == Mnil) + for (i = 0, p = name; *p; p++) { - /* Unable to decode the output of XIM. */ - mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); - MERROR (MERROR_LOCALE, -1); + *p = tolower (*p); + if (*p == '-' && i < XLFD_FIELD_MAX) + { + field[i] = p + 1; + if (i != XLFD_ENCODING) + *p = '\0'; + i++; + } } + if (i < XLFD_REGISTRY) + return -1; + for (; i < XLFD_FIELD_MAX; i++) + field[i] = "*"; - if (arg->modifier_list) - save_modifier_list = XSetLocaleModifiers (arg->modifier_list); + if (*(field[XLFD_RESY]) == '*') + *resy = 0; else - save_modifier_list = XSetLocaleModifiers (""); - if (! save_modifier_list) + *resy = atoi (field[XLFD_RESY]); + if (*(field[XLFD_PIXEL]) == '*') { - /* The specified locale is not supported by X. */ - mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); - MERROR (MERROR_LOCALE, -1); + if (*(field[XLFD_POINT]) != '*') + *size = atoi (field[XLFD_POINT]) * *resy / 72; + else + *size = 0; } + else if (*(field[XLFD_PIXEL]) == '[') + { + /* The pixel size field specifies a transformation matrix of the + form "[A B C D]". The XLFD spec says that the scalar value N + for the pixel size is equivalent to D. */ + char *p0 = field[XLFD_PIXEL] + 1, *p1; + double d; - xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class); - if (! xim) + for (i = 0; i < 4; i++, p0 = p1) + d = strtod (p0, &p1); + *size = d * 10; + } + else + *size = atoi (field[XLFD_PIXEL]) * 10; + if (*size == 0 && *(field[XLFD_POINT]) != '*') { - /* No input method is available in the current locale. */ - XSetLocaleModifiers (save_modifier_list); - mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); - MERROR (MERROR_WIN, -1); + *size = atoi (field[XLFD_POINT]); + if (*resy) + *size = *size * *resy / 72; + else + *size = *size * 100 / 72; } - MSTRUCT_MALLOC (im_info, MERROR_WIN); - im_info->display = arg->display; - im_info->xim = xim; - im_info->language = mlocale_get_prop (this, Mlanguage); - im_info->coding = mlocale_get_prop (this, Mcoding); - im->info = im_info; - - XSetLocaleModifiers (save_modifier_list); - mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); - return 0; } -static void -xim_close_im (MInputMethod *im) -{ - MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info; - - XCloseIM (im_info->xim); - free (im_info); -} - -static int -xim_create_ic (MInputContext *ic) +char * +build_font_name (MFont *font, char *name, int limit) { - MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg; - MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info; - MInputXIMContextInfo *ic_info; - XIC xic; + MSymbol prop[7]; + char *str[7]; + int len, i; + unsigned short size, resy; - if (! arg->input_style) - { - /* By default, use Root style. */ - arg->input_style = XIMPreeditNothing | XIMStatusNothing; - arg->preedit_attrs = NULL; - arg->status_attrs = NULL; + prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry); + prop[1] = (MSymbol) mfont_get_prop (font, Mfamily); + prop[2] = (MSymbol) mfont_get_prop (font, Mweight); + prop[3] = (MSymbol) mfont_get_prop (font, Mstyle); + prop[4] = (MSymbol) mfont_get_prop (font, Mstretch); + prop[5] = (MSymbol) mfont_get_prop (font, Madstyle); + prop[6] = (MSymbol) mfont_get_prop (font, Mregistry); + for (len = 0, i = 0; i < 7; i++) + { + if (prop[i] != Mnil) + { + str[i] = msymbol_name (prop[i]); + len += strlen (str[i]); + } + else + { + str[i] = "*"; + len++; + } } + if ((len + + 12 /* 12 dashes */ + + 3 /* 3 asterisks */ + + 30 /* 3 integers (each 10 digits) */ + + 1) /* '\0' terminal */ + > limit) + return NULL; - if (! arg->preedit_attrs && ! arg->status_attrs) - xic = XCreateIC (im_info->xim, - XNInputStyle, arg->input_style, - XNClientWindow, arg->client_win, - XNFocusWindow, arg->focus_win, - NULL); - else if (arg->preedit_attrs && ! arg->status_attrs) - xic = XCreateIC (im_info->xim, - XNInputStyle, arg->input_style, - XNClientWindow, arg->client_win, - XNFocusWindow, arg->focus_win, - XNPreeditAttributes, arg->preedit_attrs, - NULL); - else if (! arg->preedit_attrs && arg->status_attrs) - xic = XCreateIC (im_info->xim, - XNInputStyle, arg->input_style, - XNClientWindow, arg->client_win, - XNFocusWindow, arg->focus_win, - XNStatusAttributes, arg->status_attrs, - NULL); + size = (int) mfont_get_prop (font, Msize); + if ((size % 10) < 5) + size /= 10; else - xic = XCreateIC (im_info->xim, - XNInputStyle, arg->input_style, - XNClientWindow, arg->client_win, - XNFocusWindow, arg->focus_win, - XNPreeditAttributes, arg->preedit_attrs, - XNStatusAttributes, arg->status_attrs, - NULL); - if (! xic) - MERROR (MERROR_WIN, -1); + size = size / 10 + 1; + resy = (int) mfont_get_prop (font, Mresolution); - MSTRUCT_MALLOC (ic_info, MERROR_WIN); - ic_info->xic = xic; - ic_info->win = arg->focus_win; - ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0); - ic->info = ic_info; - return 0; + sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s", + str[0], str[1], str[2], str[3], str[4], str[5], + size, resy, resy, str[6]); + return name; } -static void -xim_destroy_ic (MInputContext *ic) +static MFontList * +build_font_list (MFrame *frame, MSymbol family, MSymbol registry, + MPlist *plist) { - MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info; + char pattern[1024]; + MFontList *font_list; + char **fontnames; + int nfonts; + int i, j; - XDestroyIC (ic_info->xic); - mconv_free_converter (ic_info->converter); - free (ic_info); - ic->info = NULL; -} + MSTRUCT_CALLOC (font_list, MERROR_WIN); -static int -xim_filter (MInputContext *ic, MSymbol key, void *event) -{ - MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info; + if (family == Mnil) + { + sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s", + msymbol_name (registry)); + font_list->tag = registry; + } + else + { + sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s", + msymbol_name (family), msymbol_name (registry)); + font_list->tag = family; + } - return (XFilterEvent ((XEvent *) event, ic_info->win) == True); + fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts); + if (nfonts > 0) + { + MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN); + for (i = j = 0; i < nfonts; i++) + if (xfont_parse_name (fontnames[i], font_list->fonts + j) + && (font_list->fonts[j].property[MFONT_SIZE] != 0 + || font_list->fonts[j].property[MFONT_RESY] == 0)) + j++; + XFreeFontNames (fontnames); + font_list->nfonts = j; + } + mplist_add (plist, font_list->tag, font_list); + return (nfonts > 0 ? font_list : NULL); } +/* The X font driver function SELECT. */ -static int -xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt) +static MRealizedFont * +xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size) { - MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info; - MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info; - XKeyPressedEvent *ev = (XKeyPressedEvent *) arg; - KeySym keysym; - Status status; - char *buf; - int len; + MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY); + MRealizedFont *rfont; + MFontList *font_list = NULL; + int i; + MFont *best_font; + int best_score, score; - buf = (char *) alloca (512); - len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status); - if (status == XBufferOverflow) + if (registry == Mnil + || ! strchr (MSYMBOL_NAME (registry), '-')) + return NULL; + + /* We handles iso8859-1 and iso10646-1 fonts specially because there + exists so many such fonts. */ + if (registry == M_iso8859_1 || registry == M_iso10646_1) { - buf = (char *) alloca (len); - len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status); + MPlist *family_list + = (registry == M_iso8859_1 + ? FRAME_DEVICE (frame)->display_info->iso8859_1_family_list + : FRAME_DEVICE (frame)->display_info->iso10646_1_family_list); + MSymbol family = FONT_PROPERTY (spec, MFONT_FAMILY); + + if (family != Mnil) + { + font_list = (MFontList *) mplist_get (family_list, family); + if (! font_list) + font_list = build_font_list (frame, family, registry, family_list); + } + if (! font_list) + { + family = FONT_PROPERTY (request, MFONT_FAMILY); + font_list = (MFontList *) mplist_get (family_list, family); + if (! font_list) + font_list = build_font_list (frame, family, registry, family_list); + } } + if (! font_list) + { + MPlist *registry_list + = FRAME_DEVICE (frame)->display_info->font_registry_list; - mtext_reset (ic->produced); - if (len == 0) - return 1; + font_list = (MFontList *) mplist_get (registry_list, registry); + if (! font_list) + font_list = build_font_list (frame, Mnil, registry, registry_list); + } + if (! font_list) + return NULL; - mconv_reset_converter (ic_info->converter); - mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len); - mconv_decode (ic_info->converter, ic->produced); - mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced), - Mlanguage, (void *) im_info->language); - mtext_cpy (mt, ic->produced); - mtext_reset (ic->produced); - return 0; + for (i = 0, best_score = -1, best_font = NULL; i < font_list->nfonts; i++) + if ((best_score = mfont__score (font_list->fonts + i, spec, request, + limited_size)) >= 0) + break; + if (best_score < 0) + return NULL; + best_font = font_list->fonts + i; + for (; best_score > 0 && i < font_list->nfonts ; i++) + { + score = mfont__score (font_list->fonts + i, spec, request, + limited_size); + if (score >= 0 && score < best_score) + { + best_font = font_list->fonts + i; + best_score = score; + } + } + + MSTRUCT_CALLOC (rfont, MERROR_WIN); + rfont->frame = frame; + rfont->spec = *spec; + rfont->request = *request; + rfont->font = *best_font; + if (best_font->property[MFONT_SIZE] == 0) + rfont->font.property[MFONT_SIZE] = request->property[MFONT_SIZE]; + rfont->score = best_score; + return rfont; } - -#ifdef X_SET_ERROR_HANDLER -static int -x_error_handler (Display *display, XErrorEvent *error) +/* The X font driver function CLOSE. */ + +static void +close_xfont (void *object) { - mdebug_hook (); - return 0; + MXFontInfo *xfont_info = object; + + XFreeFont (xfont_info->display, xfont_info->xfont); + free (object); } + +/* The X font driver function OPEN. */ + static int -x_io_error_handler (Display *display) +xfont_open (MRealizedFont *rfont) { - mdebug_hook (); + char name[1024]; + MXFontInfo *xfont_info; + MFrame *frame = rfont->frame; + int mdebug_mask = MDEBUG_FONT; + + /* This never fail to generate a valid fontname because open_spec + should correspond to a font available on the system. */ + build_font_name (&rfont->font, name, 1024); + M17N_OBJECT (xfont_info, close_xfont, MERROR_WIN); + xfont_info->display = FRAME_DISPLAY (frame); + xfont_info->xfont = XLoadQueryFont (FRAME_DISPLAY (frame), name); + if (! xfont_info->xfont) + { + rfont->status = -1; + free (xfont_info); + MDEBUG_PRINT1 (" [XFONT] x %s\n", name); + return -1; + } + rfont->info = xfont_info; + MDEBUG_PRINT1 (" [XFONT] o %s\n", name); + rfont->status = 1; + rfont->ascent = xfont_info->xfont->ascent; + rfont->descent = xfont_info->xfont->descent; return 0; } -#endif - - -int -mwin__init () -{ - Mdisplay = msymbol ("display"); - Mscreen = msymbol ("screen"); - Mdrawable = msymbol ("drawable"); - Mdepth = msymbol ("depth"); - Mwidget = msymbol ("widget"); - M_iso8859_1 = msymbol ("iso8859-1"); - M_iso10646_1 = msymbol ("iso10646-1"); - display_info_list = mplist (); - device_list = mplist (); +/* The X font driver function FIND_METRIC. */ - mplist_add (mfont__driver_list, msymbol ("x"), &xfont_driver); -#ifdef HAVE_XFT2 - xft_driver.encode_char = mfont__ft_driver.encode_char; - mplist_put (mfont__driver_list, msymbol ("freetype"), &xft_driver); -#endif - - Mxim = msymbol ("xim"); - msymbol_put (Mxim, Minput_driver, &minput_xim_driver); - - return 0; -} - -void -mwin__fini () -{ - M17N_OBJECT_UNREF (display_info_list); - M17N_OBJECT_UNREF (device_list); -} - -int -mwin__parse_font_name (char *name, MFont *font) +static void +xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring, + int from, int to) { - char *field[XLFD_FIELD_MAX]; - unsigned short size, resy; - MSymbol attrs[MFONT_PROPERTY_MAX]; - char *copy = (char *) alloca (512); - int i, len; - char *p, *last = NULL; + MXFontInfo *xfont_info = rfont->info; + XFontStruct *xfont = xfont_info->xfont; + MGlyph *g = MGLYPH (from), *gend = MGLYPH (to); - len = strlen (name) + 1; - for (i = 0, p = name; *p; p++) - { - if (*p == '-') - i++; - else if (p > name && *p == '*' && p[-1] == '-') - last = p + 1; - } - if (i == 14) - memcpy (copy, name, len); - else if (last) + for (; g != gend; g++) { - memcpy (copy, name, last - name); - for (; i < 14; i++) - strcat (copy, "-*"); - strcat (copy, last); - } - - if (split_font_name (copy, field, &size, &resy) < 0) - return -1; - attrs[MFONT_FOUNDRY] - = *(field[XLFD_FOUNDRY]) != '*' ? msymbol (field[XLFD_FOUNDRY]) : Mnil; - attrs[MFONT_FAMILY] - = *(field[XLFD_FAMILY]) != '*' ? msymbol (field[XLFD_FAMILY]) : Mnil; - attrs[MFONT_WEIGHT] - = *(field[XLFD_WEIGHT]) != '*' ? msymbol (field[XLFD_WEIGHT]) : Mnil; - attrs[MFONT_STYLE] - = *(field[XLFD_SLANT]) != '*' ? msymbol (field[XLFD_SLANT]) : Mnil; - attrs[MFONT_STRETCH] - = *(field[XLFD_SWIDTH]) != '*' ? msymbol (field[XLFD_SWIDTH]) : Mnil; - attrs[MFONT_ADSTYLE] - = *(field[XLFD_ADSTYLE]) != '*' ? msymbol (field[XLFD_ADSTYLE]) : Mnil; - attrs[MFONT_REGISTRY] - = *(field[XLFD_REGISTRY]) != '*' ? msymbol (field[XLFD_REGISTRY]) : Mnil; - mfont__set_spec (font, attrs, size, resy); - return 0; -} - + if (g->code == MCHAR_INVALID_CODE) + { + g->lbearing = xfont->max_bounds.lbearing; + g->rbearing = xfont->max_bounds.rbearing; + g->width = xfont->max_bounds.width; + g->ascent = xfont->ascent; + g->descent = xfont->descent; + } + else + { + int byte1 = g->code >> 8, byte2 = g->code & 0xFF; + XCharStruct *pcm = NULL; -char * -mwin__build_font_name (MFont *font) -{ - char name[1024]; + if (xfont->per_char != NULL) + { + if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0) + { + if (byte1 == 0 + && byte2 >= xfont->min_char_or_byte2 + && byte2 <= xfont->max_char_or_byte2) + pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2; + } + else + { + if (byte1 >= xfont->min_byte1 + && byte1 <= xfont->max_byte1 + && byte2 >= xfont->min_char_or_byte2 + && byte2 <= xfont->max_char_or_byte2) + { + pcm = (xfont->per_char + + ((xfont->max_char_or_byte2 + - xfont->min_char_or_byte2 + 1) + * (byte1 - xfont->min_byte1)) + + (byte2 - xfont->min_char_or_byte2)); + } + } + } - if (build_font_name (font, name, 1024) < 0) - return NULL; - return strdup (name); + if (pcm) + { + g->lbearing = pcm->lbearing; + g->rbearing = pcm->rbearing; + g->width = pcm->width; + g->ascent = pcm->ascent; + g->descent = pcm->descent; + } + else + { + /* If the per_char pointer is null, all glyphs between + the first and last character indexes inclusive have + the same information, as given by both min_bounds and + max_bounds. */ + g->lbearing = 0; + g->rbearing = xfont->max_bounds.width; + g->width = xfont->max_bounds.width; + g->ascent = xfont->ascent; + g->descent = xfont->descent; + } + } + } } -/** Return an MWDevice object corresponding to a display specified in - PLIST. - It searches device_list for a device matching the display. If - found, return the found object. Otherwise, return a newly created - object. */ +/* The X font driver function ENCODE_CHAR. */ -MWDevice * -mwin__open_device (MFrame *frame, MPlist *param) +static unsigned +xfont_encode_char (MRealizedFont *rfont, int c, unsigned code) { - Display *display = NULL; - Screen *screen = NULL; - int screen_num; - Drawable drawable = 0; - Widget widget = NULL; - Colormap cmap = 0; - int auto_display = 0; - MDisplayInfo *disp_info = NULL; - MWDevice *device = NULL; - MSymbol key; - XWindowAttributes attr; - unsigned depth = 0; - MPlist *plist; - AppData app_data; - MFace *face; + MXFontInfo *xfont_info; + XFontStruct *xfont; + unsigned min_byte1, max_byte1, min_byte2, max_byte2; + int all_chars_exist; - for (plist = param; (key = mplist_key (plist)) != Mnil; - plist = mplist_next (plist)) + if (rfont->status < 0 || code >= 0x10000) + return MCHAR_INVALID_CODE; + if (rfont->status == 0) { - if (key == Mdisplay) - display = (Display *) mplist_value (plist); - else if (key == Mscreen) - screen = mplist_value (plist); - else if (key == Mdrawable) - drawable = (Drawable) mplist_value (plist); - else if (key == Mdepth) - depth = (unsigned) mplist_value (plist); - else if (key == Mwidget) - widget = (Widget) mplist_value (plist); - else if (key == Mcolormap) - cmap = (Colormap) mplist_value (plist); + if (xfont_open (rfont) < 0) + return MCHAR_INVALID_CODE; } + xfont_info = rfont->info; + xfont = xfont_info->xfont; + all_chars_exist = (! xfont->per_char || xfont->all_chars_exist == True); + min_byte1 = xfont->min_byte1; + max_byte1 = xfont->max_byte1; + min_byte2 = xfont->min_char_or_byte2; + max_byte2 = xfont->max_char_or_byte2; - if (widget) - { - display = XtDisplay (widget); - screen_num = XScreenNumberOfScreen (XtScreen (widget)); - depth = DefaultDepth (display, screen_num); - } - else if (drawable) + if (min_byte1 == 0 && max_byte1 == 0) { - Window root_window; - int x, y; - unsigned width, height, border_width; + XCharStruct *pcm; - if (! display) - MERROR (MERROR_WIN, NULL); - XGetGeometry (display, drawable, &root_window, - &x, &y, &width, &height, &border_width, &depth); - XGetWindowAttributes (display, root_window, &attr); - screen_num = XScreenNumberOfScreen (attr.screen); + if (code < min_byte2 || code > max_byte2) + return MCHAR_INVALID_CODE; + if (all_chars_exist) + return code; + pcm = xfont->per_char + (code - min_byte2); + return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing) + ? code : MCHAR_INVALID_CODE); } else { - if (screen) - display = DisplayOfScreen (screen); - else - { - if (! display) - { - display = XOpenDisplay (NULL); - if (! display) - MERROR (MERROR_WIN, NULL); - auto_display = 1; - } - screen = DefaultScreenOfDisplay (display); - } - screen_num = XScreenNumberOfScreen (screen); - if (! depth) - depth = DefaultDepth (display, screen_num); - } - - if (! cmap) - cmap = DefaultColormap (display, screen_num); - - for (plist = display_info_list; mplist_key (plist) != Mnil; - plist = mplist_next (plist)) - { - disp_info = (MDisplayInfo *) mplist_value (plist); - if (disp_info->display == display) - break; - } + unsigned byte1 = code >> 8, byte2 = code & 0xFF; + XCharStruct *pcm; - if (mplist_key (plist) != Mnil) - M17N_OBJECT_REF (disp_info); - else - { - M17N_OBJECT (disp_info, free_display_info, MERROR_WIN); - disp_info->display = display; - disp_info->auto_display = auto_display; - disp_info->font_registry_list = mplist (); - disp_info->iso8859_1_family_list = mplist (); - disp_info->iso10646_1_family_list = mplist (); - disp_info->realized_font_list = mplist (); - find_modifier_bits (disp_info); - mplist_add (display_info_list, Mt, disp_info); - } + if (byte1 < min_byte1 || byte1 > max_byte1 + || byte2 < min_byte2 || byte2 > max_byte2) + return MCHAR_INVALID_CODE; - for (plist = device_list; mplist_key (plist) != Mnil; - plist = mplist_next (plist)) - { - device = (MWDevice *) mplist_value (plist); - if (device->display_info == disp_info - && device->depth == depth - && device->cmap == cmap) - break; + if (all_chars_exist) + return code; + pcm = xfont->per_char + ((byte1 - min_byte1) * (max_byte2 - min_byte2 + 1) + + (byte2 - min_byte2)); + return ((pcm->width > 0 || pcm->rbearing != pcm->lbearing) + ? code : MCHAR_INVALID_CODE); } +} - if (mplist_key (plist) != Mnil) - M17N_OBJECT_REF (device); - else - { - unsigned long valuemask = GCForeground; - XGCValues values; +/* The X font driver function RENDER. */ - M17N_OBJECT (device, free_device, MERROR_WIN); - device->display_info = disp_info; - device->screen_num = screen_num; - /* A drawable on which to create GCs. */ - device->drawable = XCreatePixmap (display, - RootWindow (display, screen_num), - 1, 1, depth); - device->depth = depth; - device->cmap = cmap; - device->realized_face_list = mplist (); - device->realized_fontset_list = mplist (); - device->gc_list = mplist (); - values.foreground = BlackPixel (display, screen_num); - device->scratch_gc = XCreateGC (display, device->drawable, - valuemask, &values); -#ifdef HAVE_XFT2 - device->xft_draw = XftDrawCreate (display, device->drawable, - DefaultVisual (display, screen_num), - cmap); -#endif - } +static void +xfont_render (MDrawWindow win, int x, int y, MGlyphString *gstring, + MGlyph *from, MGlyph *to, int reverse, MDrawRegion region) +{ + MRealizedFace *rface = from->rface; + MXFontInfo *xfont_info = rface->rfont->info; + Display *display; + XChar2b *code; + GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL]; + MGlyph *g; + int i; - frame->realized_font_list = disp_info->realized_font_list; - frame->realized_face_list = device->realized_face_list; - frame->realized_fontset_list = device->realized_fontset_list; + if (from == to) + return; - if (widget) - { - XtResource resources[] = { - { XtNfont, XtCFont, XtRString, sizeof (String), - XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT }, - { XtNforeground, XtCForeground, XtRString, sizeof (String), - XtOffset (AppDataPtr, foreground), XtRString, "black" }, - { XtNbackground, XtCBackground, XtRString, sizeof (String), - XtOffset (AppDataPtr, background), XtRString, "white" }, - { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean), - XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE } - }; + /* It is assured that the all glyphs in the current range use the + same realized face. */ + display = FRAME_DISPLAY (rface->frame); - XtGetApplicationResources (widget, &app_data, - resources, XtNumber (resources), NULL, 0); - frame->foreground = msymbol (app_data.foreground); - frame->background = msymbol (app_data.background); - frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal; - } - else + if (region) + gc = set_region (rface->frame, gc, region); + XSetFont (display, gc, xfont_info->xfont->fid); + code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from)); + for (i = 0, g = from; g < to; i++, g++) { - app_data.font = DEFAULT_FONT; - frame->foreground = msymbol ("black"); - frame->background = msymbol ("white"); - frame->videomode = Mnormal; + code[i].byte1 = g->code >> 8; + code[i].byte2 = g->code & 0xFF; } - frame->font = mfont (); - { - int nfonts; - char **names = XListFonts (display, app_data.font, 1, &nfonts); - - if (nfonts > 0) - { - if (mwin__parse_font_name (names[0], frame->font) < 0) - { - /* The font name does not conform to XLFD. Try to open the - font and get XA_FONT property. */ - XFontStruct *xfont = XLoadQueryFont (display, names[0]); - - nfonts = 0; - if (xfont) - { - unsigned long value; - char *name; - - if (XGetFontProperty (xfont, XA_FONT, &value) - && (name = ((char *) - XGetAtomName (display, (Atom) value)))) - { - if (mwin__parse_font_name (name, frame->font) >= 0) - nfonts = 1; - } - XFreeFont (display, xfont); - } - } - XFreeFontNames (names); - } - if (! nfonts) - mwin__parse_font_name (FALLBACK_FONT, frame->font); - } - - face = mface_from_font (frame->font); - face->property[MFACE_FONTSET] = mfontset (NULL); - face->property[MFACE_FOREGROUND] = frame->foreground; - face->property[MFACE_BACKGROUND] = frame->background; - mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline)); - mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox)); - face->property[MFACE_VIDEOMODE] = frame->videomode; - mface_put_prop (face, Mhook_func, - mface_get_prop (mface__default, Mhook_func)); - face->property[MFACE_RATIO] = (void *) 100; - mplist_push (param, Mface, face); - M17N_OBJECT_UNREF (face); - -#ifdef X_SET_ERROR_HANDLER - XSetErrorHandler (x_error_handler); - XSetIOErrorHandler (x_io_error_handler); -#endif - - return device; -} + g = from; + while (g < to) + { + if (g->type == GLYPH_PAD) + x += g++->width; + else if (g->type == GLYPH_SPACE) + for (; g < to && g->type == GLYPH_SPACE; g++) + x += g->width; + else if (! g->rface->rfont) + { + if ((g->c >= 0x200B && g->c <= 0x200F) + || (g->c >= 0x202A && g->c <= 0x202E)) + x += g++->width; + else + { + /* As a font is not found for this character, draw an + empty box. */ + int box_width = g->width; + int box_height = gstring->ascent + gstring->descent; -void -mwin__close_device (MFrame *frame) -{ - M17N_OBJECT_UNREF (frame->device); -} + if (box_width > 4) + box_width -= 2; + if (box_height > 4) + box_height -= 2; + XDrawRectangle (display, (Window) win, gc, + x, y - gstring->ascent, box_width, box_height); + x += g++->width; + } + } + else if (g->xoff != 0 || g->yoff != 0 || g->right_padding) + { + XDrawString16 (display, (Window) win, gc, + x + g->xoff, y + g->yoff, code + (g - from), 1); + x += g->width; + g++; + } + else + { + int orig_x = x; + int code_idx = g - from; -void * -mwin__device_get_prop (MWDevice *device, MSymbol key) -{ - if (key == Mdisplay) - return (void *) device->display_info->display; - if (key == Mscreen) - return (void *) ScreenOfDisplay(device->display_info->display, - device->screen_num); - if (key == Mcolormap) - return (void *) device->cmap; - if (key == Mdepth) - return (void *) device->depth; - return NULL; + for (i = 0; + g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0; + i++, g++) + x += g->width; + XDrawString16 (display, (Window) win, gc, orig_x, y, + code + code_idx, i); + } + } } -void -mwin__realize_face (MRealizedFace *rface) +static MFont * +xfont_parse_name (char *name, MFont *font) { - MFrame *frame; - MSymbol foreground, background, videomode; - MFaceHLineProp *hline; - MFaceBoxProp *box; - GCInfo *info; - - if (rface != rface->ascii_rface) - { - rface->info = rface->ascii_rface->info; - return; - } - - frame = rface->frame; - MSTRUCT_CALLOC (info, MERROR_WIN); - - foreground = rface->face.property[MFACE_FOREGROUND]; - background = rface->face.property[MFACE_BACKGROUND]; - videomode = rface->face.property[MFACE_VIDEOMODE]; - if (! videomode) - videomode = frame->videomode; - if (videomode != Mreverse) - { - info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore); - info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back); - } - else - { - info->gc[GC_NORMAL] = get_gc (frame, background, 0, &info->rgb_fore); - info->gc[GC_INVERSE] = get_gc (frame, foreground, 1, &info->rgb_back); - } -#ifdef HAVE_XFT2 - if (foreground == Mnil) - foreground = frame->foreground; - if (background == Mnil) - background = frame->background; - if (videomode == Mreverse) - { - MSymbol temp = foreground; - foreground = background; - background = temp; - } - if (! XftColorAllocName (FRAME_DISPLAY (frame), - FRAME_VISUAL (frame), - FRAME_CMAP (frame), - MSYMBOL_NAME (foreground), - &info->xft_color_fore)) - mdebug_hook (); - if (! XftColorAllocName (FRAME_DISPLAY (frame), - FRAME_VISUAL (frame), - FRAME_CMAP (frame), - MSYMBOL_NAME (background), - &info->xft_color_back)) - mdebug_hook (); -#endif + char *field[XLFD_FIELD_MAX]; + unsigned short size, resy; + MSymbol attrs[MFONT_PROPERTY_MAX]; + char *copy = (char *) alloca (512); + int i, len; + char *p, *last = NULL; - hline = rface->hline; - if (hline) + len = strlen (name) + 1; + for (i = 0, p = name; *p; p++) { - if (hline->color) - info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL); - else - info->gc[GC_HLINE] = info->gc[GC_NORMAL]; + if (*p == '-') + i++; + else if (p > name && *p == '*' && p[-1] == '-') + last = p + 1; } - - box = rface->box; - if (box) + if (i == 14) + memcpy (copy, name, len); + else if (last) { - if (box->color_top) - info->gc[GC_BOX_TOP] = get_gc (frame, box->color_top, 1, NULL); - else - info->gc[GC_BOX_TOP] = info->gc[GC_NORMAL]; - - if (box->color_left && box->color_left != box->color_top) - info->gc[GC_BOX_LEFT] = get_gc (frame, box->color_left, 1, NULL); - else - info->gc[GC_BOX_LEFT] = info->gc[GC_BOX_TOP]; - - if (box->color_bottom && box->color_bottom != box->color_top) - info->gc[GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1, NULL); - else - info->gc[GC_BOX_BOTTOM] = info->gc[GC_BOX_TOP]; - - if (box->color_right && box->color_right != box->color_bottom) - info->gc[GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1, NULL); - else - info->gc[GC_BOX_RIGHT] = info->gc[GC_BOX_BOTTOM]; + memcpy (copy, name, last - name); + for (; i < 14; i++) + strcat (copy, "-*"); + strcat (copy, last); } - rface->info = info; + if (split_font_name (copy, field, &size, &resy) < 0) + return NULL; + attrs[MFONT_FOUNDRY] + = *(field[XLFD_FOUNDRY]) != '*' ? msymbol (field[XLFD_FOUNDRY]) : Mnil; + attrs[MFONT_FAMILY] + = *(field[XLFD_FAMILY]) != '*' ? msymbol (field[XLFD_FAMILY]) : Mnil; + attrs[MFONT_WEIGHT] + = *(field[XLFD_WEIGHT]) != '*' ? msymbol (field[XLFD_WEIGHT]) : Mnil; + attrs[MFONT_STYLE] + = *(field[XLFD_SLANT]) != '*' ? msymbol (field[XLFD_SLANT]) : Mnil; + attrs[MFONT_STRETCH] + = *(field[XLFD_SWIDTH]) != '*' ? msymbol (field[XLFD_SWIDTH]) : Mnil; + attrs[MFONT_ADSTYLE] + = *(field[XLFD_ADSTYLE]) != '*' ? msymbol (field[XLFD_ADSTYLE]) : Mnil; + attrs[MFONT_REGISTRY] + = *(field[XLFD_REGISTRY]) != '*' ? msymbol (field[XLFD_REGISTRY]) : Mnil; + mfont__set_spec (font, attrs, size, resy); + return font; } - -void -mwin__free_realized_face (MRealizedFace *rface) +static char * +xfont_build_name (MFont *font) { - if (rface == rface->ascii_rface) - free (rface->info); + char name[1024]; + + if (! build_font_name (font, name, 1024)) + return NULL; + return strdup (name); } + +/* Xft Handler */ -void -mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface, - int reverse, - int x, int y, int width, int height, MDrawRegion region) +#ifdef HAVE_XFT2 + +typedef struct { - GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE]; + M17NObject control; + Display *display; + XftFont *font_aa; + XftFont *font_no_aa; +} MXftFontInfo; - if (region) - gc = set_region (frame, gc, region); +static MRealizedFont *xft_select (MFrame *, MFont *, MFont *, int); +static int xft_open (MRealizedFont *); +static void xft_find_metric (MRealizedFont *, MGlyphString *, int, int); +static void xft_render (MDrawWindow, int, int, MGlyphString *, + MGlyph *, MGlyph *, int, MDrawRegion); - XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc, - x, y, width, height); -} +MFontDriver xft_driver = + { NULL, /* Set to ft_select in mwin__init (). */ + xft_open, xft_find_metric, + NULL, /* Set to ft_encode_char in mwin__init (). */ + xft_render }; -void mwin__draw_empty_boxes (MDrawWindow win, int x, int y, - MGlyphString *gstring, MGlyph *from, MGlyph *to, - int reverse, MDrawRegion region) +static void +close_xft (void *object) { - MRealizedFace *rface = from->rface; - Display *display = FRAME_DISPLAY (rface->frame); - GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL]; - - if (from == to) - return; + MXftFontInfo *font_info = object; - if (region) - gc = set_region (rface->frame, gc, region); - for (; from < to; from++) - { - XDrawRectangle (display, (Window) win, gc, - x, y - gstring->ascent + 1, from->width - 1, - gstring->ascent + gstring->descent - 2); - x += from->width; - } + XftFontClose (font_info->display, font_info->font_aa); + XftFontClose (font_info->display, font_info->font_no_aa); + free (font_info); } -void -mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring, - MRealizedFace *rface, int reverse, - int x, int y, int width, MDrawRegion region) +static XftFont * +xft_open_font (MFrame *frame, MFTInfo *ft_info, int size, int anti_alias) { - enum MFaceHLineType type = rface->hline->type; - GCInfo *info = rface->info; - GC gc = gc = info->gc[GC_HLINE]; - int i; - - y = (type == MFACE_HLINE_BOTTOM - ? y + gstring->text_descent - rface->hline->width - : type == MFACE_HLINE_UNDER - ? y + 1 - : type == MFACE_HLINE_STRIKE_THROUGH - ? y - ((gstring->ascent + gstring->descent) / 2) - : y - gstring->text_ascent); - if (region) - gc = set_region (frame, gc, region); + XftPattern *pattern; + XftFontInfo *xft_font_info; + XftFont *font; - for (i = 0; i < rface->hline->width; i++) - XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc, - x, y + i, x + width - 1, y + i); + pattern = XftPatternCreate (); + XftPatternAddString (pattern, XFT_FILE, ft_info->filename); + XftPatternAddDouble (pattern, XFT_PIXEL_SIZE, (double) size); + XftPatternAddBool (pattern, XFT_ANTIALIAS, anti_alias); + xft_font_info = XftFontInfoCreate (FRAME_DISPLAY (frame), pattern); + if (! xft_font_info) + return NULL; + font = XftFontOpenInfo (FRAME_DISPLAY (frame), pattern, xft_font_info); + XftFontInfoDestroy (FRAME_DISPLAY (frame), xft_font_info); + return font; } -void -mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring, - MGlyph *g, int x, int y, int width, MDrawRegion region) +static int +xft_open (MRealizedFont *rfont) { - Display *display = FRAME_DISPLAY (frame); - MRealizedFace *rface = g->rface; - MFaceBoxProp *box = rface->box; - GCInfo *info = rface->info; - GC gc_top, gc_left, gc_right, gc_btm; - int y0, y1; - int i; + MFrame *frame; + MFTInfo *ft_info; + MXftFontInfo *font_info; + int size; - y0 = y - (gstring->text_ascent - + rface->box->inner_vmargin + rface->box->width); - y1 = y + (gstring->text_descent - + rface->box->inner_vmargin + rface->box->width - 1); + if ((mfont__ft_driver.open) (rfont) < 0) + return -1; - gc_top = info->gc[GC_BOX_TOP]; - if (region) - gc_top = set_region (frame, gc_top, region); - if (info->gc[GC_BOX_TOP] == info->gc[GC_BOX_BOTTOM]) - gc_btm = gc_top; - else - gc_btm = info->gc[GC_BOX_BOTTOM]; + size = rfont->font.property[MFONT_SIZE] / 10; + frame = rfont->frame; - if (g->type == GLYPH_BOX) + ft_info = rfont->info; + M17N_OBJECT (font_info, close_xft, MERROR_WIN); + ft_info->extra_info = font_info; + font_info->display = FRAME_DISPLAY (frame); + font_info->font_aa = xft_open_font (frame, ft_info, size, 1); + if (font_info->font_aa) { - int x0, x1; - - if (g->left_padding) - x0 = x + box->outer_hmargin, x1 = x + g->width - 1; - else - x0 = x, x1 = x + g->width - box->outer_hmargin - 1; + font_info->font_no_aa = xft_open_font (frame, ft_info, size, 0); + if (font_info->font_no_aa) + return 0; + XftFontClose (FRAME_DISPLAY (rfont->frame), font_info->font_aa); + } + free (font_info); + ft_info->extra_info = NULL; + rfont->status = -1; + return -1; +} - /* Draw the top side. */ - for (i = 0; i < box->width; i++) - XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i); - /* Draw the bottom side. */ - if (region && gc_btm != gc_top) - gc_btm = set_region (frame, gc_btm, region); - for (i = 0; i < box->width; i++) - XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i); +static void +xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring, + int from, int to) +{ + MFTInfo *ft_info = rfont->info; + MXftFontInfo *font_info = ft_info->extra_info; + FT_Face ft_face = ft_info->ft_face; + MGlyph *g = MGLYPH (from), *gend = MGLYPH (to); - if (g->left_padding > 0) + for (; g != gend; g++) + { + if (g->code == MCHAR_INVALID_CODE) { - /* Draw the left side. */ - if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP]) - gc_left = gc_top; - else - { - gc_left = info->gc[GC_BOX_LEFT]; - if (region) - gc_left = set_region (frame, gc_left, region); - } - for (i = 0; i < rface->box->width; i++) - XDrawLine (display, (Window) win, gc_left, - x0 + i, y0 + i, x0 + i, y1 - i); + MGlyph *start = g++; + + while (g != gend && g->code == MCHAR_INVALID_CODE) g++; + (mfont__ft_driver.find_metric) (rfont, gstring, GLYPH_INDEX (start), + GLYPH_INDEX (g)); + g--; } else { - /* Draw the right side. */ - if (info->gc[GC_BOX_RIGHT] == info->gc[GC_BOX_TOP]) - gc_right = gc_top; + XGlyphInfo extents; + unsigned code; + + if (g->otf_encoded) + code = g->code; else - { - gc_right = info->gc[GC_BOX_RIGHT]; - if (region) - gc_right = set_region (frame, gc_right, region); - } - for (i = 0; i < rface->box->width; i++) - XDrawLine (display, (Window) win, gc_right, - x1 - i, y0 + i, x1 - i, y1 - i); - } - } - else - { - /* Draw the top side. */ - for (i = 0; i < box->width; i++) - XDrawLine (display, (Window) win, gc_top, - x, y0 + i, x + width - 1, y0 + i); + code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code); - /* Draw the bottom side. */ - if (region && gc_btm != gc_top) - gc_btm = set_region (frame, gc_btm, region); - for (i = 0; i < box->width; i++) - XDrawLine (display, (Window) win, gc_btm, - x, y1 - i, x + width - 1, y1 - i); + XftGlyphExtents (FRAME_DISPLAY (rfont->frame), + font_info->font_aa, &code, 1, &extents); + g->lbearing = extents.x; + g->rbearing = extents.width - extents.x; + g->width = extents.xOff; + g->ascent = extents.y; + g->descent = extents.height - extents.y; + } } } -#if 0 -void -mwin__draw_bitmap (MFrame *frame, MDrawWindow win, MRealizedFace *rface, - int reverse, int x, int y, - int width, int height, int row_bytes, unsigned char *bmp, - MDrawRegion region) +void +xft_render (MDrawWindow win, int x, int y, + MGlyphString *gstring, MGlyph *from, MGlyph *to, + int reverse, MDrawRegion region) { - Display *display = FRAME_DISPLAY (frame); - int i, j; - GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_INVERSE : GC_NORMAL]; + MRealizedFace *rface = from->rface; + MFrame *frame = rface->frame; + MFTInfo *ft_info = rface->rfont->info; + MXftFontInfo *font_info = ft_info->extra_info; + FT_Face ft_face = ft_info->ft_face; + XftDraw *xft_draw = FRAME_DEVICE (frame)->xft_draw; + XftColor *xft_color = (! reverse + ? &((GCInfo *) rface->info)->xft_color_fore + : &((GCInfo *) rface->info)->xft_color_back); + XftFont *xft_font = (gstring->control.anti_alias + && FRAME_DEVICE (frame)->depth > 1 + ? font_info->font_aa : font_info->font_no_aa); + MGlyph *g; + FT_UInt *glyphs; + int last_x; + int nglyphs; - if (region) - gc = set_region (frame, gc, region); + if (from == to) + return; - for (i = 0; i < height; i++, bmp += row_bytes) - for (j = 0; j < width; j++) - if (bmp[j / 8] & (1 << (7 - (j % 8)))) - XDrawPoint (display, (Window) win, gc, x + j, y + i); + XftDrawChange (xft_draw, (Drawable) win); + XftDrawSetClip (xft_draw, (Region) region); + + glyphs = alloca (sizeof (FT_UInt) * (to - from)); + for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width) + { + unsigned code; + + if (g->otf_encoded) + code = g->code; + else + code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code); + if (g->xoff == 0 && g->yoff == 0) + glyphs[nglyphs++] = code; + else + { + if (nglyphs > 0) + XftDrawGlyphs (xft_draw, xft_color, xft_font, + last_x, y, glyphs, nglyphs); + nglyphs = 0; + XftDrawGlyphs (xft_draw, xft_color, xft_font, + x + g->xoff, y + g->yoff, (FT_UInt *) &code, 1); + last_x = x + g->width; + } + } + if (nglyphs > 0) + XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs); } + #endif -void -mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface, - int intensity, MDrawPoint *points, int num, - MDrawRegion region) -{ - GCInfo *info = rface->info; - GC gc; + - if (! (gc = info->gc[intensity])) - gc = info->gc[intensity] = get_gc_for_anti_alias (frame->device, info, - intensity); - if (region) - gc = set_region (frame, gc, region); +/* XIM (X Input Method) handler */ - XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc, - (XPoint *) points, num, CoordModeOrigin); -} +typedef struct MInputXIMMethodInfo +{ + Display *display; + XIM xim; + MSymbol language; + MSymbol coding; +} MInputXIMMethodInfo; +typedef struct MInputXIMContextInfo +{ + XIC xic; + Window win; + MConverter *converter; +} MInputXIMContextInfo; -MDrawRegion -mwin__region_from_rect (MDrawMetric *rect) +static int +xim_open_im (MInputMethod *im) { - MDrawRegion region1 = XCreateRegion (); - MDrawRegion region2 = XCreateRegion (); - XRectangle xrect; + MInputXIMArgIM *arg = (MInputXIMArgIM *) im->arg; + MLocale *saved, *this; + char *save_modifier_list; + XIM xim; + MInputXIMMethodInfo *im_info; - xrect.x = rect->x; - xrect.y = rect->y; - xrect.width = rect->width; - xrect.height = rect->height; - XUnionRectWithRegion (&xrect, region1, region2); - XDestroyRegion (region1); - return region2; -} + saved = mlocale_set (LC_CTYPE, NULL); + this = mlocale_set (LC_CTYPE, arg->locale ? arg->locale : ""); + if (! this) + /* The specified locale is not supported. */ + MERROR (MERROR_LOCALE, -1); + if (mlocale_get_prop (this, Mcoding) == Mnil) + { + /* Unable to decode the output of XIM. */ + mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); + MERROR (MERROR_LOCALE, -1); + } -void -mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect) -{ - MDrawRegion region1 = XCreateRegion (); - XRectangle xrect; + if (arg->modifier_list) + save_modifier_list = XSetLocaleModifiers (arg->modifier_list); + else + save_modifier_list = XSetLocaleModifiers (""); + if (! save_modifier_list) + { + /* The specified locale is not supported by X. */ + mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); + MERROR (MERROR_LOCALE, -1); + } - xrect.x = rect->x; - xrect.y = rect->y; - xrect.width = rect->width; - xrect.height = rect->height; + xim = XOpenIM (arg->display, arg->db, arg->res_name, arg->res_class); + if (! xim) + { + /* No input method is available in the current locale. */ + XSetLocaleModifiers (save_modifier_list); + mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); + MERROR (MERROR_WIN, -1); + } - XUnionRegion (region, region, region1); - XUnionRectWithRegion (&xrect, region1, region); - XDestroyRegion (region1); -} + MSTRUCT_MALLOC (im_info, MERROR_WIN); + im_info->display = arg->display; + im_info->xim = xim; + im_info->language = mlocale_get_prop (this, Mlanguage); + im_info->coding = mlocale_get_prop (this, Mcoding); + im->info = im_info; -void -mwin__intersect_region (MDrawRegion region1, MDrawRegion region2) -{ - MDrawRegion region = XCreateRegion (); + XSetLocaleModifiers (save_modifier_list); + mlocale_set (LC_CTYPE, msymbol_name (mlocale_get_prop (saved, Mname))); - XUnionRegion (region1, region1, region); - XIntersectRegion (region, region2, region1); - XDestroyRegion (region); + return 0; } -void -mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect) +static void +xim_close_im (MInputMethod *im) { - MDrawRegion region1 = XCreateRegion (); - XRectangle xrect; + MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info; - xrect.x = rect->x; - xrect.y = rect->y; - xrect.width = rect->width; - xrect.height = rect->height; - XUnionRectWithRegion (&xrect, region1, region); - XDestroyRegion (region1); + XCloseIM (im_info->xim); + free (im_info); } -void -mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect) +static int +xim_create_ic (MInputContext *ic) { - XRectangle xrect; + MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg; + MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info; + MInputXIMContextInfo *ic_info; + XIC xic; - XClipBox (region, &xrect); - rect->x = xrect.x; - rect->y = xrect.y; - rect->width = xrect.width; - rect->height = xrect.height; -} + if (! arg->input_style) + { + /* By default, use Root style. */ + arg->input_style = XIMPreeditNothing | XIMStatusNothing; + arg->preedit_attrs = NULL; + arg->status_attrs = NULL; + } -void -mwin__free_region (MDrawRegion region) -{ - XDestroyRegion (region); + if (! arg->preedit_attrs && ! arg->status_attrs) + xic = XCreateIC (im_info->xim, + XNInputStyle, arg->input_style, + XNClientWindow, arg->client_win, + XNFocusWindow, arg->focus_win, + NULL); + else if (arg->preedit_attrs && ! arg->status_attrs) + xic = XCreateIC (im_info->xim, + XNInputStyle, arg->input_style, + XNClientWindow, arg->client_win, + XNFocusWindow, arg->focus_win, + XNPreeditAttributes, arg->preedit_attrs, + NULL); + else if (! arg->preedit_attrs && arg->status_attrs) + xic = XCreateIC (im_info->xim, + XNInputStyle, arg->input_style, + XNClientWindow, arg->client_win, + XNFocusWindow, arg->focus_win, + XNStatusAttributes, arg->status_attrs, + NULL); + else + xic = XCreateIC (im_info->xim, + XNInputStyle, arg->input_style, + XNClientWindow, arg->client_win, + XNFocusWindow, arg->focus_win, + XNPreeditAttributes, arg->preedit_attrs, + XNStatusAttributes, arg->status_attrs, + NULL); + if (! xic) + MERROR (MERROR_WIN, -1); + + MSTRUCT_MALLOC (ic_info, MERROR_WIN); + ic_info->xic = xic; + ic_info->win = arg->focus_win; + ic_info->converter = mconv_buffer_converter (im_info->coding, NULL, 0); + ic->info = ic_info; + return 0; } -void -mwin__dump_region (MDrawRegion region) +static void +xim_destroy_ic (MInputContext *ic) { - XRectangle rect; - XClipBox (region, &rect); - fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height); + MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info; + + XDestroyIC (ic_info->xic); + mconv_free_converter (ic_info->converter); + free (ic_info); + ic->info = NULL; } -void -mwin__verify_region (MFrame *frame, MDrawRegion region) +static int +xim_filter (MInputContext *ic, MSymbol key, void *event) { - set_region (frame, ((GCInfo *) frame->rface->info)->gc[GC_NORMAL], region); + MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info; + + return (XFilterEvent ((XEvent *) event, ic_info->win) == True); } -MDrawWindow -mwin__create_window (MFrame *frame, MDrawWindow parent) + +static int +xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt) { - Display *display = FRAME_DISPLAY (frame); - Window win; - XWMHints wm_hints = { InputHint, False }; - XClassHint class_hints = { "M17N-IM", "m17n-im" }; - XSetWindowAttributes set_attrs; - unsigned long mask; - XGCValues values; - GCInfo *info = frame->rface->info; + MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info; + MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info; + XKeyPressedEvent *ev = (XKeyPressedEvent *) arg; + KeySym keysym; + Status status; + char *buf; + int len; - if (! parent) - parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame)); - mask = GCForeground; - XGetGCValues (display, info->gc[GC_INVERSE], mask, &values); - set_attrs.background_pixel = values.foreground; - set_attrs.backing_store = Always; - set_attrs.override_redirect = True; - set_attrs.save_under = True; - mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder; - win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0, - CopyFromParent, InputOutput, CopyFromParent, - mask, &set_attrs); - XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0, - NULL, &wm_hints, &class_hints); - XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask); - return (MDrawWindow) win; + buf = (char *) alloca (512); + len = XmbLookupString (ic_info->xic, ev, buf, 512, &keysym, &status); + if (status == XBufferOverflow) + { + buf = (char *) alloca (len); + len = XmbLookupString (ic_info->xic, ev, buf, len, &keysym, &status); + } + + mtext_reset (ic->produced); + if (len == 0) + return 1; + + mconv_reset_converter (ic_info->converter); + mconv_rebind_buffer (ic_info->converter, (unsigned char *) buf, len); + mconv_decode (ic_info->converter, ic->produced); + mtext_put_prop (ic->produced, 0, mtext_nchars (ic->produced), + Mlanguage, (void *) im_info->language); + mtext_cpy (mt, ic->produced); + mtext_reset (ic->produced); + return 0; } -void -mwin__destroy_window (MFrame *frame, MDrawWindow win) + + +#ifdef X_SET_ERROR_HANDLER +static int +x_error_handler (Display *display, XErrorEvent *error) { - XDestroyWindow (FRAME_DISPLAY (frame), (Window) win); + mdebug_hook (); + return 0; } -#if 0 -MDrawWindow -mwin__event_window (void *event) +static int +x_io_error_handler (Display *display) { - return ((MDrawWindow) ((XEvent *) event)->xany.window); + mdebug_hook (); + return 0; } +#endif -void -mwin__print_event (void *arg, char *win_name) + + +/* Functions to be stored in MDeviceLibraryInterface by dlsym (). */ + +int +device_init () { - char *event_name; - XEvent *event = (XEvent *) arg; + M_iso8859_1 = msymbol ("iso8859-1"); + M_iso10646_1 = msymbol ("iso10646-1"); - switch (event->xany.type) - { - case 2: event_name = "KeyPress"; break; - case 3: event_name = "KeyRelease"; break; - case 4: event_name = "ButtonPress"; break; - case 5: event_name = "ButtonRelease"; break; - case 6: event_name = "MotionNotify"; break; - case 7: event_name = "EnterNotify"; break; - case 8: event_name = "LeaveNotify"; break; - case 9: event_name = "FocusIn"; break; - case 10: event_name = "FocusOut"; break; - case 11: event_name = "KeymapNotify"; break; - case 12: event_name = "Expose"; break; - case 13: event_name = "GraphicsExpose"; break; - case 14: event_name = "NoExpose"; break; - case 15: event_name = "VisibilityNotify"; break; - case 16: event_name = "CreateNotify"; break; - case 17: event_name = "DestroyNotify"; break; - case 18: event_name = "UnmapNotify"; break; - case 19: event_name = "MapNotify"; break; - case 20: event_name = "MapRequest"; break; - case 21: event_name = "ReparentNotify"; break; - case 22: event_name = "ConfigureNotify"; break; - case 23: event_name = "ConfigureRequest"; break; - case 24: event_name = "GravityNotify"; break; - case 25: event_name = "ResizeRequest"; break; - case 26: event_name = "CirculateNotify"; break; - case 27: event_name = "CirculateRequest"; break; - case 28: event_name = "PropertyNotify"; break; - case 29: event_name = "SelectionClear"; break; - case 30: event_name = "SelectionRequest"; break; - case 31: event_name = "SelectionNotify"; break; - case 32: event_name = "ColormapNotify"; break; - case 33: event_name = "ClientMessage"; break; - case 34: event_name = "MappingNotify"; break; - default: event_name = "unknown"; - } + display_info_list = mplist (); + device_list = mplist (); - fprintf (stderr, "%s: %s\n", win_name, event_name); -} +#ifdef HAVE_XFT2 + xft_driver.select = mfont__ft_driver.select; + xft_driver.encode_char = mfont__ft_driver.encode_char; #endif -void -mwin__map_window (MFrame *frame, MDrawWindow win) -{ - XMapRaised (FRAME_DISPLAY (frame), (Window) win); + Mxim = msymbol ("xim"); + msymbol_put (Mxim, Minput_driver, &minput_xim_driver); + + return 0; } -void -mwin__unmap_window (MFrame *frame, MDrawWindow win) +int +device_fini () { - XUnmapWindow (FRAME_DISPLAY (frame), (Window) win); + M17N_OBJECT_UNREF (display_info_list); + M17N_OBJECT_UNREF (device_list); + return 0; } -void -mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win, - MDrawMetric *geometry) +/** Return an MWDevice object corresponding to a display specified in + PLIST. + + It searches device_list for a device matching the display. If + found, return the found object. Otherwise, return a newly created + object. */ + +void * +device_open (MFrame *frame, MPlist *param) { - Display *display = FRAME_DISPLAY (frame); + Display *display = NULL; + Screen *screen = NULL; + int screen_num; + Drawable drawable = 0; + Widget widget = NULL; + Colormap cmap = 0; + int auto_display = 0; + MDisplayInfo *disp_info = NULL; + MWDevice *device = NULL; + MSymbol key; XWindowAttributes attr; - Window parent = (Window) parent_win, root; + unsigned depth = 0; + MPlist *plist; + AppData app_data; + MFace *face; - XGetWindowAttributes (display, (Window) win, &attr); - geometry->x = attr.x + attr.border_width; - geometry->y = attr.y + attr.border_width; - geometry->width = attr.width; - geometry->height = attr.height; + for (plist = param; (key = mplist_key (plist)) != Mnil; + plist = mplist_next (plist)) + { + if (key == Mdisplay) + display = (Display *) mplist_value (plist); + else if (key == Mscreen) + screen = mplist_value (plist); + else if (key == Mdrawable) + drawable = (Drawable) mplist_value (plist); + else if (key == Mdepth) + depth = (unsigned) mplist_value (plist); + else if (key == Mwidget) + widget = (Widget) mplist_value (plist); + else if (key == Mcolormap) + cmap = (Colormap) mplist_value (plist); + } - if (! parent) - parent = RootWindow (display, FRAME_SCREEN (frame)); - while (1) + if (widget) { - Window this_parent, *children; - unsigned n; + display = XtDisplay (widget); + screen_num = XScreenNumberOfScreen (XtScreen (widget)); + depth = DefaultDepth (display, screen_num); + } + else if (drawable) + { + Window root_window; + int x, y; + unsigned width, height, border_width; - XQueryTree (display, (Window) win, &root, &this_parent, &children, &n); - if (children) - XFree (children); - if (this_parent == parent || this_parent == root) - break; - win = (MDrawWindow) this_parent; - XGetWindowAttributes (display, (Window) win, &attr); - geometry->x += attr.x + attr.border_width; - geometry->y += attr.y + attr.border_width; + if (! display) + MERROR (MERROR_WIN, NULL); + XGetGeometry (display, drawable, &root_window, + &x, &y, &width, &height, &border_width, &depth); + XGetWindowAttributes (display, root_window, &attr); + screen_num = XScreenNumberOfScreen (attr.screen); + } + else + { + if (screen) + display = DisplayOfScreen (screen); + else + { + if (! display) + { + display = XOpenDisplay (NULL); + if (! display) + MERROR (MERROR_WIN, NULL); + auto_display = 1; + } + screen = DefaultScreenOfDisplay (display); + } + screen_num = XScreenNumberOfScreen (screen); + if (! depth) + depth = DefaultDepth (display, screen_num); } -} -void -mwin__adjust_window (MFrame *frame, MDrawWindow win, - MDrawMetric *current, MDrawMetric *new) -{ - Display *display = FRAME_DISPLAY (frame); - unsigned int mask = 0; - XWindowChanges values; + if (! cmap) + cmap = DefaultColormap (display, screen_num); - if (current->width != new->width) + for (plist = display_info_list; mplist_key (plist) != Mnil; + plist = mplist_next (plist)) { - mask |= CWWidth; - if (new->width <= 0) - new->width = 1; - values.width = current->width = new->width; + disp_info = (MDisplayInfo *) mplist_value (plist); + if (disp_info->display == display) + break; } - if (current->height != new->height) + + if (mplist_key (plist) != Mnil) + M17N_OBJECT_REF (disp_info); + else { - mask |= CWHeight; - if (new->height <= 0) - new->height = 1; - values.height = current->height = new->height; - } - if (current->x != new->x) + M17N_OBJECT (disp_info, free_display_info, MERROR_WIN); + disp_info->display = display; + disp_info->auto_display = auto_display; + disp_info->font_registry_list = mplist (); + disp_info->iso8859_1_family_list = mplist (); + disp_info->iso10646_1_family_list = mplist (); + disp_info->realized_font_list = mplist (); + find_modifier_bits (disp_info); + mplist_add (display_info_list, Mt, disp_info); + } + + for (plist = device_list; mplist_key (plist) != Mnil; + plist = mplist_next (plist)) { - mask |= CWX; - values.x = current->x = new->x; + device = (MWDevice *) mplist_value (plist); + if (device->display_info == disp_info + && device->depth == depth + && device->cmap == cmap) + break; } - if (current->y != new->y) + + if (mplist_key (plist) != Mnil) + M17N_OBJECT_REF (device); + else { - mask |= CWY; - current->y = new->y; - values.y = current->y = new->y; + unsigned long valuemask = GCForeground; + XGCValues values; + + M17N_OBJECT (device, free_device, MERROR_WIN); + device->display_info = disp_info; + device->screen_num = screen_num; + /* A drawable on which to create GCs. */ + device->drawable = XCreatePixmap (display, + RootWindow (display, screen_num), + 1, 1, depth); + device->depth = depth; + device->cmap = cmap; + device->realized_face_list = mplist (); + device->realized_fontset_list = mplist (); + device->gc_list = mplist (); + values.foreground = BlackPixel (display, screen_num); + device->scratch_gc = XCreateGC (display, device->drawable, + valuemask, &values); +#ifdef HAVE_XFT2 + device->xft_draw = XftDrawCreate (display, device->drawable, + DefaultVisual (display, screen_num), + cmap); +#endif } - if (mask) - XConfigureWindow (display, (Window) win, mask, &values); - XClearWindow (display, (Window) win); -} -MSymbol -mwin__parse_event (MFrame *frame, void *arg, int *modifiers) -{ - XEvent *event = (XEvent *) arg; - MDisplayInfo *disp_info = frame->device->display_info; - int len; - char buf[512]; - KeySym keysym; - MSymbol key; + frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT; + frame->driver = &x_driver; + frame->font_driver_list = mplist (); + mplist_add (frame->font_driver_list, Mx, &xfont_driver); +#ifdef HAVE_XFT2 + mplist_add (frame->font_driver_list, Mfreetype, &xft_driver); +#else + mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver); +#endif + frame->realized_font_list = disp_info->realized_font_list; + frame->realized_face_list = device->realized_face_list; + frame->realized_fontset_list = device->realized_fontset_list; - *modifiers = 0; - if (event->xany.type != KeyPress - /* && event->xany.type != KeyRelease */ - ) - return Mnil; - len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL); - if (len > 1) - return Mnil; - if (len == 1) + if (widget) { - int c = keysym; + XtResource resources[] = { + { XtNfont, XtCFont, XtRString, sizeof (String), + XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT }, + { XtNforeground, XtCForeground, XtRString, sizeof (String), + XtOffset (AppDataPtr, foreground), XtRString, "black" }, + { XtNbackground, XtCBackground, XtRString, sizeof (String), + XtOffset (AppDataPtr, background), XtRString, "white" }, + { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean), + XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE } + }; - if (c < XK_space || c > XK_asciitilde) - c = buf[0]; - if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask) - *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; - if (((XKeyEvent *) event)->state & ControlMask) - { - if (c >= 'a' && c <= 'z') - c += 'A' - 'a'; - if (c >= ' ' && c < 127) - *modifiers |= MINPUT_KEY_CONTROL_MODIFIER; - } - key = minput__char_to_key (c); + XtGetApplicationResources (widget, &app_data, + resources, XtNumber (resources), NULL, 0); + frame->foreground = msymbol (app_data.foreground); + frame->background = msymbol (app_data.background); + frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal; } - else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R) - return Mnil; else { - char *str = XKeysymToString (keysym); - - if (! str) - return Mnil; - key = msymbol (str); - if (((XKeyEvent *) event)->state & ShiftMask) - *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; - if (((XKeyEvent *) event)->state & ControlMask) - *modifiers |= MINPUT_KEY_CONTROL_MODIFIER; + app_data.font = DEFAULT_FONT; + frame->foreground = msymbol ("black"); + frame->background = msymbol ("white"); + frame->videomode = Mnormal; } - if (((XKeyEvent *) event)->state & disp_info->meta_mask) - *modifiers |= MINPUT_KEY_META_MODIFIER; - if (((XKeyEvent *) event)->state & disp_info->alt_mask) - *modifiers |= MINPUT_KEY_ALT_MODIFIER; - if (((XKeyEvent *) event)->state & disp_info->super_mask) - *modifiers |= MINPUT_KEY_SUPER_MODIFIER; - if (((XKeyEvent *) event)->state & disp_info->hyper_mask) - *modifiers |= MINPUT_KEY_HYPER_MODIFIER; - return key; -} + frame->font = mfont (); + { + int nfonts; + char **names = XListFonts (display, app_data.font, 1, &nfonts); + + if (nfonts > 0) + { + if (! xfont_parse_name (names[0], frame->font)) + { + /* The font name does not conform to XLFD. Try to open the + font and get XA_FONT property. */ + XFontStruct *xfont = XLoadQueryFont (display, names[0]); + nfonts = 0; + if (xfont) + { + unsigned long value; + char *name; -MText * -mwin__get_selection_text (MFrame *frame) -{ - return NULL; -} + if (XGetFontProperty (xfont, XA_FONT, &value) + && (name = ((char *) + XGetAtomName (display, (Atom) value)))) + { + if (xfont_parse_name (name, frame->font)) + nfonts = 1; + } + XFreeFont (display, xfont); + } + } + XFreeFontNames (names); + } + if (! nfonts) + xfont_parse_name (FALLBACK_FONT, frame->font); + } + face = mface_from_font (frame->font); + face->property[MFACE_FONTSET] = mfontset (NULL); + face->property[MFACE_FOREGROUND] = frame->foreground; + face->property[MFACE_BACKGROUND] = frame->background; + mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline)); + mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox)); + face->property[MFACE_VIDEOMODE] = frame->videomode; + mface_put_prop (face, Mhook_func, + mface_get_prop (mface__default, Mhook_func)); + face->property[MFACE_RATIO] = (void *) 100; + mplist_push (param, Mface, face); + M17N_OBJECT_UNREF (face); -void -mwin__dump_gc (MFrame *frame, MRealizedFace *rface) -{ - unsigned long valuemask = GCForeground | GCBackground | GCClipMask; - XGCValues values; - Display *display = FRAME_DISPLAY (frame); - GCInfo *info = rface->info; - int i; +#ifdef X_SET_ERROR_HANDLER + XSetErrorHandler (x_error_handler); + XSetIOErrorHandler (x_io_error_handler); +#endif - for (i = 0; i <= GC_INVERSE; i++) - { - XGetGCValues (display, info->gc[i], valuemask, &values); - fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i, - values.foreground, values.background); - fprintf (stderr, "\n"); - } + return device; } /*** @} */ @@ -2395,33 +2393,6 @@ mwin__dump_gc (MFrame *frame, MRealizedFace *rface) /* External API */ /*=*/ -/*** @addtogroup m17nFrame */ -/*** @{ */ -/*=*/ - -/***en - @name Variables: Keys of frame parameter (X specific). - - These are the symbols to use as parameter keys for the function - mframe () (which see). They are also keys of a frame property - except for #Mwidget. */ -/***ja - @name ÊÑ¿ô¡§ ¥Õ¥ì¡¼¥à¥Ñ¥é¥á¡¼¥¿ÍÑ¥­¡¼ (X ¸ÇÍ­). - - ´Ø¿ô mframe () ¤Î¥Ñ¥é¥á¡¼¥¿¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¥·¥ó¥Ü¥ë¡£( mframe - () ¤ÎÀâÌÀ»²¾È¡£) #Mwidget ¤ò½ü¤¤¤Æ¤Ï¥Õ¥ì¡¼¥à¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤Ç¤â¤¢ - ¤ë¡£ - */ - -/*=*/ -/*** @{ */ -/* Keywords for mwin__open_device (). */ -MSymbol Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap; - -/*** @} */ -/*** @} */ - -/*=*/ /*** @addtogroup m17nInputMethodWin */ /*=*/ /*** @{ */ @@ -2488,21 +2459,6 @@ MInputDriver minput_xim_driver = { xim_open_im, xim_close_im, xim_create_ic, xim_destroy_ic, xim_filter, xim_lookup, NULL }; -/*=*/ - -/***en - @brief Symbol of the name "xim". - - The variable Mxim is a symbol of name "xim". It is a name of the - input method driver #minput_xim_driver. */ -/***ja - @brief "xim"¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë . - - ÊÑ¿ô Mxim ¤Ï"xim"¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£"xim" ¤ÏÆþÎϥ᥽¥Ã - ¥É¥É¥é¥¤¥Ð #minput_xim_driver ¤Î̾Á°¤Ç¤¢¤ë¡£ */ - -MSymbol Mxim; - /*** @} */ /*