diff options
Diffstat (limited to 'nx-X11/lib/Xaw/AsciiSink.c')
-rw-r--r-- | nx-X11/lib/Xaw/AsciiSink.c | 1951 |
1 files changed, 0 insertions, 1951 deletions
diff --git a/nx-X11/lib/Xaw/AsciiSink.c b/nx-X11/lib/Xaw/AsciiSink.c deleted file mode 100644 index ad35a127c..000000000 --- a/nx-X11/lib/Xaw/AsciiSink.c +++ /dev/null @@ -1,1951 +0,0 @@ -/* $Xorg: AsciiSink.c,v 1.4 2001/02/09 02:03:42 xorgcvs Exp $ */ - -/*********************************************************** - -Copyright 1987, 1988, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ -/* $XFree86: xc/lib/Xaw/AsciiSink.c,v 1.26 2001/12/14 19:54:38 dawes Exp $ */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <X11/IntrinsicP.h> -#include <X11/StringDefs.h> -#include <X11/Xatom.h> -#include <X11/Xaw/XawInit.h> -#include <X11/Xaw/AsciiSinkP.h> -#include <X11/Xaw/AsciiSrcP.h> -#include <X11/Xaw/TextP.h> -#include "Private.h" - -#ifdef GETLASTPOS -#undef GETLASTPOS /* We will use our own GETLASTPOS */ -#endif - -#define GETLASTPOS \ - XawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, True) - -/* - * Class Methods - */ -static void XawAsciiSinkClassPartInitialize(WidgetClass); -static void XawAsciiSinkInitialize(Widget, Widget, ArgList, Cardinal*); -static void XawAsciiSinkDestroy(Widget); -static void XawAsciiSinkResize(Widget); -static Boolean XawAsciiSinkSetValues(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*); -#ifndef OLDXAW -static void AsciiPreparePaint(Widget, int, int, - XawTextPosition, XawTextPosition, Bool); -static void AsciiDoPaint(Widget); -#endif - -/* - * Prototypes - */ -static void GetGC(AsciiSinkObject); -static int CharWidth(AsciiSinkObject, XFontStruct*, int, unsigned int); -static unsigned int PaintText(Widget w, GC gc, int x, int y, - char *buf, int len, Bool); - -/* - * Defined in TextSink.c - */ -void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned); - -/* - * Initialization - */ -#define offset(field) XtOffsetOf(AsciiSinkRec, ascii_sink.field) -static XtResource resources[] = { - { - XtNfont, - XtCFont, - XtRFontStruct, - sizeof(XFontStruct*), - offset(font), - XtRString, - XtDefaultFont - }, - { - 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) -AsciiSinkClassRec asciiSinkClassRec = { - /* object */ - { - (WidgetClass)Superclass, /* superclass */ - "AsciiSink", /* class_name */ - sizeof(AsciiSinkRec), /* widget_size */ - XawInitializeWidgetSet, /* class_initialize */ - XawAsciiSinkClassPartInitialize, /* class_part_initialize */ - False, /* class_inited */ - XawAsciiSinkInitialize, /* 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 */ - XawAsciiSinkDestroy, /* destroy */ - (XtProc)XawAsciiSinkResize, /* obj8 */ - NULL, /* obj9 */ - XawAsciiSinkSetValues, /* 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 */ - { - DisplayText, /* DisplayText */ - InsertCursor, /* InsertCursor */ - XtInheritClearToBackground, /* ClearToBackground */ - FindPosition, /* FindPosition */ - FindDistance, /* FindDistance */ - Resolve, /* Resolve */ - MaxLines, /* MaxLines */ - MaxHeight, /* MaxHeight */ - SetTabs, /* SetTabs */ - GetCursorBounds, /* GetCursorBounds */ -#ifndef OLDXAW - NULL /* extension */ -#endif - }, - /* ascii_sink */ - { - NULL, /* extension */ - } -}; - -WidgetClass asciiSinkObjectClass = (WidgetClass)&asciiSinkClassRec; - -/* - * Implementation - */ -static void -XawAsciiSinkClassPartInitialize(WidgetClass wc) -{ -#ifndef OLDXAW - AsciiSinkObjectClass cclass = (AsciiSinkObjectClass)wc; - XrmQuark record_type = XrmPermStringToQuark("TextSink"); - TextSinkExt ext = cclass->text_sink_class.extension; - - while (ext) { - if (ext->record_type == record_type && - ext->version == 1) { - ext->PreparePaint = AsciiPreparePaint; - ext->DoPaint = AsciiDoPaint; - break; - } - ext = (TextSinkExt)ext->next_extension; - } - if (ext == NULL) - XtError("TextSinkClass: cannot resolve extension.\n"); -#endif -} - -static int -CharWidth(AsciiSinkObject sink, XFontStruct *font, int x, unsigned int c) -{ - int width = 0; - - if (c == XawLF) - return (0); - - if (c == 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 >= 0 && 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 ((c & 0177) < XawSP || c == 0177) { - if (sink->ascii_sink.display_nonprinting) { - if (c > 0177) { - width = CharWidth(sink, font, x, '\\'); - width += CharWidth(sink, font, x, ((c >> 6) & 7) + '0'); - width += CharWidth(sink, font, x, ((c >> 3) & 7) + '0'); - c = (c & 7) + '0'; - } - else { - width = CharWidth(sink, font, x, '^'); - if ((c |= 0100) == 0177) - c = '?'; - } - } - else - c = XawSP; - } - - if (font->per_char - && (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2)) - width += font->per_char[c - font->min_char_or_byte2].width; - else - width += font->min_bounds.width; - - return (width); -} - -#ifndef OLDXAW -static int -GetTextWidth(TextWidget ctx, int current_width, XFontStruct *font, - XawTextPosition from, int length) -{ - int i, width = 0; - XawTextBlock block; - XawTextPosition pos = from; - - while (length > 0) { - pos = XawTextSourceRead(ctx->text.source, from, &block, length); - length -= pos - from; - from = pos; - for (i = 0; i < block.length; i++) - width += CharWidth((AsciiSinkObject)ctx->text.sink, font, - current_width + width, - (unsigned char)block.ptr[i]); - } - - return (width); -} - -static -void CalculateBearing(TextWidget ctx, XawTextPosition position, int x, int y, - int ascent, int descent, Bool highlight, Bool right) -{ -/* - * Sample case: - * - * lbearing| width |rbearing - * | | - * | #### - * | ### | - * | #### | - * | #### | - * | ########## | - * | #### | - * | #### | - * | #### | - * | #### | - * |### | - * #### | - * | | - * - */ - AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink; - XawTextAnchor *anchor; - XawTextEntity *entity; - XawTextProperty *property; - XawTextPaintStruct *paint; - XawTextBlock block; - XFontStruct *font; - - property = NULL; - if (XawTextSourceAnchorAndEntity(ctx->text.source, position, - &anchor, &entity) && - (property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (property->mask & XAW_TPROP_FONT)) - font = property->font; - else - font = sink->ascii_sink.font; - if (right) { - if (font->max_bounds.rbearing > 0) { - int rbearing = font->max_bounds.rbearing - font->max_bounds.width; - unsigned char c; - - (void)XawTextSourceRead(ctx->text.source, position, &block, 1); - c = *(unsigned char*)block.ptr; - if (c == '\t' || c == '\n') - c = ' '; - else if ((c & 0177) < XawSP || c == 0177) { - if (sink->ascii_sink.display_nonprinting) - c = c > 0177 ? (c & 7) + '0' : c + '@'; - else - c = ' '; - } - if (font->per_char && - (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2)) - rbearing = font->per_char[c - font->min_char_or_byte2].rbearing - - font->per_char[c - font->min_char_or_byte2].width; - if (rbearing > 0) { - paint = XtNew(XawTextPaintStruct); - paint->next = sink->text_sink.paint->bearings; - sink->text_sink.paint->bearings = paint; - paint->x = x - (paint->width = CharWidth(sink, font, 0, c)); - paint->y = y + ascent; - paint->property = property; - paint->max_ascent = ascent; - paint->max_descent = descent; - paint->backtabs = NULL; - paint->highlight = highlight; - paint->length = 1; - paint->text = XtMalloc(1); - paint->text[0] = c; - } - } - } - else { - if (font->min_bounds.lbearing < 0) { - int lbearing = font->min_bounds.lbearing; - unsigned char c; - - (void)XawTextSourceRead(ctx->text.source, position, &block, 1); - c = *(unsigned char*)block.ptr; - if (c == '\t' || c == '\n') - c = ' '; - else if ((c & 0177) < XawSP || c == 0177) { - if (sink->ascii_sink.display_nonprinting) - c = c > 0177 ? '\\' : c + '^'; - else - c = ' '; - } - if (font->per_char && - (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2)) - lbearing = font->per_char[c - font->min_char_or_byte2].lbearing; - if (lbearing < 0) { - paint = XtNew(XawTextPaintStruct); - paint->next = sink->text_sink.paint->bearings; - sink->text_sink.paint->bearings = paint; - paint->x = x; - paint->width = -CharWidth(sink, font, 0, c); - paint->y = y + ascent; - paint->property = property; - paint->max_ascent = ascent; - paint->max_descent = descent; - paint->backtabs = NULL; - paint->highlight = highlight; - paint->length = 1; - paint->text = XtMalloc(1); - paint->text[0] = c; - } - } - } -} - -static void -AsciiPreparePaint(Widget w, int y, int line, - XawTextPosition from, XawTextPosition to, Bool highlight) -{ - static XmuSegment segment; - static XmuScanline next; - static XmuScanline scanline = {0, &segment, &next}; - static XmuArea area = {&scanline}; - - TextWidget ctx = (TextWidget)XtParent(w); - AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink; - XawTextPosition left, right, pos, pos2, tmp, length; - XawTextAnchor *anchor; - XawTextEntity *entity; - XawTextProperty *property; - int i, ascent = 0, descent = 0, xl, xr, x = ctx->text.left_margin, bufsiz; - XawTextBlock block; - XFontStruct *font; - XawTextPaintStruct *paint; - - if (!sink->ascii_sink.echo) - return; - - /* pass 1: calculate ascent/descent values and x coordinate */ - /* XXX the MAX ascent/descent value should be in the line table XXX */ - /* XXX the x coordinate can be a parameter, but since it is required - to calculate the ascent/descent, do it here to avoid an extra - search in the entities */ - pos = tmp = left = ctx->text.lt.info[line].position; - right = ctx->text.lt.info[line + 1].position; - right = XawMin(right, ctx->text.lastPos + 1); - while (pos < right) { - if (XawTextSourceAnchorAndEntity(ctx->text.source, pos, - &anchor, &entity)) { - if ((property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (property->mask & XAW_TPROP_FONT)) - font = property->font; - else - font = sink->ascii_sink.font; - tmp = pos; - pos = anchor->position + entity->offset + entity->length; - if ((length = XawMin(from, pos) - tmp) > 0) - x += GetTextWidth(ctx, x, font, tmp, length); - ascent = XawMax(font->ascent, ascent); - descent = XawMax(font->descent, descent); - } - else if (anchor) { - ascent = XawMax(sink->ascii_sink.font->ascent, ascent); - descent = XawMax(sink->ascii_sink.font->descent, descent); - while (entity && pos < right) { - tmp = pos; - if ((pos = anchor->position + entity->offset) < tmp) - pos = tmp; - else { - if ((length = XawMin(from, pos) - tmp) > 0) { - x += GetTextWidth(ctx, x, sink->ascii_sink.font, tmp, - length); - tmp += length; - } - if (pos < right) { - pos += entity->length; - if ((property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (property->mask & XAW_TPROP_FONT)) - font = property->font; - else - font = sink->ascii_sink.font; - if ((length = XawMin(from, pos) - tmp) > 0) - x += GetTextWidth(ctx, x, font, tmp, length); - ascent = XawMax(font->ascent, ascent); - descent = XawMax(font->descent, descent); - } - } - entity = entity->next; - } - - if (anchor->entities == NULL) { - tmp = XawMin(pos, from); - if ((length = from - tmp) > 0) - x += GetTextWidth(ctx, x, sink->ascii_sink.font, tmp, length); - break; - } - } - else { - tmp = XawMin(pos, from); - if ((length = from - tmp) > 0) - x += GetTextWidth(ctx, x, sink->ascii_sink.font, tmp, length); - ascent = XawMax(sink->ascii_sink.font->ascent, ascent); - descent = XawMax(sink->ascii_sink.font->descent, descent); - break; - } - } - if (!ascent) - ascent = sink->ascii_sink.font->ascent; - if (!descent) - descent = sink->ascii_sink.font->descent; - - xl = x; - - /* pass 2: feed the XawTextPaintStruct lists */ - pos = from; - while (pos < to) { - paint = XtNew(XawTextPaintStruct); - paint->next = sink->text_sink.paint->paint; - sink->text_sink.paint->paint = paint; - paint->x = x; - paint->y = y + ascent; - paint->property = NULL; - paint->max_ascent = ascent; - paint->max_descent = descent; - paint->backtabs = NULL; - paint->highlight = highlight; - - tmp = pos; - if (XawTextSourceAnchorAndEntity(ctx->text.source, pos, - &anchor, &entity)) { - pos = anchor->position + entity->offset + entity->length; - if ((paint->property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (paint->property->mask & XAW_TPROP_FONT)) - font = paint->property->font; - else - font = sink->ascii_sink.font; - } - else { - if (anchor) { - while (entity && anchor->position + entity->offset < pos) - entity = entity->next; - if (entity) - pos = anchor->position + entity->offset; - else - pos = to; - } - else - pos = to; - font = sink->ascii_sink.font; - } - pos = XawMin(pos, to); - length = pos - tmp; - - paint->text = XtMalloc(bufsiz = pos - tmp + 4); - paint->length = 0; - segment.x1 = x; - - pos2 = tmp; - while (length > 0) { - pos2 = XawTextSourceRead(ctx->text.source, tmp, &block, length); - length = pos - pos2; - tmp = pos2; - for (i = 0; i < block.length; i++) { - unsigned char c = (unsigned char)block.ptr[i]; - - if (paint->length + 4 > bufsiz) - paint->text = XtRealloc(paint->text, bufsiz += 32); - paint->text[paint->length] = c; - if (c == '\n') { - x += CharWidth(sink, font, 0, ' '); - continue; - } - if (c == '\t') { - x += XTextWidth(font, paint->text, paint->length); - segment.x2 = x + CharWidth(sink, font, x, '\t'); - - if (XmuValidSegment(&segment)) { - if (!highlight && (paint->property && - (paint->property->mask & XAW_TPROP_BACKGROUND))) { - if (ascent > font->ascent) { - scanline.y = y; - next.y = y + ascent - font->ascent; - XmuAreaOr(sink->text_sink.paint->clip, &area); - } - if (descent >= font->descent) { - scanline.y = y + ascent + font->descent; - next.y = scanline.y + descent - font->descent + 1; - XmuAreaOr(sink->text_sink.paint->clip, &area); - } - if (paint->backtabs == NULL) - paint->backtabs = XmuCreateArea(); - scanline.y = y + ascent - font->ascent; - next.y = y + ascent + font->descent; - XmuAreaOr(paint->backtabs, &area); - } - else { - scanline.y = y; - next.y = ctx->text.lt.info[line + 1].y; - if (highlight) { - if (!sink->text_sink.paint->hightabs) - sink->text_sink.paint->hightabs = - XmuCreateArea(); - XmuAreaOr(sink->text_sink.paint->hightabs, &area); - } - else - XmuAreaOr(sink->text_sink.paint->clip, &area); - } - } - - paint->width = segment.x2 - segment.x1; - x = segment.x1 = segment.x2; - - if (paint->length == 0) { - paint->x = x; - continue; - } - paint->text = XtRealloc(paint->text, paint->length); - property = paint->property; - paint = XtNew(XawTextPaintStruct); - paint->next = sink->text_sink.paint->paint; - sink->text_sink.paint->paint = paint; - paint->x = x; - paint->y = y + ascent; - paint->property = property; - paint->max_ascent = ascent; - paint->max_descent = descent; - paint->backtabs = NULL; - paint->highlight = highlight; - paint->text = XtMalloc(bufsiz = pos - tmp - length + - block.length - i + 4); - paint->length = 0; - continue; - } - if ((c & 0177) < XawSP || c == 0177) { - if (sink->ascii_sink.display_nonprinting) { - if (c > 0177) { - paint->text[paint->length++] = '\\'; - paint->text[paint->length++] = ((c >> 6) & 7) + '0'; - paint->text[paint->length++] = ((c >> 3) & 7) + '0'; - paint->text[paint->length] = (c & 7) + '0'; - } - else { - c |= 0100; - paint->text[paint->length++] = '^'; - paint->text[paint->length] = c == 0177 ? '?' : c; - } - } - else - paint->text[paint->length] = ' '; - } - paint->length++; - } - } - - x += XTextWidth(font, paint->text, paint->length); - segment.x2 = x; - if (XmuValidSegment(&segment)) { - /* erase only what really is needed */ - /*if (!highlight || (paint->property && - (paint->property->mask & XAW_TPROP_BACKGROUND))) { - if (ascent > font->ascent) { - scanline.y = y; - next.y = y + ascent - font->ascent; - XmuAreaOr(sink->text_sink.paint->clip, &area); - } - if (descent > font->descent) { - scanline.y = y + ascent + font->descent; - next.y = scanline.y + descent - font->descent; - XmuAreaOr(sink->text_sink.paint->clip, &area); - } - } - else*/ { - scanline.y = y; - next.y = ctx->text.lt.info[line + 1].y; - XmuAreaOr(sink->text_sink.paint->clip, &area); - } - } - - paint->width = x - segment.x1; - } - - xr = x; - - /* pass 3: bearing clipping */ - if (left < from) { - CalculateBearing(ctx, from - 1, xl, y, ascent, descent, highlight, True); - if (ctx->text.s.left < ctx->text.s.right) { - if (ctx->text.s.right == from) - CalculateBearing(ctx, from, xl, y, ascent, descent, True, False); - else if (ctx->text.s.left == from) - CalculateBearing(ctx, from, xl, y, ascent, descent, False, False); - } - } - right = XawMin(right, ctx->text.lastPos); - if (right >= to && to > from) { - if (to < right) - CalculateBearing(ctx, to, xr, y, ascent, descent, highlight, False); - if (ctx->text.s.left < ctx->text.s.right) { - if (ctx->text.s.right == to) - CalculateBearing(ctx, to - 1, xr, y, ascent, descent, False, True); - else if (ctx->text.s.left == to) - CalculateBearing(ctx, to - 1, xr, y, ascent, descent, True, True); - } - } -} - -static int -qcmp_paint_struct(_Xconst void *left, _Xconst void *right) -{ - return ((*(XawTextPaintStruct**)left)->property - - (*(XawTextPaintStruct**)right)->property); -} - -static void -AsciiDoPaint(Widget w) -{ - TextWidget ctx = (TextWidget)XtParent(w); - AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink; - XmuScanline *scan; - XmuSegment *seg; - XawTextPaintList *list = sink->text_sink.paint; -#if 0 - XawTextPaintStruct *base, *head; -#endif - XawTextPaintStruct *paint = list->paint; - XawTextProperty *property; - XFontStruct *font = NULL; - XRectangle *rects; - int n_rects, i_rects; - GC gc; - Bool highlight; - XRectangle rect; - int width, height, line_width = -1; - XGCValues values; - - /* pass 1: clear clipping areas */ - /* XXX Don't use XDrawImageString because the font may be italic, and - will get incorrectly drawn. Probably, it could be a good idea to - check if this is the case, and do special processing. But this - will need to be checked if required. */ - for (scan = list->clip->scanline; scan && scan->next; scan = scan->next) - for (seg = scan->segment; seg; seg = seg->next) - _XawTextSinkClearToBackground(ctx->text.sink, - seg->x1, scan->y, - seg->x2 - seg->x1, - scan->next->y - scan->y); - - /* pass 2: optimize drawing list to avoid too much GC change requests */ - /* XXX this assumes there will not exist entities drawn over other - entities. */ -#if 0 - while (paint) { - base = paint; - head = paint->next; - while (head) { - if (head->property == paint->property) { - base->next = head->next; - head->next = paint->next; - paint->next = head; - paint = head; - } - base = head; - head = head->next; - } - paint = paint->next; - } -#endif - if (paint && paint->next) { - XawTextPaintStruct **paints; - int i = 0, n_paints = 0; - - while (paint) { - paint = paint->next; - ++n_paints; - } - paints = (XawTextPaintStruct**) - XtMalloc(n_paints * sizeof(XawTextPaintStruct)); - paint = list->paint; - while (paint) { - paints[i++] = paint; - paint = paint->next; - } - qsort((void*)paints, n_paints, sizeof(XawTextPaintStruct*), - qcmp_paint_struct); - list->paint = paints[0]; - for (i = 0; i < n_paints - 1; i++) - paints[i]->next = paints[i + 1]; - paints[i]->next = NULL; - XtFree((XtPointer)paints); - } - - /* pass 3: clip gc */ - gc = sink->ascii_sink.normgc; - - rect.x = ctx->text.r_margin.left; - rect.y = ctx->text.r_margin.top; - width = (int)XtWidth(ctx) - RHMargins(ctx); - height = (int)XtHeight(ctx) - RVMargins(ctx); - rect.width = width; - rect.height = height; - if (width >= 0 && height >= 0) - XSetClipRectangles(XtDisplay((Widget)ctx), gc, - 0, 0, &rect, 1, Unsorted); - else - XSetClipMask(XtDisplay((Widget)ctx), gc, None); - - /* pass 4: draw backgrounds */ - paint = list->paint; - property = NULL; - rects = NULL; - i_rects = n_rects = 0; - while (paint) { - if (paint->property && (paint->property->mask & XAW_TPROP_BACKGROUND)) { - if (property != paint->property) { - if (i_rects) - XFillRectangles(XtDisplay(ctx), XtWindow(ctx), gc, - rects, i_rects); - i_rects = 0; - property = paint->property; - if (property->mask & XAW_TPROP_FONT) - font = property->font; - else - font = sink->ascii_sink.font; - XSetForeground(XtDisplay(ctx), gc, property->background); - } - if (i_rects <= n_rects) - rects = (XRectangle*) - XtRealloc((XtPointer)rects, sizeof(XRectangle) * - ++n_rects); - rects[i_rects].x = paint->x; - rects[i_rects].y = paint->y - font->ascent; - rects[i_rects].width = paint->width; - rects[i_rects++].height = font->ascent + font->descent; - - if (paint->backtabs) { - for (scan = paint->backtabs->scanline; scan && scan->next; - scan = scan->next) - for (seg = scan->segment; seg; seg = seg->next) { - if (i_rects <= n_rects) - rects = (XRectangle*) - XtRealloc((XtPointer)rects, sizeof(XRectangle) * - ++n_rects); - rects[i_rects].x = seg->x1; - rects[i_rects].y = scan->y; - rects[i_rects].width = seg->x2 - seg->x1; - rects[i_rects++].height = scan->next->y - scan->y; - } - } - - - } - paint = paint->next; - } - if (i_rects) - XFillRectangles(XtDisplay(ctx), XtWindow(ctx), gc, rects, i_rects); - - paint = list->paint; - i_rects = 0; - while (paint) { - if (paint->highlight) { - if (i_rects == 0) - XSetForeground(XtDisplay(ctx), gc, sink->text_sink.cursor_color); - if (i_rects <= n_rects) - rects = (XRectangle*) - XtRealloc((XtPointer)rects, sizeof(XRectangle) * - ++n_rects); - rects[i_rects].x = paint->x; - rects[i_rects].y = paint->y - paint->max_ascent; - rects[i_rects].width = paint->width; - rects[i_rects++].height = paint->max_ascent + paint->max_descent + 1; - } - paint = paint->next; - } - if (list->hightabs) { - for (scan = list->hightabs->scanline; scan && scan->next; - scan = scan->next) - for (seg = scan->segment; seg; seg = seg->next) { - if (i_rects == 0) - XSetForeground(XtDisplay(ctx), gc, - sink->text_sink.cursor_color); - if (i_rects <= n_rects) - rects = (XRectangle*) - XtRealloc((XtPointer)rects, sizeof(XRectangle) * - ++n_rects); - rects[i_rects].x = seg->x1; - rects[i_rects].y = scan->y; - rects[i_rects].width = seg->x2 - seg->x1; - rects[i_rects++].height = scan->next->y - scan->y; - } - } - - if (i_rects) - XFillRectangles(XtDisplay(ctx), XtWindow(ctx), gc, rects, i_rects); - if (rects) - XtFree((XtPointer)rects); - - /* pass 5: draw text! */ - paint = list->paint; - if (paint && (property = paint->property) == NULL) { - font = sink->ascii_sink.font; - XSetFont(XtDisplay(ctx), gc, font->fid); - if (!paint->highlight) - XSetForeground(XtDisplay(ctx), gc, sink->text_sink.foreground); - } - else - property = NULL; - highlight = False; - while (paint) { - if (!highlight && paint->highlight) - XSetForeground(XtDisplay(ctx), gc, sink->text_sink.background); - if (highlight || paint->highlight || paint->property != property) { - if (!paint->property || !(paint->property->mask & XAW_TPROP_FONT)) - font = sink->ascii_sink.font; - else - font = paint->property->font; - XSetFont(XtDisplay(ctx), gc, font->fid); - if (!paint->highlight) { - if (!paint->property || - !(paint->property->mask & XAW_TPROP_FOREGROUND)) - XSetForeground(XtDisplay(ctx), gc, - sink->text_sink.foreground); - else - XSetForeground(XtDisplay(ctx), gc, - paint->property->foreground); - } - highlight = paint->highlight; - property = paint->property; - } - - if (paint->x < XtWidth(ctx) && paint->x + paint->width > 0) { - XDrawString(XtDisplay(ctx), XtWindow(ctx), gc, paint->x, paint->y, - paint->text, paint->length); - if (property) { - if (property->mask & XAW_TPROP_UNDERLINE) { - if (line_width != property->underline_thickness) { - values.line_width = line_width = - property->underline_thickness; - XChangeGC(XtDisplay(ctx), gc, GCLineWidth, &values); - } - - XDrawLine(XtDisplay(ctx), XtWindow(ctx), gc, paint->x, - paint->y + property->underline_position, - paint->x + paint->width, - paint->y + property->underline_position); - } - if (property->mask & XAW_TPROP_OVERSTRIKE) { - if (line_width != property->underline_thickness) { - values.line_width = line_width = - property->underline_thickness; - XChangeGC(XtDisplay(ctx), gc, GCLineWidth, &values); - } - - XDrawLine(XtDisplay(ctx), XtWindow(ctx), gc, paint->x, - paint->y - (font->ascent>>1) + (font->descent>>1), - paint->x + paint->width, - paint->y - (font->ascent>>1) + (font->descent>>1)); - } - } - } - - paint = paint->next; - } - - /* pass 6: bearing clipping */ - /* dont care on order of drawing or caching of state (by now) */ - paint = list->bearings; - while (paint) { - XRectangle rect; - - if (paint->highlight) - XSetForeground(XtDisplay(ctx), gc, sink->text_sink.background); - if (!paint->property || !(paint->property->mask & XAW_TPROP_FONT)) - font = sink->ascii_sink.font; - else - font = paint->property->font; - XSetFont(XtDisplay(ctx), gc, font->fid); - if (!paint->highlight) { - if (!paint->property || - !(paint->property->mask & XAW_TPROP_FOREGROUND)) - XSetForeground(XtDisplay(ctx), gc, sink->text_sink.foreground); - else - XSetForeground(XtDisplay(ctx), gc, paint->property->foreground); - } - if (paint->x < XtWidth(ctx) && paint->x + paint->width > 0) { - rect.x = paint->x + paint->width; - rect.width = XawAbs(paint->width); /* more than enough */ - rect.y = paint->y - font->ascent; - rect.height = rect.y + font->ascent + font->descent; - XSetClipRectangles(XtDisplay((Widget)ctx), gc, - 0, 0, &rect, 1, Unsorted); - XDrawString(XtDisplay(ctx), XtWindow(ctx), gc, paint->x, paint->y, - paint->text, paint->length); - } - paint = paint->next; - } -} -#endif - -/* - * Function: - * PaintText - * - * Parameters: - * w - text sink object - * gc - gc to paint text with - * 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 unsigned int -PaintText(Widget w, GC gc, int x, int y, char *buf, int len, Bool clear_bg) -{ - AsciiSinkObject sink = (AsciiSinkObject)w; - TextWidget ctx = (TextWidget)XtParent(w); - int width = XTextWidth(sink->ascii_sink.font, buf, len); - - if ((x > XtWidth(ctx)) || width <= -x) /* Don't draw if we can't see it */ - return (width); - - if (clear_bg) { - _XawTextSinkClearToBackground(w, x, y - sink->ascii_sink.font->ascent, - width, sink->ascii_sink.font->ascent - + sink->ascii_sink.font->descent); - XDrawString(XtDisplay(ctx), XtWindow(ctx), gc, x, y, buf, len); - } - else - XDrawImageString(XtDisplay(ctx), XtWindow(ctx), gc, x, y, buf, len); - - return (width); -} - -static void -DisplayText(Widget w, int x, int y, - XawTextPosition pos1, XawTextPosition pos2, Bool highlight) -{ - TextWidget ctx = (TextWidget)XtParent(w); - AsciiSinkObject sink = (AsciiSinkObject)w; - XFontStruct *font = sink->ascii_sink.font; - Widget source = XawTextGetSource(XtParent(w)); - unsigned char buf[260]; - int j, k; - XawTextBlock blk; - GC gc, invgc, tabgc; - int max_x; - Bool clear_bg; - - if (!sink->ascii_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->ascii_sink.invgc : sink->ascii_sink.normgc; - invgc = highlight ? sink->ascii_sink.normgc : sink->ascii_sink.invgc; - - if (highlight && sink->ascii_sink.xorgc) - tabgc = sink->ascii_sink.xorgc; - else - tabgc = invgc; - - y += sink->ascii_sink.font->ascent; - for (j = 0; pos1 < pos2;) { - pos1 = XawTextSourceRead(source, pos1, &blk, pos2 - pos1); - for (k = 0; k < blk.length; k++) { - if (j >= sizeof(buf) - 4) { /* buffer full, dump the text */ - if ((x += PaintText(w, gc, x, y, (char*)buf, j, clear_bg)) - >= max_x) - return; - j = 0; - } - buf[j] = blk.ptr[k]; - if (buf[j] == XawLF) /* line feeds ('\n') are not printed */ - continue; - - else if (buf[j] == '\t') { - int width; - - if (j != 0 - && (x += PaintText(w, gc, x, y, (char*)buf, j, clear_bg)) - >= max_x) - return; - - if ((width = CharWidth(sink, font, x, '\t')) > -x) { - if (clear_bg) - _XawTextSinkClearToBackground(w, x, y-font->ascent, width, - font->ascent+font->descent); - else - XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), - tabgc, x, y - font->ascent, width, - font->ascent + font->descent); - } - - if ((x += width) >= max_x) - return; - - j = -1; - } - else if ((buf[j] & 0177) < XawSP || buf[j] == 0177) { - if (sink->ascii_sink.display_nonprinting) { - unsigned char c = buf[j]; - - if (c > 0177) { - buf[j++] = '\\'; - buf[j++] = ((c >> 6) & 7) + '0'; - buf[j++] = ((c >> 3) & 7) + '0'; - buf[j] = (c & 7) + '0'; - } - else { - c |= 0100; - buf[j++] = '^'; - buf[j] = c == 0177 ? '?' : c; - } - } - else - buf[j] = ' '; - } - j++; - } - } - - if (j > 0) - (void)PaintText(w, gc, x, y, (char*)buf, j, clear_bg); -} - -/* - * 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) -{ - AsciiSinkObject sink = (AsciiSinkObject)w; - XFontStruct *font = sink->ascii_sink.font; - unsigned char ch; -#ifndef OLDXAW - TextWidget ctx = (TextWidget)XtParent(w); - XawTextBlock block; - XawTextAnchor *anchor; - XawTextEntity *entity; - XawTextProperty *property; - - if (XawTextSourceAnchorAndEntity(XawTextGetSource(XtParent(w)), - sink->ascii_sink.cursor_position, - &anchor, &entity)) { - if ((property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (property->mask & XAW_TPROP_FONT)) - font = property->font; - } - (void)XawTextSourceRead(XawTextGetSource((Widget)ctx), - ctx->text.insertPos, &block, 1); - if (!block.length || block.ptr[0] == '\n' || block.ptr[0] == '\t') - ch = ' '; - else if ((*((unsigned char*)block.ptr) & 0177) < XawSP || - *(unsigned char*)block.ptr == 0177) { - if (sink->ascii_sink.display_nonprinting) - ch = *((unsigned char*)block.ptr) > 0177 ? '\\' : '^'; - else - ch = ' '; - } - else - ch = *(unsigned char*)block.ptr; -#else - ch = ' '; -#endif - - rect->width = CharWidth(sink, font, 0, ch); - rect->height = font->descent + font->ascent + 1; - - rect->x = sink->ascii_sink.cursor_x; - rect->y = sink->ascii_sink.cursor_y - font->ascent; -} - -/* this function is required to support diferent fonts and correctly place - * the cursor. There are better ways to calculate the base line, but there is - * no place/code (yet) to store this information. - */ -static int -FindCursorY(TextWidget ctx, XawTextPosition position) -{ - int y, line, ascent; - AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink; -#ifndef OLDXAW - XawTextAnchor *anchor; - XawTextEntity *entity; - XawTextProperty *property; - XawTextPosition left, right; -#endif - - for (line = 0; line < ctx->text.lt.lines; line++) - if (position < ctx->text.lt.info[line + 1].position) - break; - - y = ctx->text.lt.info[line].y; -#ifndef OLDXAW - ascent = 0; - left = ctx->text.lt.info[line].position; - right = ctx->text.lt.info[line + 1].position; - right = XawMin(right, ctx->text.lastPos + 1); - while (left < right) { - if (XawTextSourceAnchorAndEntity(ctx->text.source, left, - &anchor, &entity)) { - if ((property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (property->mask & XAW_TPROP_FONT)) - ascent = XawMax(property->font->ascent, ascent); - else - ascent = XawMax(sink->ascii_sink.font->ascent, ascent); - left = anchor->position + entity->offset + entity->length; - } - else if (anchor) { - ascent = XawMax(sink->ascii_sink.font->ascent, ascent); - while (entity) { - XawTextPosition tmp = anchor->position + entity->offset + entity->length; - - if (tmp > left && tmp < right) { - left = tmp; - if ((property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (property->mask & XAW_TPROP_FONT)) - ascent = XawMax(property->font->ascent, ascent); - else - ascent = XawMax(sink->ascii_sink.font->ascent, ascent); - } - entity = entity->next; - } - if (entity == NULL) - break; - } - else { - ascent = XawMax(sink->ascii_sink.font->ascent, ascent); - break; - } - } - if (!ascent) - ascent = sink->ascii_sink.font->ascent; -#else - ascent = sink->ascii_sink.font->ascent; -#endif - - return (y + ascent); -} - -static void -InsertCursor(Widget w, int x, int y, XawTextInsertState state) -{ - AsciiSinkObject sink = (AsciiSinkObject)w; - XFontStruct *font = sink->ascii_sink.font; - TextWidget ctx = (TextWidget)XtParent(w); - XawTextPosition position = XawTextGetInsertionPoint((Widget)ctx); - Boolean overflow = (x & 0xffff8000) != 0; -#ifndef OLDXAW - XawTextAnchor *anchor; - XawTextEntity *entity; - XawTextProperty *property; -#endif - - if (XtIsRealized((Widget)ctx)) { - int fheight; - XawTextBlock block; - XawTextPosition selection_start, selection_end; - Boolean has_selection; - - if (!sink->ascii_sink.echo) { - if (sink->ascii_sink.laststate != state) { - int width = CharWidth(sink, font, 0, ' ') - 1; - - x = ctx->text.margin.left; - y = ctx->text.margin.top; - font = sink->ascii_sink.font; - fheight = font->ascent + font->descent; - if (state == XawisOn) { - if (ctx->text.hasfocus) - XFillRectangle(XtDisplay(ctx), XtWindow(ctx), - sink->ascii_sink.xorgc, x, y, - width + 1, fheight + 1); - else - XDrawRectangle(XtDisplay(ctx), XtWindow(ctx), - sink->ascii_sink.xorgc, x, y, - width, fheight); - - } - else - _XawTextSinkClearToBackground(w, x, y, - width + 1, fheight + 1); - } - sink->ascii_sink.cursor_x = x; - sink->ascii_sink.cursor_y = y; - sink->ascii_sink.laststate = state; - return; - } - - - XawTextGetSelectionPos((Widget)ctx, &selection_start, &selection_end); - has_selection = selection_start != selection_end; - - if (sink->ascii_sink.laststate != state) { - unsigned char ch; - -#ifndef OLDXAW - if (XawTextSourceAnchorAndEntity(ctx->text.source, - position, &anchor, &entity) && - (property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (property->mask & XAW_TPROP_FONT)) - font = property->font; - else - font = sink->ascii_sink.font; -#endif - - fheight = font->ascent + font->descent; - (void)XawTextSourceRead(XawTextGetSource((Widget)ctx), - position, &block, 1); - if (!block.length || block.ptr[0] == '\n' || block.ptr[0] == '\t') - ch = ' '; - else if ((*((unsigned char*)block.ptr) & 0177) < XawSP - || *(unsigned char*)block.ptr == 0177) { - if (sink->ascii_sink.display_nonprinting) - ch = *((unsigned char*)block.ptr) > 0177 ? '\\' : '^'; - else - ch = ' '; - } - else - ch = *(unsigned char*)block.ptr; - - y = FindCursorY(ctx, position); - if (ctx->text.hasfocus && !has_selection) - XFillRectangle(XtDisplay(ctx), XtWindow(ctx), - sink->ascii_sink.xorgc, x, y - font->ascent, - CharWidth(sink, font, 0, ch), fheight + 1); - else - XDrawRectangle(XtDisplay(ctx), XtWindow(ctx), - sink->ascii_sink.xorgc, x, y - font->ascent, - CharWidth(sink, font, 0, ch) - 1, fheight); - } - } - - sink->ascii_sink.cursor_x = overflow ? -16384 : x; - sink->ascii_sink.cursor_y = y; - sink->ascii_sink.laststate = state; - sink->ascii_sink.cursor_position = position; -} - -/* - * 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) -{ -#ifndef OLDXAW - AsciiSinkObject sink = (AsciiSinkObject)w; - TextWidget ctx = (TextWidget)XtParent(w); - XFontStruct *font = sink->ascii_sink.font; - Widget source = ctx->text.source; - XawTextPosition idx, pos; - unsigned char c; - XawTextBlock blk; - int i, rWidth, ascent = 0, descent = 0; - XawTextAnchor *anchor; - XawTextEntity *entity; - XawTextProperty *property; - Cardinal length; - Bool done = False; - - pos = idx = fromPos; - rWidth = 0; - c = 0; - - while (!done) { - if (XawTextSourceAnchorAndEntity(source, pos, &anchor, &entity)) { - length = anchor->position + entity->offset + entity->length; - length = XawMin(toPos, length) - pos; - if ((property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (property->mask & XAW_TPROP_FONT)) - font = property->font; - else - font = sink->ascii_sink.font; - } - else { - if (anchor) { - while (entity && anchor->position + entity->offset < pos) - entity = entity->next; - if (entity) { - length = anchor->position + entity->offset; - length = XawMin(toPos, length) - pos; - } - else - length = XawMin(toPos - pos, 4096); - } - else - length = XawMin(toPos - pos, 4096); - font = sink->ascii_sink.font; - } - - ascent = XawMax(font->ascent, ascent); - descent = XawMax(font->descent, descent); - - pos = XawTextSourceRead(source, pos, &blk, length); - if (blk.length == 0 && pos == idx) /* eof reached */ - break; - - idx = blk.firstPos; - for (i = 0; idx < toPos; i++, idx++) { - if (i >= blk.length) - break; - c = blk.ptr[i]; - rWidth += CharWidth(sink, font, fromx + rWidth, c); - if (c == XawLF) { - idx++; - done = True; - break; - } - } - if (idx >= toPos) - break; - } - - *resPos = idx; - *resWidth = rWidth; - *resHeight = ascent + descent + 1; -#else - AsciiSinkObject sink = (AsciiSinkObject)w; - TextWidget ctx = (TextWidget)XtParent(w); - XFontStruct *font = sink->ascii_sink.font; - Widget source = ctx->text.source; - XawTextPosition idx, pos; - unsigned char c; - 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; - pos = XawTextSourceRead(source, pos, &blk, toPos - pos); - if (blk.length == 0) - break; - } - c = blk.ptr[i]; - rWidth += CharWidth(sink, font, fromx + rWidth, c); - if (c == XawLF) { - idx++; - break; - } - } - - *resPos = idx; - *resWidth = rWidth; - *resHeight = font->ascent + font->descent + 1; -#endif -} - -static void -FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width, - Bool stopAtWordBreak, XawTextPosition *resPos, - int *resWidth, int *resHeight) -{ -#ifndef OLDXAW - AsciiSinkObject sink = (AsciiSinkObject)w; - TextWidget ctx = (TextWidget)XtParent(w); - Widget source = ctx->text.source; - XFontStruct *font = sink->ascii_sink.font; - XawTextPosition idx, pos, whiteSpacePosition = 0; - int i, lastWidth, whiteSpaceWidth, rWidth, ascent = 0, descent = 0; - Boolean whiteSpaceSeen; - unsigned char c; - XawTextBlock blk; - XawTextAnchor *anchor; - XawTextEntity *entity; - XawTextProperty *property; - Cardinal length; - Bool done = False; - - pos = idx = fromPos; - rWidth = lastWidth = whiteSpaceWidth = 0; - whiteSpaceSeen = False; - c = 0; - - while (!done) { - font = sink->ascii_sink.font; - if (XawTextSourceAnchorAndEntity(source, pos, &anchor, &entity)) { - length = anchor->position + entity->offset + entity->length - pos; - if ((property = XawTextSinkGetProperty((Widget)sink, - entity->property)) != NULL && - (property->mask & XAW_TPROP_FONT)) - font = property->font; - } - else { - if (anchor) { - while (entity && anchor->position + entity->offset < pos) - entity = entity->next; - if (entity) - length = anchor->position + entity->offset - pos; - else - length = 4096; - } - else - length = 4096; - } - - ascent = XawMax(font->ascent, ascent); - descent = XawMax(font->descent, descent); - - pos = XawTextSourceRead(source, pos, &blk, length); - if (blk.length == 0 && pos == idx) /* eof reached */ - break; - - idx = blk.firstPos; - for (i = 0; rWidth <= width && i < blk.length; i++, idx++) { - c = blk.ptr[i]; - lastWidth = rWidth; - rWidth += CharWidth(sink, font, fromx + rWidth, c); - - if (c == XawLF) { - idx++; - done = True; - break; - } - else if ((c == XawSP || c == XawTAB) && rWidth <= width) { - whiteSpaceSeen = True; - whiteSpacePosition = idx; - whiteSpaceWidth = rWidth; - } - } - if (rWidth > width) - break; - } - - if (rWidth > width && idx > fromPos) { - idx--; - rWidth = lastWidth; - if (stopAtWordBreak && whiteSpaceSeen) { - idx = whiteSpacePosition + 1; - rWidth = whiteSpaceWidth; - } - } - - if (idx >= ctx->text.lastPos && c != XawLF) - idx = ctx->text.lastPos + 1; - - *resPos = idx; - *resWidth = rWidth; - *resHeight = ascent + descent + 1; -#else - AsciiSinkObject sink = (AsciiSinkObject)w; - TextWidget ctx = (TextWidget)XtParent(w); - Widget source = ctx->text.source; - XFontStruct *font = sink->ascii_sink.font; - XawTextPosition idx, pos, whiteSpacePosition = 0; - int i, lastWidth, whiteSpaceWidth, rWidth; - Boolean whiteSpaceSeen; - unsigned char c; - 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 = blk.ptr[i]; - lastWidth = rWidth; - rWidth += CharWidth(sink, font, fromx + rWidth, c); - - if (c == XawLF) { - idx++; - break; - } - else if ((c == XawSP || c == 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 != XawLF) - idx = ctx->text.lastPos + 1; - - *resPos = idx; - *resWidth = rWidth; - *resHeight = font->ascent + font->descent + 1; -#endif -} - -static void -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, pos_return, &resWidth, &resHeight); - if (*pos_return > GETLASTPOS) - *pos_return = GETLASTPOS; -} - -static void -GetGC(AsciiSinkObject sink) -{ - XtGCMask valuemask = (GCFont | GCGraphicsExposures | GCClipXOrigin | - GCForeground | GCBackground); - XGCValues values; - - /* 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.font = sink->ascii_sink.font->fid; - values.graphics_exposures = False; - - values.foreground = sink->text_sink.foreground; - values.background = sink->text_sink.background; - sink->ascii_sink.normgc = XtAllocateGC((Widget)sink, 0, valuemask, &values, - GCClipMask | GCFont | GCForeground | - GCBackground, 0); - - values.foreground = sink->text_sink.background; -#ifndef OLDXAW - values.background = sink->text_sink.cursor_color; -#else - values.background = sink->text_sink.foreground; -#endif - sink->ascii_sink.invgc = XtAllocateGC((Widget)sink, 0, valuemask, &values, - GCClipMask | GCFont, 0); - - valuemask |= GCFunction; - values.function = GXxor; -#ifndef OLDXAW - values.foreground = sink->text_sink.background ^ sink->text_sink.cursor_color; -#else - values.foreground = sink->text_sink.background ^ sink->text_sink.foreground; -#endif - values.background = 0L; - sink->ascii_sink.xorgc = XtAllocateGC((Widget)sink, 0, valuemask, - &values, GCClipMask | GCFont, 0); - - XawAsciiSinkResize((Widget)sink); -} - -/* Function: - * XawAsciiSinkInitialize - * - * Parameters: - * request - the requested and new values for the object instance - * cnew - "" - * - * Description: - * Initializes the TextSink Object. - */ -/*ARGSUSED*/ -static void -XawAsciiSinkInitialize(Widget request, Widget cnew, - ArgList args, Cardinal *num_args) -{ - AsciiSinkObject sink = (AsciiSinkObject)cnew; - - GetGC(sink); - - if (!sink->ascii_sink.font) XtError("Aborting: no font found\n"); - - sink->ascii_sink.cursor_position = 0; - sink->ascii_sink.laststate = XawisOff; - sink->ascii_sink.cursor_x = sink->ascii_sink.cursor_y = 0; -} - -/* - * Function: - * XawAsciiSinkDestroy - * - * Parameters: - * w - AsciiSink Object - * - * Description: - * This function cleans up when the object is destroyed. - */ -static void -XawAsciiSinkDestroy(Widget w) -{ - AsciiSinkObject sink = (AsciiSinkObject)w; - - XtReleaseGC(w, sink->ascii_sink.normgc); - XtReleaseGC(w, sink->ascii_sink.invgc); - XtReleaseGC(w, sink->ascii_sink.xorgc); - - sink->ascii_sink.normgc = - sink->ascii_sink.invgc = - sink->ascii_sink.xorgc = NULL; -} - -static void -XawAsciiSinkResize(Widget w) -{ - TextWidget ctx = (TextWidget)XtParent(w); - AsciiSinkObject sink = (AsciiSinkObject)w; - XRectangle rect; - int width, height; - - if (w->core.widget_class != asciiSinkObjectClass) - return; - - rect.x = ctx->text.r_margin.left; - rect.y = ctx->text.r_margin.top; - width = (int)XtWidth(ctx) - RHMargins(ctx); - height = (int)XtHeight(ctx) - RVMargins(ctx); - rect.width = width; - rect.height = height; - - if (sink->ascii_sink.normgc) { - if (width >= 0 && height >= 0) - XSetClipRectangles(XtDisplay((Widget)ctx), sink->ascii_sink.normgc, - 0, 0, &rect, 1, Unsorted); - else - XSetClipMask(XtDisplay((Widget)ctx), sink->ascii_sink.normgc, None); - } - if (sink->ascii_sink.invgc) { - if (width >= 0 && height >= 0) - XSetClipRectangles(XtDisplay((Widget)ctx), sink->ascii_sink.invgc, - 0, 0, &rect, 1, Unsorted); - else - XSetClipMask(XtDisplay((Widget)ctx), sink->ascii_sink.invgc, None); - } - if (sink->ascii_sink.xorgc) { - if (width >= 0 && height >= 0) - XSetClipRectangles(XtDisplay((Widget)ctx), sink->ascii_sink.xorgc, - 0, 0, &rect, 1, Unsorted); - else - XSetClipMask(XtDisplay((Widget)ctx), sink->ascii_sink.xorgc, None); - } -} - -/* - * Function: - * XawAsciiSinkSetValues - * - * Parameters: - * current - current state of the object - * request - what was requested - * cnew - what the object will become - * - * Description: - * Sets the values for the AsciiSink. - * - * Returns: - * True if redisplay is needed - */ -/*ARGSUSED*/ -static Boolean -XawAsciiSinkSetValues(Widget current, Widget request, Widget cnew, - ArgList args, Cardinal *num_args) -{ - AsciiSinkObject w = (AsciiSinkObject)cnew; - AsciiSinkObject old_w = (AsciiSinkObject)current; - - if (w->ascii_sink.font != old_w->ascii_sink.font - || 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 - || w->text_sink.properties != old_w->text_sink.properties -#endif - ) { -#ifdef OLDXAW - XtReleaseGC(cnew, w->ascii_sink.normgc); - XtReleaseGC(cnew, w->ascii_sink.invgc); - XtReleaseGC(cnew, w->ascii_sink.xorgc); - GetGC(w); -#endif - ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; - } - else if (w->ascii_sink.echo != old_w->ascii_sink.echo - || w->ascii_sink.display_nonprinting - != old_w->ascii_sink.display_nonprinting) - ((TextWidget)XtParent(cnew))->text.redisplay_needed = True; -#ifndef OLDXAW - if (w->text_sink.properties != old_w->text_sink.properties) { - XawTextProperty *property = - XawTextSinkGetProperty(cnew, XrmStringToQuark("default")); - - if (property) { - if (property->mask & XAW_TPROP_FONT) - w->ascii_sink.font = property->font; - if (property->mask & XAW_TPROP_FOREGROUND) - w->text_sink.foreground = property->foreground; - if (property->mask & XAW_TPROP_BACKGROUND) - w->text_sink.background = property->background; - } - } -#endif - - return (False); -} - -/* - * Function: - * MaxLines - * - * Parameters: - * w - AsciiSink 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*/ -static int -MaxLines(Widget w, unsigned int height) -{ - AsciiSinkObject sink = (AsciiSinkObject)w; - int font_height; - - font_height = sink->ascii_sink.font->ascent + sink->ascii_sink.font->descent + 1; - - return ((int)height / font_height); -} - -/* - * Function: - * MaxHeight - * - * Parameters: - * w - AsciiSink Object - * lines - number of lines - * - * Description: - * Finds the Minium height that will contain a given number lines. - * - * Returns: - * the height - */ -static int -MaxHeight(Widget w, int lines) -{ - AsciiSinkObject sink = (AsciiSinkObject)w; - - return (lines * (sink->ascii_sink.font->ascent + - sink->ascii_sink.font->descent + 1)); -} - -/* - * Function: - * SetTabs - * - * Parameters: - * w - AsciiSink Object - * tab_count - number of tabs in the list - * tabs - text positions of the tabs - * - * Description: - * Sets the Tab stops. - */ -static void -SetTabs(Widget w, int tab_count, short *tabs) -{ - AsciiSinkObject sink = (AsciiSinkObject)w; - int i; - Atom XA_FIGURE_WIDTH; - unsigned long figure_width = 0; - XFontStruct *font = sink->ascii_sink.font; - - /* - * 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, tab_count * sizeof(Position)); - sink->text_sink.char_tabs = (short *) - XtRealloc((char*)sink->text_sink.char_tabs, 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 ctx = (TextWidget)XtParent(w); - ctx->text.redisplay_needed = True; - _XawTextBuildLineTable(ctx, ctx->text.lt.top, True); - } -#endif -} |