static void FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width, Bool stopAtWordBreak, XawTextPosition *resPos, int *resWidth, int *resHeight) { MultiSinkObject sink = (MultiSinkObject)w; TextWidget ctx = (TextWidget)XtParent(w); Widget source = ctx->text.source; XFontSet fontset = sink->multi_sink.fontset; XawTextPosition idx, pos, whiteSpacePosition = 0; int i, lastWidth, whiteSpaceWidth, rWidth; Boolean whiteSpaceSeen; wchar_t c; XFontSetExtents *ext = XExtentsOfFontSet(fontset); XawTextBlock blk; pos = XawTextSourceRead(source, fromPos, &blk, BUFSIZ); rWidth = lastWidth = whiteSpaceWidth = 0; whiteSpaceSeen = False; c = 0; for (i = 0, idx = fromPos; rWidth <= width; i++, idx++) { if (i >= blk.length) { i = 0; pos = XawTextSourceRead(source, pos, &blk, BUFSIZ); if (blk.length == 0) break; } c = ((wchar_t *)blk.ptr)[i]; lastWidth = rWidth; rWidth += CharWidth(sink, fontset, fromx + rWidth, c); if (c == _Xaw_atowc(XawLF)) { idx++; break; } else if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB)) && rWidth <= width) { whiteSpaceSeen = True; whiteSpacePosition = idx; whiteSpaceWidth = rWidth; } } if (rWidth > width && idx > fromPos) { idx--; rWidth = lastWidth; if (stopAtWordBreak && whiteSpaceSeen) { idx = whiteSpacePosition + 1; rWidth = whiteSpaceWidth; } } if (idx >= ctx->text.lastPos && c != _Xaw_atowc(XawLF)) idx = ctx->text.lastPos + 1; *resPos = idx; *resWidth = rWidth; *resHeight = ext->max_logical_extent.height; }
static void FindPosition( Widget w, XawTextPosition fromPos, /* Starting position. */ int fromx, /* Horizontal location of starting position. */ int width, /* Desired width. */ Boolean stopAtWordBreak, /* Whether the resulting position should be at a word break. */ XawTextPosition * resPos, /* Resulting position. */ int *resWidth, /* Actual width used. */ int *resHeight) /* Height required. */ { MultiSinkObject sink = (MultiSinkObject) w; Widget source = XawTextGetSource(XtParent(w)); XawTextPosition lastPos, inx, whiteSpacePosition = 0; int lastWidth = 0, whiteSpaceWidth = 0; Boolean whiteSpaceSeen; wchar_t c; XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); XawTextBlock blk; lastPos = GETLASTPOS; XawTextSourceRead(source, fromPos, &blk, BUFSIZ); *resWidth = 0; whiteSpaceSeen = FALSE; c = 0; for (inx = fromPos; *resWidth <= width && inx < lastPos; inx++) { lastWidth = *resWidth; if (inx - blk.firstPos >= blk.length) XawTextSourceRead(source, inx, &blk, BUFSIZ); c = ((wchar_t *) blk.ptr)[inx - blk.firstPos]; *resWidth += CharWidth(w, fromx + *resWidth, c); if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB)) && *resWidth <= width) { whiteSpaceSeen = TRUE; whiteSpacePosition = inx; whiteSpaceWidth = *resWidth; } if (c == _Xaw_atowc(XawLF)) { inx++; break; } } if (*resWidth > width && inx > fromPos) { *resWidth = lastWidth; inx--; if (stopAtWordBreak && whiteSpaceSeen) { inx = whiteSpacePosition + 1; *resWidth = whiteSpaceWidth; } } if (inx == lastPos && c != _Xaw_atowc(XawLF)) inx = lastPos + 1; *resPos = inx; *resHeight = ext->max_logical_extent.height; }
/* * Implementation */ static int CharWidth(MultiSinkObject sink, XFontSet fontset, int x, wchar_t c) { int width = 0; if (c == _Xaw_atowc(XawLF)) return (0); if (c == _Xaw_atowc(XawTAB)) { int i; Position *tab; width = x; /* Adjust for Left Margin. */ x -= ((TextWidget)XtParent((Widget)sink))->text.left_margin; i = 0; tab = sink->text_sink.tabs; /*CONSTCOND*/ while (1) { if (x < *tab) return (*tab - x); /* Start again */ if (++i >= sink->text_sink.tab_count) { x -= *tab; i = 0; tab = sink->text_sink.tabs; if (width == x) return (0); } else ++tab; } /*NOTREACHED*/ } if (XwcTextEscapement(fontset, &c, 1) == 0) { if (sink->multi_sink.display_nonprinting) c = _Xaw_atowc('@'); else c = _Xaw_atowc(XawSP); } /* * if more efficiency(suppose one column is one ASCII char) width = XwcGetColumn(fontset->font_charset, fontset->num_of_fonts, c) * fontset->font_struct_list[0]->min_bounds.width; * * WARNING: Very Slower!!! * * Li Yuhong. */ width = XwcTextEscapement(fontset, &c, 1); return (width); }
static int CharWidth(Widget w, int x, wchar_t c) { int i, width; MultiSinkObject sink = (MultiSinkObject) w; XFontSet fontset = sink->multi_sink.fontset; Position *tab; if (c == _Xaw_atowc(XawLF)) return (0); if (c == _Xaw_atowc(XawTAB)) { /* Adjust for Left Margin. */ x -= ((TextWidget) XtParent(w))->text.margin.left; if (x >= (int) XtParent(w)->core.width) return 0; for (i = 0, tab = sink->text_sink.tabs; i < sink->text_sink.tab_count; i++, tab++) { if (x < *tab) { if (*tab < (int) XtParent(w)->core.width) return *tab - x; else return 0; } } return 0; } if (XwcTextEscapement(fontset, &c, 1) == 0) { if (sink->multi_sink.display_nonprinting) c = _Xaw_atowc('@'); else { c = _Xaw_atowc(XawSP); } } /* * if more efficiency(suppose one column is one ASCII char) width = XwcGetColumn(fontset->font_charset, fontset->num_of_fonts, c) * fontset->font_struct_list[0]->min_bounds.width; * * WARNING: Very Slower!!! * * Li Yuhong. */ width = XwcTextEscapement(fontset, &c, 1); return width; }
/* * Given two positions, find the distance between them. */ static void FindDistance( Widget w, XawTextPosition fromPos, /* First position. */ int fromx, /* Horizontal location of first position. */ XawTextPosition toPos, /* Second position. */ int *resWidth, /* Distance between fromPos and resPos. */ XawTextPosition * resPos, /* Actual second position used. */ int *resHeight) /* Height required. */ { MultiSinkObject sink = (MultiSinkObject) w; Widget source = XawTextGetSource(XtParent(w)); XawTextPosition inx, lastPos; wchar_t c; XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); XawTextBlock blk; /* we may not need this */ lastPos = GETLASTPOS; XawTextSourceRead(source, fromPos, &blk, (int) (toPos - fromPos)); *resWidth = 0; for (inx = fromPos; inx != toPos && inx < lastPos; inx++) { if (inx - blk.firstPos >= blk.length) XawTextSourceRead(source, inx, &blk, (int) (toPos - fromPos)); c = ((wchar_t *) blk.ptr)[inx - blk.firstPos]; *resWidth += CharWidth(w, fromx + *resWidth, c); if (c == _Xaw_atowc(XawLF)) { inx++; break; } } *resPos = inx; *resHeight = ext->max_logical_extent.height; }
int _Xaw_iswspace(wchar_t w) { int ret = 0; wchar_t s = _Xaw_atowc(' '); if (s == w) ret = 1; return (ret); }
/* * Function: * GetCursorBounds * * Parameters: * w - text sink object * rect - X rectangle to return the cursor bounds * * Description: * Returns the size and location of the cursor. */ static void GetCursorBounds(Widget w, XRectangle *rect) { MultiSinkObject sink = (MultiSinkObject)w; rect->width = CharWidth(sink, sink->multi_sink.fontset, 0, _Xaw_atowc(XawSP)); rect->height = (XExtentsOfFontSet(sink->multi_sink.fontset) ->max_logical_extent.height); rect->x = sink->multi_sink.cursor_x; rect->y = sink->multi_sink.cursor_y - (short)rect->height; }
int _XawImWcLookupString(Widget inwidg, XKeyPressedEvent *event, wchar_t* buffer_return, int bytes_buffer, KeySym *keysym_return) { XawVendorShellExtPart* ve; VendorShellWidget vw; XawIcTableList p; int i, ret; char tmp_buf[64], *tmp_p; wchar_t* buf_p; if ((vw = SearchVendorShell(inwidg)) && (ve = GetExtPart(vw)) && ve->im.xim && (p = GetIcTableShared(inwidg, ve)) && p->xic) { return(XwcLookupString(p->xic, event, buffer_return, bytes_buffer/sizeof(wchar_t), keysym_return, NULL)); } ret = XLookupString( event, tmp_buf, sizeof(tmp_buf), keysym_return, NULL ); for ( i = 0, tmp_p = tmp_buf, buf_p = buffer_return; i < ret; i++ ) { *buf_p++ = _Xaw_atowc(*tmp_p++); } return( ret ); }
/* * Given two positions, find the distance between them */ static void FindDistance(Widget w, XawTextPosition fromPos, int fromx, XawTextPosition toPos, int *resWidth, XawTextPosition *resPos, int *resHeight) { MultiSinkObject sink = (MultiSinkObject)w; XFontSet fontset = sink->multi_sink.fontset; TextWidget ctx = (TextWidget)XtParent(w); Widget source = ctx->text.source; XawTextPosition idx, pos; wchar_t c; XFontSetExtents *ext = XExtentsOfFontSet(fontset); XawTextBlock blk; int i, rWidth; pos = XawTextSourceRead(source, fromPos, &blk, toPos - fromPos); rWidth = 0; for (i = 0, idx = fromPos; idx < toPos; i++, idx++) { if (i >= blk.length) { i = 0; XawTextSourceRead(source, pos, &blk, toPos - pos); if (blk.length == 0) break; } c = ((wchar_t *)blk.ptr)[i]; rWidth += CharWidth(sink, fontset, fromx + rWidth, c); if (c == _Xaw_atowc(XawLF)) { idx++; break; } } *resPos = idx; *resWidth = rWidth; *resHeight = ext->max_logical_extent.height; }
/* * This function does not know about drawing more than one line of text. */ static void DisplayText( Widget w, Position x, Position y, XawTextPosition pos1, XawTextPosition pos2, Boolean highlight) { MultiSinkObject sink = (MultiSinkObject) w; Widget source = XawTextGetSource(XtParent(w)); wchar_t buf[BUFSIZ]; XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); int j, k; XawTextBlock blk; GC gc = highlight ? sink->multi_sink.invgc : sink->multi_sink.normgc; GC invgc = highlight ? sink->multi_sink.normgc : sink->multi_sink.invgc; if (!sink->multi_sink.echo) return; y = (Position) (y + abs(ext->max_logical_extent.y)); for (j = 0; pos1 < pos2;) { pos1 = (int) XawTextSourceRead(source, pos1, &blk, (int) (pos2 - pos1)); for (k = 0; k < blk.length; k++) { if (j >= BUFSIZ) { /* buffer full, dump the text. */ x = (Position) (x + PaintText(w, gc, x, y, buf, j)); j = 0; } buf[j] = ((wchar_t *) blk.ptr)[k]; if (buf[j] == _Xaw_atowc(XawLF)) continue; else if (buf[j] == _Xaw_atowc(XawTAB)) { Position temp = 0; Dimension width; if ((j != 0) && ((temp = (Position) PaintText(w, gc, x, y, buf, j) ) == 0)) return; x = (Position) (x + temp); width = (Dimension) CharWidth(w, x, _Xaw_atowc(XawTAB)); XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), invgc, (int) x, (int) y - abs(ext->max_logical_extent.y), (unsigned int) width, (unsigned int) ext->max_logical_extent.height); x = (Position) (x + width); j = -1; } else if (XwcTextEscapement(sink->multi_sink.fontset, &buf[j], 1) == 0) { if (sink->multi_sink.display_nonprinting) buf[j] = _Xaw_atowc('@'); else buf[j] = _Xaw_atowc(' '); } j++; } } if (j > 0) (void) PaintText(w, gc, x, y, buf, j); }
static void XawMultiSinkClassInitialize(void) { wspace[0] = _Xaw_atowc(XawSP); XawInitializeWidgetSet(); }
/* * The following procedure manages the "insert" cursor */ static void InsertCursor(Widget w, int x, int y, XawTextInsertState state) { MultiSinkObject sink = (MultiSinkObject)w; XFontSet fontset = sink->multi_sink.fontset; Widget ctx = XtParent(w); XawTextPosition position = XawTextGetInsertionPoint(ctx); if (XtIsRealized(ctx)) { int fheight, fdiff; XawTextBlock block; wchar_t c; XawTextPosition selection_start, selection_end; Boolean has_selection; XFontSetExtents *ext = XExtentsOfFontSet(fontset); XawTextGetSelectionPos((Widget)ctx, &selection_start, &selection_end); has_selection = selection_start != selection_end; fheight = ext->max_logical_extent.height; fdiff = fheight - abs(ext->max_logical_extent.y); if ((sink->multi_sink.cursor_position != position || state == XawisOff) && !has_selection && sink->multi_sink.laststate != XawisOff) { wchar_t *ochar; (void)XawTextSourceRead(XawTextGetSource(ctx), sink->multi_sink.cursor_position, &block, 1); if (!block.length) ochar = NULL; else { c = ((wchar_t *)block.ptr)[0]; if (c == _Xaw_atowc(XawLF)) ochar = NULL; else if (c == _Xaw_atowc(XawTAB)) ochar = wspace; else ochar = (wchar_t *)block.ptr; } if (!ochar) _XawTextSinkClearToBackground(w, sink->multi_sink.cursor_x, (sink->multi_sink.cursor_y - 1 - fheight), CharWidth(sink, fontset, 0, wspace[0]), fheight); else { if (XwcTextEscapement(sink->multi_sink.fontset, ochar, 1) != 0) DisplayText(w, sink->multi_sink.cursor_x, sink->multi_sink.cursor_y - 1 - fheight, sink->multi_sink.cursor_position, sink->multi_sink.cursor_position + 1, False); else PaintText(w, sink->multi_sink.normgc, sink->multi_sink.cursor_x, sink->multi_sink.cursor_y - 1 - fdiff, ochar, 1, ctx->core.background_pixmap != XtUnspecifiedPixmap); } } if (!has_selection && state != XawisOff) { wchar_t *nchar; Boolean focus = ((TextWidget)ctx)->text.hasfocus; (void)XawTextSourceRead(XawTextGetSource(ctx), position, &block, 1); c = ((wchar_t *)block.ptr)[0]; if (!block.length || c == _Xaw_atowc(XawLF) || c == _Xaw_atowc(XawTAB)) nchar = wspace; else nchar = (wchar_t *)block.ptr; if (focus) { if (XwcTextEscapement(sink->multi_sink.fontset, nchar, 1) != 0) XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, sink->multi_sink.invgc, x, (y - 1 - fdiff), nchar, 1); else DisplayText(w, x, y - 1 - fheight, position, position + 1, True); } else XDrawRectangle(XtDisplay(ctx), XtWindow(ctx), sink->multi_sink.xorgc ? sink->multi_sink.xorgc : sink->multi_sink.normgc, x, y - 1 - fheight, CharWidth(sink, fontset, 0, *nchar) - 1, fheight - 1); } } sink->multi_sink.cursor_x = x; sink->multi_sink.cursor_y = y; sink->multi_sink.laststate = state; sink->multi_sink.cursor_position = position; }
/* * This function does not know about drawing more than one line of text */ static void DisplayText(Widget w, int x, int y, XawTextPosition pos1, XawTextPosition pos2, Bool highlight) { TextWidget ctx = (TextWidget)XtParent(w); MultiSinkObject sink = (MultiSinkObject)w; XFontSet fontset = sink->multi_sink.fontset; Widget source = XawTextGetSource(XtParent(w)); wchar_t buf[256]; XFontSetExtents *ext = XExtentsOfFontSet(fontset); int j, k; XawTextBlock blk; GC gc, invgc, tabgc; int max_x; Bool clear_bg; if (!sink->multi_sink.echo || !ctx->text.lt.lines) return; max_x = (int)XtWidth(ctx) - ctx->text.r_margin.right; clear_bg = !highlight && ctx->core.background_pixmap != XtUnspecifiedPixmap; gc = highlight ? sink->multi_sink.invgc : sink->multi_sink.normgc; invgc = highlight ? sink->multi_sink.normgc : sink->multi_sink.invgc; if (highlight && sink->multi_sink.xorgc) tabgc = sink->multi_sink.xorgc; else tabgc = invgc; y += abs(ext->max_logical_extent.y); for (j = 0; pos1 < pos2;) { pos1 = XawTextSourceRead(source, pos1, &blk, (int) pos2 - pos1); for (k = 0; k < blk.length; k++) { if ((unsigned) j >= (sizeof(buf) / sizeof(wchar_t)) - 1) { /* buffer full, dump the text */ if ((x += PaintText(w, gc, x, y, buf, j, clear_bg)) >= max_x) return; j = 0; } buf[j] = ((wchar_t *)blk.ptr)[k]; if (buf[j] == _Xaw_atowc(XawLF)) continue; else if (buf[j] == _Xaw_atowc(XawTAB)) { unsigned int width; if (j != 0 && (x += PaintText(w, gc, x, y, buf, j, clear_bg)) >= max_x) return; width = CharWidth(sink, fontset, x, _Xaw_atowc(XawTAB)); if (clear_bg) _XawTextSinkClearToBackground(w, x, y - abs(ext->max_logical_extent.y), width, ext->max_logical_extent.height); else XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), tabgc, x, y - abs(ext->max_logical_extent.y), width, ext->max_logical_extent.height); x += width; j = -1; } else if (XwcTextEscapement(sink->multi_sink.fontset, &buf[j], 1) == 0) { if (sink->multi_sink.display_nonprinting) buf[j] = _Xaw_atowc('@'); else buf[j] = _Xaw_atowc(XawSP); } j++; } } if (j > 0) (void)PaintText(w, gc, x, y, buf, j, clear_bg); }