}
\f
-/* Functions for the device driver. */
-
-void
-mwin__close_device (MFrame *frame)
-{
- M17N_OBJECT_UNREF (FRAME_DEVICE (frame));
-}
+/** X font handler */
-void *
-mwin__device_get_prop (MFrame *frame, MSymbol key)
-{
- MWDevice *device = FRAME_DEVICE (frame);
+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 *, unsigned);
+static void xfont_render (MDrawWindow, int, int, MGlyphString *,
+ MGlyph *, MGlyph *, int, MDrawRegion);
- 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;
-}
+static MFontDriver xfont_driver =
+ { xfont_select, xfont_open,
+ xfont_find_metric, xfont_encode_char, xfont_render };
-void
-mwin__realize_face (MRealizedFace *rface)
+typedef struct
{
- MFrame *frame;
- MSymbol foreground, background, videomode;
- MFaceHLineProp *hline;
- MFaceBoxProp *box;
- GCInfo *info;
+ M17NObject control;
+ Display *display;
+ XFontStruct *xfont;
+} MXFontInfo;
- if (rface != rface->ascii_rface)
- {
- rface->info = rface->ascii_rface->info;
- return;
- }
+static MFontList *
+build_font_list (MFrame *frame, MSymbol family, MSymbol registry,
+ MPlist *plist)
+{
+ char pattern[1024];
+ MFontList *font_list;
+ char **fontnames;
+ int nfonts;
+ int i, j;
- frame = rface->frame;
- MSTRUCT_CALLOC (info, MERROR_WIN);
+ MSTRUCT_CALLOC (font_list, 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)
+ if (family == Mnil)
{
- info->gc[GC_NORMAL] = get_gc (frame, foreground, 1, &info->rgb_fore);
- info->gc[GC_INVERSE] = get_gc (frame, background, 0, &info->rgb_back);
+ sprintf (pattern, "-*-*-*-*-*-*-*-*-*-*-*-*-%s",
+ msymbol_name (registry));
+ font_list->tag = registry;
}
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;
+ sprintf (pattern, "-*-%s-*-*-*-*-*-*-*-*-*-*-%s",
+ msymbol_name (family), msymbol_name (registry));
+ font_list->tag = family;
}
- 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)
+ fontnames = XListFonts (FRAME_DISPLAY (frame), pattern, 0x8000, &nfonts);
+ if (nfonts > 0)
{
- if (hline->color)
- info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
- else
- info->gc[GC_HLINE] = info->gc[GC_NORMAL];
+ MTABLE_MALLOC (font_list->fonts, nfonts, MERROR_WIN);
+ for (i = j = 0; i < nfonts; i++)
+ if ((mfont__parse_name_into_font (fontnames[i], Mx,
+ 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;
}
+ mplist_add (plist, font_list->tag, font_list);
+ return (nfonts > 0 ? font_list : NULL);
+}
- 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];
+/* The X font driver function SELECT. */
- 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];
+static MRealizedFont *
+xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size)
+{
+ MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
+ MRealizedFont *rfont;
+ MFontList *font_list = NULL;
+ int i;
+ MFont *best_font;
+ int best_score, score;
- 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 (registry == Mnil
+ || ! strchr (MSYMBOL_NAME (registry), '-'))
+ return NULL;
- 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];
+ /* 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)
+ {
+ 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;
- rface->info = info;
-}
+ 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;
+ 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;
+ }
+ }
-void
-mwin__free_realized_face (MRealizedFace *rface)
-{
- if (rface == rface->ascii_rface)
- free (rface->info);
+ 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;
}
-void
-mwin__fill_space (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
- int reverse,
- int x, int y, int width, int height, MDrawRegion region)
-{
- GC gc = ((GCInfo *) rface->info)->gc[reverse ? GC_NORMAL : GC_INVERSE];
+/* The X font driver function CLOSE. */
- if (region)
- gc = set_region (frame, gc, region);
+static void
+close_xfont (void *object)
+{
+ MXFontInfo *xfont_info = object;
- XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
- x, y, width, height);
+ XFreeFont (xfont_info->display, xfont_info->xfont);
+ free (object);
}
-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];
+/* The X font driver function OPEN. */
- if (from == to)
- return;
+static int
+xfont_open (MRealizedFont *rfont)
+{
+ char *name;
+ MXFontInfo *xfont_info;
+ MFrame *frame = rfont->frame;
+ int mdebug_mask = MDEBUG_FONT;
- 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;
+ /* This never fail to generate a valid fontname because open_spec
+ should correspond to a font available on the system. */
+ name = mfont_unparse_name (&rfont->font, Mx);
+ 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);
+ free (name);
+ return -1;
}
+ rfont->info = xfont_info;
+ MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
+ free (name);
+ rfont->status = 1;
+ rfont->ascent = xfont_info->xfont->ascent;
+ rfont->descent = xfont_info->xfont->descent;
+ return 0;
}
-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;
-
- 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);
-
- for (i = 0; i < rface->hline->width; i++)
- XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
- x, y + i, x + width - 1, y + i);
-}
-
+/* The X font driver function FIND_METRIC. */
-void
-mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
- MGlyph *g, int x, int y, int width, MDrawRegion region)
+static void
+xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
+ int from, int to)
{
- 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;
-
- 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);
-
- 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];
+ MXFontInfo *xfont_info = rfont->info;
+ XFontStruct *xfont = xfont_info->xfont;
+ MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
- if (g->type == GLYPH_BOX)
+ for (; g != gend; g++)
{
- int x0, x1;
-
- if (g->left_padding)
- x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
+ 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
- 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);
+ {
+ int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
+ XCharStruct *pcm = NULL;
- /* 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 (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 (g->left_padding > 0)
- {
- /* Draw the left side. */
- if (info->gc[GC_BOX_LEFT] == info->gc[GC_BOX_TOP])
- gc_left = gc_top;
- else
+ if (pcm)
{
- gc_left = info->gc[GC_BOX_LEFT];
- if (region)
- gc_left = set_region (frame, gc_left, region);
+ g->lbearing = pcm->lbearing;
+ g->rbearing = pcm->rbearing;
+ g->width = pcm->width;
+ g->ascent = pcm->ascent;
+ g->descent = pcm->descent;
}
- for (i = 0; i < rface->box->width; i++)
- XDrawLine (display, (Window) win, gc_left,
- x0 + i, y0 + i, x0 + i, y1 - i);
- }
- else
- {
- /* 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);
+ /* 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;
}
- for (i = 0; i < rface->box->width; i++)
- XDrawLine (display, (Window) win, gc_right,
- x1 - i, y0 + i, x1 - i, y1 - i);
}
}
+}
+
+
+/* The X font driver function GET_GLYPH_ID. */
+
+static unsigned
+xfont_encode_char (MRealizedFont *rfont, unsigned code)
+{
+ MXFontInfo *xfont_info;
+ XFontStruct *xfont;
+ 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_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 (min_byte1 == 0 && max_byte1 == 0)
+ {
+ XCharStruct *pcm;
+
+ 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
{
- /* 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);
+ unsigned byte1 = code >> 8, byte2 = code & 0xFF;
+ XCharStruct *pcm;
- /* 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 (byte1 < min_byte1 || byte1 > max_byte1
+ || byte2 < min_byte2 || byte2 > max_byte2)
+ return MCHAR_INVALID_CODE;
+
+ 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);
}
}
+/* The X font driver function RENDER. */
-#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)
+static void
+xfont_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;
+ 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;
- 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);
-}
-#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;
+ /* It is assured that the all glyphs in the current range use the
+ same realized face. */
+ display = FRAME_DISPLAY (rface->frame);
- 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);
-
- XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
- (XPoint *) points, num, CoordModeOrigin);
-}
+ 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++)
+ {
+ code[i].byte1 = g->code >> 8;
+ code[i].byte2 = g->code & 0xFF;
+ }
+ 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;
-MDrawRegion
-mwin__region_from_rect (MDrawMetric *rect)
-{
- MDrawRegion region1 = XCreateRegion ();
- MDrawRegion region2 = XCreateRegion ();
- XRectangle xrect;
+ 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;
- xrect.x = rect->x;
- xrect.y = rect->y;
- xrect.width = rect->width;
- xrect.height = rect->height;
- XUnionRectWithRegion (&xrect, region1, region2);
- XDestroyRegion (region1);
- return region2;
+ 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__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
-{
- MDrawRegion region1 = XCreateRegion ();
- XRectangle xrect;
-
- xrect.x = rect->x;
- xrect.y = rect->y;
- xrect.width = rect->width;
- xrect.height = rect->height;
+\f
+/* Xft Handler */
- XUnionRegion (region, region, region1);
- XUnionRectWithRegion (&xrect, region1, region);
- XDestroyRegion (region1);
-}
+#ifdef HAVE_XFT2
-void
-mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
+typedef struct
{
- MDrawRegion region = XCreateRegion ();
+ M17NObject control;
+ Display *display;
+ XftFont *font_aa;
+ XftFont *font_no_aa;
+} MXftFontInfo;
- XUnionRegion (region1, region1, region);
- XIntersectRegion (region, region2, region1);
- XDestroyRegion (region);
-}
+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);
-void
-mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
-{
- MDrawRegion region1 = XCreateRegion ();
- XRectangle xrect;
+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 };
- xrect.x = rect->x;
- xrect.y = rect->y;
- xrect.width = rect->width;
- xrect.height = rect->height;
- XUnionRectWithRegion (&xrect, region1, region);
- XDestroyRegion (region1);
-}
-void
-mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
+static void
+close_xft (void *object)
{
- XRectangle xrect;
+ MXftFontInfo *font_info = object;
- XClipBox (region, &xrect);
- rect->x = xrect.x;
- rect->y = xrect.y;
- rect->width = xrect.width;
- rect->height = xrect.height;
+ XftFontClose (font_info->display, font_info->font_aa);
+ XftFontClose (font_info->display, font_info->font_no_aa);
+ free (font_info);
}
-void
-mwin__free_region (MDrawRegion region)
-{
- XDestroyRegion (region);
-}
-void
-mwin__dump_region (MDrawRegion region)
+static XftFont *
+xft_open_font (MFrame *frame, MFTInfo *ft_info, int size, int anti_alias)
{
- XRectangle rect;
- XClipBox (region, &rect);
- fprintf (stderr, "(%d %d %d %d)\n", rect.x, rect.y, rect.width, rect.height);
+ XftPattern *pattern;
+ XftFontInfo *xft_font_info;
+ XftFont *font;
+
+ 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;
}
-MDrawWindow
-mwin__create_window (MFrame *frame, MDrawWindow parent)
+static int
+xft_open (MRealizedFont *rfont)
{
- 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;
+ MFrame *frame;
+ MFTInfo *ft_info;
+ MXftFontInfo *font_info;
+ int size;
- 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;
-}
+ if ((mfont__ft_driver.open) (rfont) < 0)
+ return -1;
-void
-mwin__destroy_window (MFrame *frame, MDrawWindow win)
-{
- XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
-}
+ size = rfont->font.property[MFONT_SIZE] / 10;
+ frame = rfont->frame;
-#if 0
-MDrawWindow
-mwin__event_window (void *event)
-{
- return ((MDrawWindow) ((XEvent *) event)->xany.window);
+ 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)
+ {
+ 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;
}
-void
-mwin__print_event (void *arg, char *win_name)
+
+static void
+xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
+ int from, int to)
{
- char *event_name;
- XEvent *event = (XEvent *) arg;
+ MFTInfo *ft_info = rfont->info;
+ MXftFontInfo *font_info = ft_info->extra_info;
+ MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
- switch (event->xany.type)
+ for (; g != gend; g++)
{
- 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";
+ 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;
+
+ XftGlyphExtents (FRAME_DISPLAY (rfont->frame),
+ font_info->font_aa, &g->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;
+ }
}
+}
- fprintf (stderr, "%s: %s\n", win_name, event_name);
+
+static void
+xft_render (MDrawWindow win, int x, int y,
+ MGlyphString *gstring, MGlyph *from, MGlyph *to,
+ int reverse, MDrawRegion region)
+{
+ MRealizedFace *rface = from->rface;
+ MFrame *frame = rface->frame;
+ MFTInfo *ft_info = rface->rfont->info;
+ MXftFontInfo *font_info = ft_info->extra_info;
+ 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 (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)
+ {
+ if (g->xoff == 0 && g->yoff == 0)
+ glyphs[nglyphs++] = g->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 *) &g->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__map_window (MFrame *frame, MDrawWindow win)
+\f
+/* Functions for the device driver. */
+
+static int
+mwin__device_init ()
{
- XMapRaised (FRAME_DISPLAY (frame), (Window) win);
+ M_iso8859_1 = msymbol ("iso8859-1");
+ M_iso10646_1 = msymbol ("iso10646-1");
+
+ display_info_list = mplist ();
+ device_list = mplist ();
+
+ Mxim = msymbol ("xim");
+ msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
+
+ return 0;
}
-void
-mwin__unmap_window (MFrame *frame, MDrawWindow win)
+static int
+mwin__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. */
+
+static int
+mwin__open_device (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;
-
- 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;
+ unsigned depth = 0;
+ MPlist *plist;
+ AppData app_data;
+ MFace *face;
- if (! parent)
- parent = RootWindow (display, FRAME_SCREEN (frame));
- while (1)
+ for (plist = param; (key = mplist_key (plist)) != Mnil;
+ plist = mplist_next (plist))
{
- Window this_parent, *children;
- unsigned n;
-
- 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 (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);
}
-}
-
-void
-mwin__adjust_window (MFrame *frame, MDrawWindow win,
- MDrawMetric *current, MDrawMetric *new)
-{
- Display *display = FRAME_DISPLAY (frame);
- unsigned int mask = 0;
- XWindowChanges values;
- if (current->width != new->width)
+ if (widget)
{
- mask |= CWWidth;
- if (new->width <= 0)
- new->width = 1;
- values.width = current->width = new->width;
+ display = XtDisplay (widget);
+ screen_num = XScreenNumberOfScreen (XtScreen (widget));
+ depth = DefaultDepth (display, screen_num);
}
- if (current->height != new->height)
+ else if (drawable)
{
- mask |= CWHeight;
- if (new->height <= 0)
- new->height = 1;
- values.height = current->height = new->height;
+ Window root_window;
+ int x, y;
+ unsigned width, height, border_width;
+
+ if (! display)
+ MERROR (MERROR_WIN, -1);
+ XGetGeometry (display, drawable, &root_window,
+ &x, &y, &width, &height, &border_width, &depth);
+ XGetWindowAttributes (display, root_window, &attr);
+ screen_num = XScreenNumberOfScreen (attr.screen);
}
- if (current->x != new->x)
+ else
{
- mask |= CWX;
- values.x = current->x = new->x;
+ if (screen)
+ display = DisplayOfScreen (screen);
+ else
+ {
+ if (! display)
+ {
+ display = XOpenDisplay (NULL);
+ if (! display)
+ MERROR (MERROR_WIN, -1);
+ auto_display = 1;
+ }
+ screen = DefaultScreenOfDisplay (display);
+ }
+ screen_num = XScreenNumberOfScreen (screen);
+ if (! depth)
+ depth = DefaultDepth (display, screen_num);
}
- if (current->y != new->y)
+
+ if (! cmap)
+ cmap = DefaultColormap (display, screen_num);
+
+ for (plist = display_info_list; mplist_key (plist) != Mnil;
+ plist = mplist_next (plist))
{
- mask |= CWY;
- current->y = new->y;
- values.y = current->y = new->y;
+ disp_info = (MDisplayInfo *) mplist_value (plist);
+ if (disp_info->display == display)
+ break;
}
- 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 (frame)->display_info;
- int len;
- char buf[512];
- KeySym keysym;
- MSymbol key;
-
- *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 (mplist_key (plist) != Mnil)
+ M17N_OBJECT_REF (disp_info);
+ else
{
- int c = keysym;
+ 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 (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);
+ 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;
}
- else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
- return Mnil;
+
+ if (mplist_key (plist) != Mnil)
+ M17N_OBJECT_REF (device);
else
{
- char *str = XKeysymToString (keysym);
+ unsigned long valuemask = GCForeground;
+ XGCValues values;
- 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;
+ 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 (((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->device = device;
+ frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT;
+ 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);
+#elif HAVE_FREETYPE
+ 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;
+
+ 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 }
+ };
+
+ 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
+ {
+ app_data.font = DEFAULT_FONT;
+ frame->foreground = msymbol ("black");
+ frame->background = msymbol ("white");
+ frame->videomode = Mnormal;
+ }
+
+ {
+ int nfonts;
+ char **names = XListFonts (display, app_data.font, 1, &nfonts);
+
+ if (nfonts > 0)
+ {
+ if (! (frame->font = mfont_parse_name (names[0], Mx)))
+ {
+ /* 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 ((frame->font = mfont_parse_name (name, Mx)))
+ nfonts = 1;
+ }
+ XFreeFont (display, xfont);
+ }
+ }
+ XFreeFontNames (names);
+ }
+ if (! nfonts)
+ frame->font = mfont_parse_name (FALLBACK_FONT, Mx);
+ }
+
+ 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 0;
}
-MText *
-mwin__get_selection_text (MFrame *frame)
+static void
+mwin__close_device (MFrame *frame)
{
- return NULL;
+ M17N_OBJECT_UNREF (FRAME_DEVICE (frame));
}
+static void *
+mwin__device_get_prop (MFrame *frame, MSymbol key)
+{
+ MWDevice *device = FRAME_DEVICE (frame);
-void
-mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
+ 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;
+}
+
+static void
+mwin__realize_face (MRealizedFace *rface)
{
- unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
- XGCValues values;
- Display *display = FRAME_DISPLAY (frame);
- GCInfo *info = rface->info;
- int i;
+ MFrame *frame;
+ MSymbol foreground, background, videomode;
+ MFaceHLineProp *hline;
+ MFaceBoxProp *box;
+ GCInfo *info;
- for (i = 0; i <= GC_INVERSE; i++)
+ if (rface != rface->ascii_rface)
{
- XGetGCValues (display, info->gc[i], valuemask, &values);
- fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
- values.foreground, values.background);
- fprintf (stderr, "\n");
+ rface->info = rface->ascii_rface->info;
+ return;
}
-}
-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
- };
+ frame = rface->frame;
+ MSTRUCT_CALLOC (info, MERROR_WIN);
-\f
-/** X font handler */
+ 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
-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 *, unsigned);
-static void xfont_render (MDrawWindow, int, int, MGlyphString *,
- MGlyph *, MGlyph *, int, MDrawRegion);
+ hline = rface->hline;
+ if (hline)
+ {
+ if (hline->color)
+ info->gc[GC_HLINE] = get_gc (frame, hline->color, 1, NULL);
+ else
+ info->gc[GC_HLINE] = info->gc[GC_NORMAL];
+ }
-static MFontDriver xfont_driver =
- { xfont_select, xfont_open,
- xfont_find_metric, xfont_encode_char, xfont_render };
+ 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];
-typedef struct
+ 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];
+ }
+
+ rface->info = info;
+}
+
+
+static void
+mwin__free_realized_face (MRealizedFace *rface)
{
- M17NObject control;
- Display *display;
- XFontStruct *xfont;
-} MXFontInfo;
+ if (rface == rface->ascii_rface)
+ free (rface->info);
+}
-static MFontList *
-build_font_list (MFrame *frame, MSymbol family, MSymbol registry,
- MPlist *plist)
+
+static 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)
+
+static 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 ((mfont__parse_name_into_font (fontnames[i], Mx,
- 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);
}
-/* The X font driver function SELECT. */
-static MRealizedFont *
-xfont_select (MFrame *frame, MFont *spec, MFont *request, int limited_size)
+static void
+mwin__draw_hline (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
+ MRealizedFace *rface, int reverse,
+ int x, int y, int width, MDrawRegion region)
{
- MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
- MRealizedFont *rfont;
- MFontList *font_list = NULL;
+ enum MFaceHLineType type = rface->hline->type;
+ GCInfo *info = rface->info;
+ GC gc = gc = info->gc[GC_HLINE];
int i;
- MFont *best_font;
- int best_score, score;
- if (registry == Mnil
- || ! strchr (MSYMBOL_NAME (registry), '-'))
- return NULL;
+ 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);
+
+ for (i = 0; i < rface->hline->width; i++)
+ XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
+ x, y + i, x + width - 1, y + i);
+}
+
+
+static void
+mwin__draw_box (MFrame *frame, MDrawWindow win, MGlyphString *gstring,
+ MGlyph *g, int x, int y, int width, MDrawRegion region)
+{
+ 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;
+
+ 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);
+
+ 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)
+ {
+ 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;
+
+ /* Draw the top side. */
+ for (i = 0; i < box->width; i++)
+ XDrawLine (display, (Window) win, gc_top, x0, y0 + i, x1, y0 + i);
- /* 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)
- {
- 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);
+ /* 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 (family != Mnil)
+ 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 (frame)->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;
- return rfont;
-}
+#if 0
+static 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);
-/* The X font driver function CLOSE. */
+ 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
static void
-close_xfont (void *object)
+mwin__draw_points (MFrame *frame, MDrawWindow win, MRealizedFace *rface,
+ int intensity, MDrawPoint *points, int num,
+ MDrawRegion region)
{
- MXFontInfo *xfont_info = object;
+ GCInfo *info = rface->info;
+ GC gc;
- XFreeFont (xfont_info->display, xfont_info->xfont);
- free (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);
+ XDrawPoints (FRAME_DISPLAY (frame), (Window) win, gc,
+ (XPoint *) points, num, CoordModeOrigin);
+}
-/* The X font driver function OPEN. */
-static int
-xfont_open (MRealizedFont *rfont)
+static MDrawRegion
+mwin__region_from_rect (MDrawMetric *rect)
{
- char *name;
- MXFontInfo *xfont_info;
- 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. */
- name = mfont_unparse_name (&rfont->font, Mx);
- 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);
- free (name);
- return -1;
- }
- rfont->info = xfont_info;
- MDEBUG_PRINT1 (" [XFONT] o %s\n", name);
- free (name);
- rfont->status = 1;
- rfont->ascent = xfont_info->xfont->ascent;
- rfont->descent = xfont_info->xfont->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;
}
-
-/* The X font driver function FIND_METRIC. */
-
static void
-xfont_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
- int from, int to)
+mwin__union_rect_with_region (MDrawRegion region, MDrawMetric *rect)
{
- MXFontInfo *xfont_info = rfont->info;
- XFontStruct *xfont = xfont_info->xfont;
- MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
-
- for (; g != gend; g++)
- {
- 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;
+ MDrawRegion region1 = XCreateRegion ();
+ XRectangle xrect;
- 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));
- }
- }
- }
+ xrect.x = rect->x;
+ xrect.y = rect->y;
+ xrect.width = rect->width;
+ xrect.height = rect->height;
- 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;
- }
- }
- }
+ XUnionRegion (region, region, region1);
+ XUnionRectWithRegion (&xrect, region1, region);
+ XDestroyRegion (region1);
}
-
-/* The X font driver function GET_GLYPH_ID. */
-
-static unsigned
-xfont_encode_char (MRealizedFont *rfont, unsigned code)
+static void
+mwin__intersect_region (MDrawRegion region1, MDrawRegion region2)
{
- MXFontInfo *xfont_info;
- XFontStruct *xfont;
- 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_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 (min_byte1 == 0 && max_byte1 == 0)
- {
- XCharStruct *pcm;
+ MDrawRegion region = XCreateRegion ();
- 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
- {
- unsigned byte1 = code >> 8, byte2 = code & 0xFF;
- XCharStruct *pcm;
+ XUnionRegion (region1, region1, region);
+ XIntersectRegion (region, region2, region1);
+ XDestroyRegion (region);
+}
- if (byte1 < min_byte1 || byte1 > max_byte1
- || byte2 < min_byte2 || byte2 > max_byte2)
- return MCHAR_INVALID_CODE;
+static void
+mwin__region_add_rect (MDrawRegion region, MDrawMetric *rect)
+{
+ MDrawRegion region1 = XCreateRegion ();
+ XRectangle xrect;
- 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);
- }
+ xrect.x = rect->x;
+ xrect.y = rect->y;
+ xrect.width = rect->width;
+ xrect.height = rect->height;
+ XUnionRectWithRegion (&xrect, region1, region);
+ XDestroyRegion (region1);
}
-/* 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)
+mwin__region_to_rect (MDrawRegion region, MDrawMetric *rect)
{
- 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;
+ XRectangle xrect;
- if (from == to)
- return;
+ XClipBox (region, &xrect);
+ rect->x = xrect.x;
+ rect->y = xrect.y;
+ rect->width = xrect.width;
+ rect->height = xrect.height;
+}
- /* It is assured that the all glyphs in the current range use the
- same realized face. */
- display = FRAME_DISPLAY (rface->frame);
+static void
+mwin__free_region (MDrawRegion region)
+{
+ XDestroyRegion (region);
+}
- 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++)
- {
- code[i].byte1 = g->code >> 8;
- code[i].byte2 = g->code & 0xFF;
- }
+static 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);
+}
- 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;
+static MDrawWindow
+mwin__create_window (MFrame *frame, MDrawWindow parent)
+{
+ 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;
- 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);
- }
- }
+ 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;
}
-\f
-/* Xft Handler */
-
-#ifdef HAVE_XFT2
+static void
+mwin__destroy_window (MFrame *frame, MDrawWindow win)
+{
+ XDestroyWindow (FRAME_DISPLAY (frame), (Window) win);
+}
-typedef struct
+#if 0
+static MDrawWindow
+mwin__event_window (void *event)
{
- M17NObject control;
- Display *display;
- XftFont *font_aa;
- XftFont *font_no_aa;
-} MXftFontInfo;
+ return ((MDrawWindow) ((XEvent *) event)->xany.window);
+}
-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);
+static void
+mwin__print_event (void *arg, char *win_name)
+{
+ char *event_name;
+ XEvent *event = (XEvent *) arg;
-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 };
+ 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";
+ }
+ fprintf (stderr, "%s: %s\n", win_name, event_name);
+}
+#endif
static void
-close_xft (void *object)
+mwin__map_window (MFrame *frame, MDrawWindow win)
{
- MXftFontInfo *font_info = object;
-
- XftFontClose (font_info->display, font_info->font_aa);
- XftFontClose (font_info->display, font_info->font_no_aa);
- free (font_info);
+ XMapRaised (FRAME_DISPLAY (frame), (Window) win);
}
-
-static XftFont *
-xft_open_font (MFrame *frame, MFTInfo *ft_info, int size, int anti_alias)
+static void
+mwin__unmap_window (MFrame *frame, MDrawWindow win)
{
- XftPattern *pattern;
- XftFontInfo *xft_font_info;
- XftFont *font;
-
- 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;
+ XUnmapWindow (FRAME_DISPLAY (frame), (Window) win);
}
-
-static int
-xft_open (MRealizedFont *rfont)
+static void
+mwin__window_geometry (MFrame *frame, MDrawWindow win, MDrawWindow parent_win,
+ MDrawMetric *geometry)
{
- MFrame *frame;
- MFTInfo *ft_info;
- MXftFontInfo *font_info;
- int size;
-
- if ((mfont__ft_driver.open) (rfont) < 0)
- return -1;
+ Display *display = FRAME_DISPLAY (frame);
+ XWindowAttributes attr;
+ Window parent = (Window) parent_win, root;
- size = rfont->font.property[MFONT_SIZE] / 10;
- frame = rfont->frame;
+ 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;
- 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)
+ if (! parent)
+ parent = RootWindow (display, FRAME_SCREEN (frame));
+ while (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);
+ Window this_parent, *children;
+ unsigned n;
+
+ 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;
}
- free (font_info);
- ft_info->extra_info = NULL;
- rfont->status = -1;
- return -1;
}
-
static void
-xft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
- int from, int to)
+mwin__adjust_window (MFrame *frame, MDrawWindow win,
+ MDrawMetric *current, MDrawMetric *new)
{
- MFTInfo *ft_info = rfont->info;
- MXftFontInfo *font_info = ft_info->extra_info;
- MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
+ Display *display = FRAME_DISPLAY (frame);
+ unsigned int mask = 0;
+ XWindowChanges values;
- for (; g != gend; g++)
+ if (current->width != new->width)
{
- if (g->code == MCHAR_INVALID_CODE)
- {
- MGlyph *start = g++;
+ 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);
+}
- 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;
+static MSymbol
+mwin__parse_event (MFrame *frame, void *arg, int *modifiers)
+{
+ XEvent *event = (XEvent *) arg;
+ MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info;
+ int len;
+ char buf[512];
+ KeySym keysym;
+ MSymbol key;
- XftGlyphExtents (FRAME_DISPLAY (rfont->frame),
- font_info->font_aa, &g->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;
+ *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);
+
+ 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;
+
+ return key;
}
-void
-xft_render (MDrawWindow win, int x, int y,
- MGlyphString *gstring, MGlyph *from, MGlyph *to,
- int reverse, MDrawRegion region)
+void
+mwin__dump_gc (MFrame *frame, MRealizedFace *rface)
{
- MRealizedFace *rface = from->rface;
- MFrame *frame = rface->frame;
- MFTInfo *ft_info = rface->rfont->info;
- MXftFontInfo *font_info = ft_info->extra_info;
- 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 (from == to)
- return;
+ unsigned long valuemask = GCForeground | GCBackground | GCClipMask;
+ XGCValues values;
+ Display *display = FRAME_DISPLAY (frame);
+ GCInfo *info = rface->info;
+ int 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)
+ for (i = 0; i <= GC_INVERSE; i++)
{
- if (g->xoff == 0 && g->yoff == 0)
- glyphs[nglyphs++] = g->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 *) &g->code, 1);
- last_x = x + g->width;
- }
+ XGetGCValues (display, info->gc[i], valuemask, &values);
+ fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,
+ values.foreground, values.background);
+ fprintf (stderr, "\n");
}
- if (nglyphs > 0)
- XftDrawGlyphs (xft_draw, xft_color, xft_font, last_x, y, glyphs, nglyphs);
}
-#endif
+static MDeviceDriver x_driver =
+ {
+ 0,
+ mwin__device_init,
+ mwin__device_fini,
+ mwin__open_device,
+ 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
+ };
\f
{
MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) im->info;
- XCloseIM (im_info->xim);
- free (im_info);
-}
-
-static int
-xim_create_ic (MInputContext *ic)
-{
- MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
- MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
- MInputXIMContextInfo *ic_info;
- XIC xic;
-
- if (! arg->input_style)
- {
- /* By default, use Root style. */
- arg->input_style = XIMPreeditNothing | XIMStatusNothing;
- arg->preedit_attrs = NULL;
- arg->status_attrs = 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);
- 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;
-}
-
-static void
-xim_destroy_ic (MInputContext *ic)
-{
- MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
-
- XDestroyIC (ic_info->xic);
- mconv_free_converter (ic_info->converter);
- free (ic_info);
- ic->info = NULL;
-}
-
-static int
-xim_filter (MInputContext *ic, MSymbol key, void *event)
-{
- MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
-
- return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
-}
-
-
-static int
-xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
-{
- 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;
-
- 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;
-}
-
-\f
-
-#ifdef X_SET_ERROR_HANDLER
-static int
-x_error_handler (Display *display, XErrorEvent *error)
-{
- mdebug_hook ();
- return 0;
-}
-
-static int
-x_io_error_handler (Display *display)
-{
- mdebug_hook ();
- return 0;
-}
-#endif
-
-\f
-
-/* Functions to be stored in MDeviceLibraryInterface by dlsym (). */
-
-int
-device_init ()
-{
- M_iso8859_1 = msymbol ("iso8859-1");
- M_iso10646_1 = msymbol ("iso10646-1");
-
- display_info_list = mplist ();
- device_list = mplist ();
-
-#ifdef HAVE_XFT2
- xft_driver.select = mfont__ft_driver.select;
- xft_driver.encode_char = mfont__ft_driver.encode_char;
-#endif
-
- Mxim = msymbol ("xim");
- msymbol_put (Mxim, Minput_driver, &minput_xim_driver);
-
- return 0;
-}
-
-int
-device_fini ()
-{
- M17N_OBJECT_UNREF (display_info_list);
- M17N_OBJECT_UNREF (device_list);
- return 0;
-}
-
-/** 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 = 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;
-
- 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 (widget)
- {
- 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;
-
- 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);
- }
+ XCloseIM (im_info->xim);
+ free (im_info);
+}
- if (! cmap)
- cmap = DefaultColormap (display, screen_num);
+static int
+xim_create_ic (MInputContext *ic)
+{
+ MInputXIMArgIC *arg = (MInputXIMArgIC *) ic->arg;
+ MInputXIMMethodInfo *im_info = (MInputXIMMethodInfo *) ic->im->info;
+ MInputXIMContextInfo *ic_info;
+ XIC xic;
- for (plist = display_info_list; mplist_key (plist) != Mnil;
- plist = mplist_next (plist))
+ if (! arg->input_style)
{
- disp_info = (MDisplayInfo *) mplist_value (plist);
- if (disp_info->display == display)
- break;
+ /* By default, use Root style. */
+ arg->input_style = XIMPreeditNothing | XIMStatusNothing;
+ arg->preedit_attrs = NULL;
+ arg->status_attrs = NULL;
}
- if (mplist_key (plist) != Mnil)
- M17N_OBJECT_REF (disp_info);
+ 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
- {
- 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);
- }
+ 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);
- 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;
- }
+ 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;
+}
- if (mplist_key (plist) != Mnil)
- M17N_OBJECT_REF (device);
- else
- {
- unsigned long valuemask = GCForeground;
- XGCValues values;
+static void
+xim_destroy_ic (MInputContext *ic)
+{
+ MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
- 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
- }
+ XDestroyIC (ic_info->xic);
+ mconv_free_converter (ic_info->converter);
+ free (ic_info);
+ ic->info = NULL;
+}
- 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);
-#elif HAVE_FREETYPE
- 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;
+static int
+xim_filter (MInputContext *ic, MSymbol key, void *event)
+{
+ MInputXIMContextInfo *ic_info = (MInputXIMContextInfo *) ic->info;
- 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 }
- };
+ return (XFilterEvent ((XEvent *) event, ic_info->win) == True);
+}
- 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
- {
- app_data.font = DEFAULT_FONT;
- frame->foreground = msymbol ("black");
- frame->background = msymbol ("white");
- frame->videomode = Mnormal;
- }
- {
- int nfonts;
- char **names = XListFonts (display, app_data.font, 1, &nfonts);
+static int
+xim_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
+{
+ 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 (nfonts > 0)
- {
- if (! (frame->font = mfont_parse_name (names[0], Mx)))
- {
- /* The font name does not conform to XLFD. Try to open the
- font and get XA_FONT property. */
- XFontStruct *xfont = XLoadQueryFont (display, names[0]);
+ 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);
+ }
- nfonts = 0;
- if (xfont)
- {
- unsigned long value;
- char *name;
+ mtext_reset (ic->produced);
+ if (len == 0)
+ return 1;
- if (XGetFontProperty (xfont, XA_FONT, &value)
- && (name = ((char *)
- XGetAtomName (display, (Atom) value))))
- {
- if ((frame->font = mfont_parse_name (name, Mx)))
- nfonts = 1;
- }
- XFreeFont (display, xfont);
- }
- }
- XFreeFontNames (names);
- }
- if (! nfonts)
- frame->font = mfont_parse_name (FALLBACK_FONT, Mx);
- }
+ 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;
+}
- 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);
+\f
#ifdef X_SET_ERROR_HANDLER
- XSetErrorHandler (x_error_handler);
- XSetIOErrorHandler (x_io_error_handler);
-#endif
+static int
+x_error_handler (Display *display, XErrorEvent *error)
+{
+ mdebug_hook ();
+ return 0;
+}
- return device;
+static int
+x_io_error_handler (Display *display)
+{
+ mdebug_hook ();
+ return 0;
}
+#endif
/*** @} */
#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
\f
/* External API */
+int
+m17n_init_X ()
+{
+ x_driver.initialized = 0;
+ mplist_put (m17n__device_library_list, Mx, &x_driver);
+
+#ifdef HAVE_XFT2
+ xft_driver.select = mfont__ft_driver.select;
+ xft_driver.encode_char = mfont__ft_driver.encode_char;
+#endif
+
+ return 0;
+}
+
/*=*/
/*** @addtogroup m17nInputMethodWin */
/*=*/