diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:48 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:48 +0000 |
commit | 384ac455a6cd5d23dfa24f9939f3ec04f1e5de46 (patch) | |
tree | caf2569ba305a1d32fed698546a300d6bb22a6a3 /src/MultiSink.c | |
parent | 81ad93fde745d556aaa3880deabf3674bb3db49e (diff) | |
download | xorg-lib-libXaw-384ac455a6cd5d23dfa24f9939f3ec04f1e5de46.tar.gz |
XFree86 4.3.0.1xf86-4_3_0_1PRE_xf86-4_3_0_1
Diffstat (limited to 'src/MultiSink.c')
-rw-r--r-- | src/MultiSink.c | 1189 |
1 files changed, 695 insertions, 494 deletions
diff --git a/src/MultiSink.c b/src/MultiSink.c index 3f4b017..77b0c9f 100644 --- a/src/MultiSink.c +++ b/src/MultiSink.c @@ -70,6 +70,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ +/* $XFree86: xc/lib/Xaw/MultiSink.c,v 1.20 2001/12/14 19:54:41 dawes Exp $ */ #include <X11/IntrinsicP.h> #include <X11/StringDefs.h> @@ -81,692 +82,892 @@ SOFTWARE. #include "XawI18n.h" #include <stdio.h> #include <ctype.h> +#include "Private.h" #ifdef GETLASTPOS -#undef GETLASTPOS /* We will use our own GETLASTPOS. */ +#undef GETLASTPOS /* We will use our own GETLASTPOS */ #endif -#define GETLASTPOS XawTextSourceScan(source, (XawTextPosition) 0, XawstAll, XawsdRight, 1, TRUE) +#define GETLASTPOS \ + XawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, True) -static void Initialize(), Destroy(); -static Boolean SetValues(); -static int MaxLines(), MaxHeight(); -static void SetTabs(); +/* + * Class Methods + */ +static void XawMultiSinkClassInitialize(void); +static void XawMultiSinkInitialize(Widget, Widget, ArgList, Cardinal*); +static void XawMultiSinkDestroy(Widget); +static void XawMultiSinkResize(Widget); +static Boolean XawMultiSinkSetValues(Widget, Widget, Widget, + ArgList, Cardinal*); +static int MaxLines(Widget, unsigned int); +static int MaxHeight(Widget, int); +static void SetTabs(Widget, int, short*); +static void DisplayText(Widget, int, int, + XawTextPosition, XawTextPosition, Bool); +static void InsertCursor(Widget, int, int, XawTextInsertState); +static void FindPosition(Widget, XawTextPosition, int, int, Bool, + XawTextPosition*, int*, int*); +static void FindDistance(Widget, XawTextPosition, int, XawTextPosition, int*, + XawTextPosition*, int*); +static void Resolve(Widget, XawTextPosition, int, int, XawTextPosition*); +static void GetCursorBounds(Widget, XRectangle*); -static void DisplayText(), InsertCursor(), FindPosition(); -static void FindDistance(), Resolve(), GetCursorBounds(); +/* + * Prototypes + */ +static void GetGC(MultiSinkObject); +static int CharWidth(MultiSinkObject, XFontSet, int, wchar_t); +static unsigned int PaintText(Widget w, GC gc, int x, int y, + wchar_t *buf, int len, Bool); -#define offset(field) XtOffsetOf(MultiSinkRec, multi_sink.field) +/* + * Defined in TextSink.c + */ +void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned); + +/* + * Initialization + */ +static wchar_t wspace[2]; +#define offset(field) XtOffsetOf(MultiSinkRec, multi_sink.field) static XtResource resources[] = { - {XtNfontSet, XtCFontSet, XtRFontSet, sizeof (XFontSet), - offset(fontset), XtRString, XtDefaultFontSet}, - {XtNecho, XtCOutput, XtRBoolean, sizeof(Boolean), - offset(echo), XtRImmediate, (XtPointer) True}, - {XtNdisplayNonprinting, XtCOutput, XtRBoolean, sizeof(Boolean), - offset(display_nonprinting), XtRImmediate, (XtPointer) True}, + { + XtNfontSet, + XtCFontSet, + XtRFontSet, + sizeof(XFontSet), + offset(fontset), + XtRString, + XtDefaultFontSet + }, + { + XtNecho, + XtCOutput, + XtRBoolean, + sizeof(Boolean), + offset(echo), + XtRImmediate, + (XtPointer)True + }, + { + XtNdisplayNonprinting, + XtCOutput, + XtRBoolean, + sizeof(Boolean), + offset(display_nonprinting), + XtRImmediate, + (XtPointer)True + }, }; #undef offset #define SuperClass (&textSinkClassRec) MultiSinkClassRec multiSinkClassRec = { - { /* core_class fields */ - /* superclass */ (WidgetClass) SuperClass, - /* class_name */ "MultiSink", - /* widget_size */ sizeof(MultiSinkRec), - /* class_initialize */ XawInitializeWidgetSet, - /* class_part_initialize */ NULL, - /* class_inited */ FALSE, - /* initialize */ Initialize, - /* initialize_hook */ NULL, - /* obj1 */ NULL, - /* obj2 */ NULL, - /* obj3 */ 0, - /* resources */ resources, - /* num_resources */ XtNumber(resources), - /* xrm_class */ NULLQUARK, - /* obj4 */ FALSE, - /* obj5 */ FALSE, - /* obj6 */ FALSE, - /* obj7 */ FALSE, - /* destroy */ Destroy, - /* obj8 */ NULL, - /* obj9 */ NULL, - /* set_values */ SetValues, - /* set_values_hook */ NULL, - /* obj10 */ NULL, - /* get_values_hook */ NULL, - /* obj11 */ NULL, - /* version */ XtVersion, - /* callback_private */ NULL, - /* obj12 */ NULL, - /* obj13 */ NULL, - /* obj14 */ NULL, - /* extension */ NULL + /* object */ + { + (WidgetClass)SuperClass, /* superclass */ + "MultiSink", /* class_name */ + sizeof(MultiSinkRec), /* widget_size */ + XawMultiSinkClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + False, /* class_inited */ + XawMultiSinkInitialize, /* initialize */ + NULL, /* initialize_hook */ + NULL, /* obj1 */ + NULL, /* obj2 */ + 0, /* obj3 */ + resources, /* resources */ + XtNumber(resources), /* num_resources */ + NULLQUARK, /* xrm_class */ + False, /* obj4 */ + False, /* obj5 */ + False, /* obj6 */ + False, /* obj7 */ + XawMultiSinkDestroy, /* destroy */ + (XtProc)XawMultiSinkResize, /* obj8 */ + NULL, /* obj9 */ + XawMultiSinkSetValues, /* set_values */ + NULL, /* set_values_hook */ + NULL, /* obj10 */ + NULL, /* get_values_hook */ + NULL, /* obj11 */ + XtVersion, /* version */ + NULL, /* callback_private */ + NULL, /* obj12 */ + NULL, /* obj13 */ + NULL, /* obj14 */ + NULL, /* extension */ }, - { /* text_sink_class fields */ - /* DisplayText */ DisplayText, - /* InsertCursor */ InsertCursor, - /* ClearToBackground */ XtInheritClearToBackground, - /* FindPosition */ FindPosition, - /* FindDistance */ FindDistance, - /* Resolve */ Resolve, - /* MaxLines */ MaxLines, - /* MaxHeight */ MaxHeight, - /* SetTabs */ SetTabs, - /* GetCursorBounds */ GetCursorBounds + /* text_sink */ + { + DisplayText, /* DisplayText */ + InsertCursor, /* InsertCursor */ + XtInheritClearToBackground, /* ClearToBackground */ + FindPosition, /* FindPosition */ + FindDistance, /* FindDistance */ + Resolve, /* Resolve */ + MaxLines, /* MaxLines */ + MaxHeight, /* MaxHeight */ + SetTabs, /* SetTabs */ + GetCursorBounds, /* GetCursorBounds */ }, - { /* multi_sink_class fields */ - /* unused */ 0 + /* multi_sink */ + { + NULL, /* extension */ } }; WidgetClass multiSinkObjectClass = (WidgetClass)&multiSinkClassRec; -/* Utilities */ - -static int -CharWidth (w, x, c) - Widget w; - int x; - wchar_t c; +/* + * Implementation + */ +static int +CharWidth(MultiSinkObject sink, XFontSet fontset, int x, wchar_t c) { - int i, width; - MultiSinkObject sink = (MultiSinkObject) w; - XFontSet fontset = sink->multi_sink.fontset; - Position *tab; + int width = 0; - if ( c == _Xaw_atowc(XawLF) ) return(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(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; + 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; } - return 0; + /*NOTREACHED*/ } - if (XwcTextEscapement (fontset, &c, 1) == 0) + if (XwcTextEscapement(fontset, &c, 1) == 0) { if (sink->multi_sink.display_nonprinting) c = _Xaw_atowc('@'); - else { + else c = _Xaw_atowc(XawSP); - } + } - /* - * if more efficiency(suppose one column is one ASCII char) + /* + * 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 = 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; + return (width); } -/* Function Name: PaintText - * Description: Actually paints the text into the windoe. - * Arguments: w - the text widget. - * gc - gc to paint text with. - * x, y - location to paint the text. - * buf, len - buffer and length of text to paint. - * Returns: the width of the text painted, or 0. +/* + * Function: + * PaintText * - * NOTE: If this string attempts to paint past the end of the window - * then this function will return zero. + * Parameters: + * w - text sink object + * gc - gc to paint text + * x - location to paint the text + * y - "" + * buf - buffer and length of text to paint + * len - "" + * clear_bg - clear background before drawing ? + * + * Description: + * Actually paints the text into the window. + * + * Returns: + * The width of the text painted */ - -static Dimension -PaintText(w, gc, x, y, buf, len) - Widget w; - GC gc; - Position x, y; - wchar_t* buf; - int len; +static unsigned int +PaintText(Widget w, GC gc, int x, int y, wchar_t *buf, int len, Bool clear_bg) { - MultiSinkObject sink = (MultiSinkObject) w; - TextWidget ctx = (TextWidget) XtParent(w); - + MultiSinkObject sink = (MultiSinkObject)w; + TextWidget ctx = (TextWidget)XtParent(w); XFontSet fontset = sink->multi_sink.fontset; - Position max_x; - Dimension width = XwcTextEscapement(fontset, buf, len); - XFontSetExtents *ext = XExtentsOfFontSet(fontset); - max_x = (Position) ctx->core.width; - - if ( ((int) width) <= -x) /* Don't draw if we can't see it. */ - return(width); - - XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, - (int) x, (int) y, buf, len); - if ( (((Position) width + x) > max_x) && (ctx->text.margin.right != 0) ) { - x = ctx->core.width - ctx->text.margin.right; - width = ctx->text.margin.right; - XFillRectangle(XtDisplay((Widget) ctx), XtWindow( (Widget) ctx), - sink->multi_sink.normgc, (int) x, - (int) y - abs(ext->max_logical_extent.y), - (unsigned int) width, - (unsigned int) ext->max_logical_extent.height); - return(0); + unsigned int width = XwcTextEscapement(fontset, buf, len); + + if (((int)width) <= -x) /* Don't draw if we can't see it */ + return (width); + + if (clear_bg) { + XFontSetExtents *ext = XExtentsOfFontSet(fontset); + + _XawTextSinkClearToBackground(w, x, y - abs(ext->max_logical_extent.y), + width, ext->max_logical_extent.height); + XwcDrawString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, x, y, buf, len); } - return(width); + else + XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, + x, y, buf, len); + + return (width); } /* Sink Object Functions */ - /* - * This function does not know about drawing more than one line of text. + * This function does not know about drawing more than one line of text */ - -static void -DisplayText(w, x, y, pos1, pos2, highlight) - Widget w; - Position x, y; - Boolean highlight; - XawTextPosition pos1, pos2; +static void +DisplayText(Widget w, int x, int y, + XawTextPosition pos1, XawTextPosition pos2, Bool highlight) { - MultiSinkObject sink = (MultiSinkObject) w; + TextWidget ctx = (TextWidget)XtParent(w); + MultiSinkObject sink = (MultiSinkObject)w; + XFontSet fontset = sink->multi_sink.fontset; Widget source = XawTextGetSource(XtParent(w)); - wchar_t buf[BUFSIZ]; - XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); - + wchar_t buf[256]; + XFontSetExtents *ext = XExtentsOfFontSet(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; + GC gc, invgc, tabgc; + int max_x; + Bool clear_bg; + + if (!sink->multi_sink.echo || !ctx->text.lt.lines) + return; - if (!sink->multi_sink.echo) 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 ; ) { + for (j = 0; pos1 < pos2;) { pos1 = XawTextSourceRead(source, pos1, &blk, (int) pos2 - pos1); for (k = 0; k < blk.length; k++) { - if (j >= BUFSIZ) { /* buffer full, dump the text. */ - x += PaintText(w, gc, x, y, buf, j); + 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; + continue; else if (buf[j] == _Xaw_atowc(XawTAB)) { - Position temp = 0; - Dimension width; - - if ((j != 0) && ((temp = PaintText(w, gc, x, y, buf, j)) == 0)) - return; - - x += temp; - width = 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 += 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(' '); - } + 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); -} - -#define insertCursor_width 6 -#define insertCursor_height 3 -static char insertCursor_bits[] = {0x0c, 0x1e, 0x33}; -static Pixmap -CreateInsertCursor(s) - Screen *s; -{ - return (XCreateBitmapFromData (DisplayOfScreen(s), RootWindowOfScreen(s), - insertCursor_bits, insertCursor_width, insertCursor_height)); + if (j > 0) + (void)PaintText(w, gc, x, y, buf, j, clear_bg); } -/* Function Name: GetCursorBounds - * Description: Returns the size and location of the cursor. - * Arguments: w - the text object. - * RETURNED rect - an X rectangle to return the cursor bounds in. - * Returns: none. +/* + * 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(w, rect) - Widget w; - XRectangle * rect; +GetCursorBounds(Widget w, XRectangle *rect) { - MultiSinkObject sink = (MultiSinkObject) w; + MultiSinkObject sink = (MultiSinkObject)w; - rect->width = (unsigned short) insertCursor_width; - rect->height = (unsigned short) insertCursor_height; - rect->x = sink->multi_sink.cursor_x - (short) (rect->width / 2); - rect->y = sink->multi_sink.cursor_y - (short) rect->height; + 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; } /* - * The following procedure manages the "insert" cursor. + * The following procedure manages the "insert" cursor */ - static void -InsertCursor (w, x, y, state) - Widget w; - Position x, y; - XawTextInsertState state; +InsertCursor(Widget w, int x, int y, XawTextInsertState state) { - MultiSinkObject sink = (MultiSinkObject) w; - Widget text_widget = XtParent(w); - XRectangle rect; + 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; - - GetCursorBounds(w, &rect); - if (state != sink->multi_sink.laststate && XtIsRealized(text_widget)) - XCopyPlane(XtDisplay(text_widget), - sink->multi_sink.insertCursorOn, - XtWindow(text_widget), sink->multi_sink.xorgc, - 0, 0, (unsigned int) rect.width, (unsigned int) rect.height, - (int) rect.x, (int) rect.y, 1); sink->multi_sink.laststate = state; + sink->multi_sink.cursor_position = position; } /* - * Given two positions, find the distance between them. + * Given two positions, find the distance between them */ - static void -FindDistance (w, fromPos, fromx, toPos, resWidth, resPos, resHeight) - 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. */ +FindDistance(Widget w, XawTextPosition fromPos, int fromx, + XawTextPosition toPos, int *resWidth, + XawTextPosition *resPos, int *resHeight) { - MultiSinkObject sink = (MultiSinkObject) w; - Widget source = XawTextGetSource(XtParent(w)); - - XawTextPosition index, lastPos; + 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(sink->multi_sink.fontset); + XFontSetExtents *ext = XExtentsOfFontSet(fontset); XawTextBlock blk; - - /* we may not need this */ - lastPos = GETLASTPOS; - XawTextSourceRead(source, fromPos, &blk, (int) toPos - fromPos); - *resWidth = 0; - for (index = fromPos; index != toPos && index < lastPos; index++) { - if (index - blk.firstPos >= blk.length) - XawTextSourceRead(source, index, &blk, (int) toPos - fromPos); - c = ((wchar_t *)blk.ptr)[index - blk.firstPos]; - *resWidth += CharWidth(w, fromx + *resWidth, c); + 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)) { - index++; + idx++; break; } } - *resPos = index; + + *resPos = idx; + *resWidth = rWidth; *resHeight = ext->max_logical_extent.height; } - static void -FindPosition(w, fromPos, fromx, width, stopAtWordBreak, resPos, resWidth, resHeight) - Widget w; - XawTextPosition fromPos; /* Starting position. */ - int fromx; /* Horizontal location of starting position.*/ - int width; /* Desired width. */ - int stopAtWordBreak; /* Whether the resulting position should be at - a word break. */ - XawTextPosition *resPos; /* Resulting position. */ - int* resWidth; /* Actual width used. */ - int* resHeight; /* Height required. */ +FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width, + Bool stopAtWordBreak, XawTextPosition *resPos, int *resWidth, + int *resHeight) { - MultiSinkObject sink = (MultiSinkObject) w; - Widget source = XawTextGetSource(XtParent(w)); - - XawTextPosition lastPos, index, whiteSpacePosition; - int lastWidth, whiteSpaceWidth; + 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(sink->multi_sink.fontset); + XFontSetExtents *ext = XExtentsOfFontSet(fontset); XawTextBlock blk; - lastPos = GETLASTPOS; - - XawTextSourceRead(source, fromPos, &blk, BUFSIZ); - *resWidth = 0; - whiteSpaceSeen = FALSE; + pos = XawTextSourceRead(source, fromPos, &blk, BUFSIZ); + rWidth = lastWidth = whiteSpaceWidth = 0; + whiteSpaceSeen = False; c = 0; - for (index = fromPos; *resWidth <= width && index < lastPos; index++) { - lastWidth = *resWidth; - if (index - blk.firstPos >= blk.length) - XawTextSourceRead(source, index, &blk, BUFSIZ); - c = ((wchar_t *)blk.ptr)[index - blk.firstPos]; - *resWidth += CharWidth(w, fromx + *resWidth, c); - - if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB)) && - *resWidth <= width) { - whiteSpaceSeen = TRUE; - whiteSpacePosition = index; - whiteSpaceWidth = *resWidth; + + 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)) { - index++; + idx++; break; } + else if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB)) + && rWidth <= width) { + whiteSpaceSeen = True; + whiteSpacePosition = idx; + whiteSpaceWidth = rWidth; + } } - if (*resWidth > width && index > fromPos) { - *resWidth = lastWidth; - index--; + + if (rWidth > width && idx > fromPos) { + idx--; + rWidth = lastWidth; if (stopAtWordBreak && whiteSpaceSeen) { - index = whiteSpacePosition + 1; - *resWidth = whiteSpaceWidth; + idx = whiteSpacePosition + 1; + rWidth = whiteSpaceWidth; } } - if (index == lastPos && c != _Xaw_atowc(XawLF)) index = lastPos + 1; - *resPos = index; + + 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 -Resolve (w, pos, fromx, width, leftPos, rightPos) - Widget w; - XawTextPosition pos; - int fromx, width; - XawTextPosition *leftPos, *rightPos; +Resolve(Widget w, XawTextPosition pos, int fromx, int width, + XawTextPosition *pos_return) { int resWidth, resHeight; Widget source = XawTextGetSource(XtParent(w)); - FindPosition(w, pos, fromx, width, FALSE, leftPos, &resWidth, &resHeight); - if (*leftPos > GETLASTPOS) - *leftPos = GETLASTPOS; - *rightPos = *leftPos; + FindPosition(w, pos, fromx, width, False, pos_return, &resWidth, &resHeight); + if (*pos_return > GETLASTPOS) + *pos_return = GETLASTPOS; } static void -GetGC(sink) - MultiSinkObject sink; +GetGC(MultiSinkObject sink) { - XtGCMask valuemask = (GCGraphicsExposures | GCForeground | GCBackground ); + XtGCMask valuemask = (GCGraphicsExposures | GCClipXOrigin | + GCForeground | GCBackground); XGCValues values; - values.graphics_exposures = (Bool) FALSE; + /* XXX We dont want do share a gc that will change the clip-mask */ + values.clip_x_origin = (long)sink; + values.clip_mask = None; + values.graphics_exposures = False; values.foreground = sink->text_sink.foreground; values.background = sink->text_sink.background; - sink->multi_sink.normgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 ); - + sink->multi_sink.normgc = XtAllocateGC((Widget)sink, 0, valuemask, &values, + GCFont | GCClipMask, 0); + values.foreground = sink->text_sink.background; +#ifndef OLDXAW + values.background = sink->text_sink.cursor_color; +#else values.background = sink->text_sink.foreground; - sink->multi_sink.invgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 ); - - values.function = GXxor; - values.background = (unsigned long) 0L; /* (pix ^ 0) = pix */ - values.foreground = (sink->text_sink.background ^ - sink->text_sink.foreground); - valuemask = GCGraphicsExposures | GCFunction | GCForeground | GCBackground; - - /* if this GC is not used for fontset rendering then AllocateGC aint needed. Dont hurt tho.*/ - sink->multi_sink.xorgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 ); -} +#endif + sink->multi_sink.invgc = XtAllocateGC((Widget)sink, 0, valuemask, &values, + GCFont | GCClipMask, 0); +#ifndef OLDXAW + if (sink->text_sink.cursor_color != sink->text_sink.foreground) { + values.foreground = sink->text_sink.cursor_color; + values.background = sink->text_sink.foreground; + sink->multi_sink.xorgc = XtAllocateGC((Widget)sink, 0, valuemask, + &values, GCFont | GCClipMask, 0); + } + else +#endif /* OLDXAW */ + sink->multi_sink.xorgc = NULL; + XawMultiSinkResize((Widget)sink); +} -/***** Public routines *****/ +static void +XawMultiSinkClassInitialize(void) +{ + wspace[0] = _Xaw_atowc(XawSP); + XawInitializeWidgetSet(); +} -/* Function Name: Initialize - * Description: Initializes the TextSink Object. - * Arguments: request, new - the requested and new values for the object - * instance. - * Returns: none. +/* + * Function: + * XawMultiSinkInitialize + * + * Parameters: + * request - requested and new values for the object instance + * cnew - "" * + * Description: + * Initializes the TextSink Object. */ - /* ARGSUSED */ static void -Initialize(request, new, args, num_args) - Widget request, new; - ArgList args; - Cardinal* num_args; +XawMultiSinkInitialize(Widget request, Widget cnew, + ArgList args, Cardinal *num_args) { - MultiSinkObject sink = (MultiSinkObject) new; + MultiSinkObject sink = (MultiSinkObject)cnew; GetGC(sink); - - sink->multi_sink.insertCursorOn= CreateInsertCursor(XtScreenOfObject(new)); + + sink->multi_sink.cursor_position = 0; sink->multi_sink.laststate = XawisOff; sink->multi_sink.cursor_x = sink->multi_sink.cursor_y = 0; } -/* Function Name: Destroy - * Description: This function cleans up when the object is - * destroyed. - * Arguments: w - the MultiSink Object. - * Returns: none. +/* + * Function: + * XawMultiSinkDestroy + * + * Parameters: + * w - MultiSink Object + * + * Description: + * This function cleans up when the object is destroyed. */ - static void -Destroy(w) - Widget w; +XawMultiSinkDestroy(Widget w) { - MultiSinkObject sink = (MultiSinkObject) w; - - XtReleaseGC(w, sink->multi_sink.normgc); - XtReleaseGC(w, sink->multi_sink.invgc); - XtReleaseGC(w, sink->multi_sink.xorgc); + MultiSinkObject sink = (MultiSinkObject)w; + + XtReleaseGC(w, sink->multi_sink.normgc); + XtReleaseGC(w, sink->multi_sink.invgc); + if (sink->multi_sink.xorgc) + XtReleaseGC(w, sink->multi_sink.xorgc); + sink->multi_sink.normgc = + sink->multi_sink.invgc = + sink->multi_sink.xorgc = NULL; +} - XFreePixmap(XtDisplayOfObject(w), sink->multi_sink.insertCursorOn); +static void +XawMultiSinkResize(Widget w) +{ + TextWidget ctx = (TextWidget)XtParent(w); + MultiSinkObject sink = (MultiSinkObject)w; + XRectangle rect; + int width, height; + + if (w->core.widget_class != multiSinkObjectClass) + return; + + rect.x = ctx->text.r_margin.left; + rect.y = ctx->text.r_margin.top; + width = (int)XtWidth(ctx) - + (int)ctx->text.r_margin.right - (int)ctx->text.r_margin.left; + height = (int)XtHeight(ctx) - + (int)ctx->text.r_margin.top - (int)ctx->text.r_margin.bottom; + rect.width = width; + rect.height = height; + + if (sink->multi_sink.normgc) { + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), sink->multi_sink.normgc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), sink->multi_sink.normgc, None); + } + if (sink->multi_sink.invgc) { + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), sink->multi_sink.invgc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), sink->multi_sink.invgc, None); + } + if (sink->multi_sink.xorgc) { + if (width >= 0 && height >= 0) + XSetClipRectangles(XtDisplay((Widget)ctx), sink->multi_sink.xorgc, + 0, 0, &rect, 1, Unsorted); + else + XSetClipMask(XtDisplay((Widget)ctx), sink->multi_sink.xorgc, None); + } } -/* Function Name: SetValues - * Description: Sets the values for the MultiSink - * Arguments: current - current state of the object. - * request - what was requested. - * new - what the object will become. - * Returns: True if redisplay is needed. +/* + * Function: + * XawMultiSinkSetValues + * + * Parameters: + * current - current state of the object + * request - what was requested + * cnew - what the object will become + * + * Description: + * Sets the values for the MultiSink. + * + * Returns: + * True if redisplay is needed */ - -/* ARGSUSED */ +/*ARGSUSED*/ static Boolean -SetValues(current, request, new, args, num_args) - Widget current, request, new; - ArgList args; - Cardinal* num_args; +XawMultiSinkSetValues(Widget current, Widget request, Widget cnew, + ArgList args, Cardinal *num_args) { - MultiSinkObject w = (MultiSinkObject) new; - MultiSinkObject old_w = (MultiSinkObject) current; + MultiSinkObject w = (MultiSinkObject)cnew; + MultiSinkObject old_w = (MultiSinkObject)current; /* Font set is not in the GC! Do not make a new GC when font set changes! */ - if ( w->multi_sink.fontset != old_w->multi_sink.fontset ) { - ((TextWidget)XtParent(new))->text.redisplay_needed = True; + if (w->multi_sink.fontset != old_w->multi_sink.fontset) { + ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; #ifndef NO_TAB_FIX - SetTabs( w, w->text_sink.tab_count, w->text_sink.char_tabs ); + SetTabs((Widget)w, w->text_sink.tab_count, w->text_sink.char_tabs); #endif } - if ( w->text_sink.background != old_w->text_sink.background || - w->text_sink.foreground != old_w->text_sink.foreground ) { - - XtReleaseGC((Widget)w, w->multi_sink.normgc); - XtReleaseGC((Widget)w, w->multi_sink.invgc); - XtReleaseGC((Widget)w, w->multi_sink.xorgc); + if (w->text_sink.background != old_w->text_sink.background + || w->text_sink.foreground != old_w->text_sink.foreground +#ifndef OLDXAW + || w->text_sink.cursor_color != old_w->text_sink.cursor_color +#endif + ) { + XtReleaseGC(cnew, w->multi_sink.normgc); + XtReleaseGC(cnew, w->multi_sink.invgc); + if (w->multi_sink.xorgc) + XtReleaseGC(cnew, w->multi_sink.xorgc); GetGC(w); - ((TextWidget)XtParent(new))->text.redisplay_needed = True; - } else { - if ( (w->multi_sink.echo != old_w->multi_sink.echo) || - (w->multi_sink.display_nonprinting != - old_w->multi_sink.display_nonprinting) ) - ((TextWidget)XtParent(new))->text.redisplay_needed = True; + ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; } - - return False; + else if (w->multi_sink.echo != old_w->multi_sink.echo + || w->multi_sink.display_nonprinting + != old_w->multi_sink.display_nonprinting) + ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; + + return (False); } -/* Function Name: MaxLines - * Description: Finds the Maximum number of lines that will fit in - * a given height. - * Arguments: w - the MultiSink Object. - * height - height to fit lines into. - * Returns: the number of lines that will fit. +/* + * Function: + * MaxLines + * + * Parameters: + * w - MultiSink Object + * height - height to fit lines into + * + * Description: + * Finds the Maximum number of lines that will fit in a given height. + * + * Returns: + * The number of lines that will fit */ - -/* ARGSUSED */ +/*ARGSUSED*/ static int -MaxLines(w, height) - Widget w; - Dimension height; +MaxLines(Widget w, unsigned int height) { - MultiSinkObject sink = (MultiSinkObject) w; - int font_height; - XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + MultiSinkObject sink = (MultiSinkObject)w; + int font_height; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); - font_height = ext->max_logical_extent.height; - return( ((int) height) / font_height ); + font_height = ext->max_logical_extent.height; + return (height / font_height); } -/* Function Name: MaxHeight - * Description: Finds the Minium height that will contain a given number - * lines. - * Arguments: w - the MultiSink Object. - * lines - the number of lines. - * Returns: the height. +/* + * Function: + * MaxHeight + * + * Parameters: + * w - MultiSink Object + * lines - number of lines + * + * Description: + * Finds the Minium height that will contain a given number lines. + * Returns: + * The height */ - -/* ARGSUSED */ +/*ARGSUSED*/ static int -#if NeedFunctionPrototypes -MaxHeight( - Widget w, - int lines ) -#else -MaxHeight( w, lines ) - Widget w; - int lines; -#endif +MaxHeight(Widget w, int lines) { - MultiSinkObject sink = (MultiSinkObject) w; - XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + MultiSinkObject sink = (MultiSinkObject)w; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); - return(lines * ext->max_logical_extent.height); + return (lines * ext->max_logical_extent.height); } -/* Function Name: SetTabs - * Description: Sets the Tab stops. - * Arguments: w - the MultiSink Object. - * tab_count - the number of tabs in the list. - * tabs - the text positions of the tabs. - * Returns: none +/* + * Function: + * SetTabs + * + * Arguments: + * w - MultiSink Object + * tab_count - number of tabs in the list + * tabs - text positions of the tabs + * + * Description: + * Sets the Tab stops. */ - -static void -#if NeedFunctionPrototypes -SetTabs( - Widget w, - int tab_count, - short* tabs ) -#else -SetTabs( w, tab_count, tabs ) - Widget w; - int tab_count; - short* tabs; -#endif +static void +SetTabs(Widget w, int tab_count, short* tabs) { - MultiSinkObject sink = (MultiSinkObject) w; - int i; - Atom XA_FIGURE_WIDTH; - unsigned long figure_width = 0; - XFontStruct *font; - - /* - * Bug: - * Suppose the first font of fontset stores the unit of column. - * - * By Li Yuhong, Mar. 14, 1991 - */ - { XFontStruct **f_list; - char **f_name; - - (void) XFontsOfFontSet(sink->multi_sink.fontset, &f_list, &f_name); - font = f_list[0]; - } + MultiSinkObject sink = (MultiSinkObject)w; + int i; + Atom XA_FIGURE_WIDTH; + unsigned long figure_width = 0; + XFontStruct *font; -/* - * Find the figure width of the current font. - */ + /* + * Bug: + * Suppose the first font of fontset stores the unit of column. + * + * By Li Yuhong, Mar. 14, 1991 + */ + { + XFontStruct **f_list; + char **f_name; - XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", FALSE); - if ( (XA_FIGURE_WIDTH != None) && - ( (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width)) || - (figure_width == 0)) ) - if (font->per_char && font->min_char_or_byte2 <= '$' && - font->max_char_or_byte2 >= '$') - figure_width = font->per_char['$' - font->min_char_or_byte2].width; - else - figure_width = font->max_bounds.width; - - if (tab_count > sink->text_sink.tab_count) { - sink->text_sink.tabs = (Position *) - XtRealloc((char *) sink->text_sink.tabs, - (Cardinal) (tab_count * sizeof(Position))); - sink->text_sink.char_tabs = (short *) - XtRealloc((char *) sink->text_sink.char_tabs, - (Cardinal) (tab_count * sizeof(short))); - } + (void)XFontsOfFontSet(sink->multi_sink.fontset, &f_list, &f_name); + font = f_list[0]; + } - for ( i = 0 ; i < tab_count ; i++ ) { - sink->text_sink.tabs[i] = tabs[i] * figure_width; - sink->text_sink.char_tabs[i] = tabs[i]; - } - - sink->text_sink.tab_count = tab_count; + /* + * Find the figure width of the current font + */ + XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", False); + if (XA_FIGURE_WIDTH != None + && (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width) + || figure_width == 0)) { + if (font->per_char && font->min_char_or_byte2 <= '$' + && font->max_char_or_byte2 >= '$') + figure_width = font->per_char['$' - font->min_char_or_byte2].width; + else + figure_width = font->max_bounds.width; + } + + if (tab_count > sink->text_sink.tab_count) { + sink->text_sink.tabs = (Position *) + XtRealloc((char *)sink->text_sink.tabs, + (Cardinal)(tab_count * sizeof(Position))); + sink->text_sink.char_tabs = (short *) + XtRealloc((char *)sink->text_sink.char_tabs, + (Cardinal)(tab_count * sizeof(short))); + } + + for (i = 0 ; i < tab_count ; i++) { + sink->text_sink.tabs[i] = tabs[i] * figure_width; + sink->text_sink.char_tabs[i] = tabs[i]; + } + + sink->text_sink.tab_count = tab_count; #ifndef NO_TAB_FIX - ((TextWidget)XtParent(w))->text.redisplay_needed = True; + ((TextWidget)XtParent(w))->text.redisplay_needed = True; #endif } void -#if NeedFunctionPrototypes -_XawMultiSinkPosToXY( - Widget w, - XawTextPosition pos, - Position *x, - Position *y ) -#else -_XawMultiSinkPosToXY( w, pos, x, y ) - Widget w; - XawTextPosition pos; - Position *x, *y; -#endif +_XawMultiSinkPosToXY(Widget w, XawTextPosition pos, Position *x, Position *y) { - MultiSinkObject sink = (MultiSinkObject) ((TextWidget)w)->text.sink; - XFontSetExtents *ext = XExtentsOfFontSet( sink->multi_sink.fontset ); + MultiSinkObject sink = (MultiSinkObject)((TextWidget)w)->text.sink; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); - _XawTextPosToXY( w, pos, x, y ); - *y += abs( ext->max_logical_extent.y ); + _XawTextPosToXY(w, pos, x, y); + *y += abs(ext->max_logical_extent.y); } |