summaryrefslogtreecommitdiff
path: root/src/AsciiSink.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/AsciiSink.c')
-rw-r--r--src/AsciiSink.c2162
1 files changed, 1708 insertions, 454 deletions
diff --git a/src/AsciiSink.c b/src/AsciiSink.c
index ddf6115..fe812d9 100644
--- a/src/AsciiSink.c
+++ b/src/AsciiSink.c
@@ -46,647 +46,1901 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
+/* $XFree86: xc/lib/Xaw/AsciiSink.c,v 1.28 2002/09/08 02:29:47 paulo Exp $ */
#include <stdio.h>
-
-#include <X11/Xatom.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> /* For source function defs. */
-#include <X11/Xaw/TextP.h> /* I also reach into the text widget. */
+#include <X11/Xaw/AsciiSrcP.h>
+#include <X11/Xaw/TextP.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 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
-static void DisplayText(), InsertCursor(), FindPosition();
-static void FindDistance(), Resolve(), GetCursorBounds();
+/*
+ * 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);
-#define offset(field) XtOffsetOf(AsciiSinkRec, ascii_sink.field)
+/*
+ * 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},
+ {
+ 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)
+#define Superclass (&textSinkClassRec)
AsciiSinkClassRec asciiSinkClassRec = {
+ /* object */
{
-/* core_class fields */
- /* superclass */ (WidgetClass) SuperClass,
- /* class_name */ "AsciiSink",
- /* widget_size */ sizeof(AsciiSinkRec),
- /* 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
+ (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_class fields */
+ /* text_sink */
{
- /* DisplayText */ DisplayText,
- /* InsertCursor */ InsertCursor,
- /* ClearToBackground */ XtInheritClearToBackground,
- /* FindPosition */ FindPosition,
- /* FindDistance */ FindDistance,
- /* Resolve */ Resolve,
- /* MaxLines */ MaxLines,
- /* MaxHeight */ MaxHeight,
- /* SetTabs */ SetTabs,
- /* GetCursorBounds */ GetCursorBounds
+ 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_class fields */
+ /* ascii_sink */
{
- /* unused */ 0
+ NULL, /* extension */
}
};
WidgetClass asciiSinkObjectClass = (WidgetClass)&asciiSinkClassRec;
-/* Utilities */
+/*
+ * 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 (w, x, c)
-Widget w;
-int x;
-unsigned char c;
+static int
+CharWidth(AsciiSinkObject sink, XFontStruct *font, int x, unsigned int c)
{
- int i, width, nonPrinting;
- AsciiSinkObject sink = (AsciiSinkObject) w;
- XFontStruct *font = sink->ascii_sink.font;
- Position *tab;
+ int width = 0;
- if ( c == XawLF ) return(0);
+ if (c == XawLF)
+ return (0);
if (c == XawTAB) {
- /* Adjust for Left Margin. */
- x -= ((TextWidget) XtParent(w))->text.margin.left;
-
- if (x >= (int)XtParent(w)->core.width) return 0;
- for (i = 0, tab = sink->text_sink.tabs ;
- i < sink->text_sink.tab_count ; i++, tab++) {
- if (x < *tab) {
- if (*tab < (int)XtParent(w)->core.width)
- return *tab - x;
- else
- return 0;
+ 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;
}
- return 0;
+ /*NOTREACHED*/
}
- if ( (nonPrinting = (c < (unsigned char) XawSP)) )
- if (sink->ascii_sink.display_nonprinting)
- c += '@';
- else {
- c = XawSP;
- nonPrinting = False;
+ 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;
+ 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;
+ width += font->min_bounds.width;
- if (nonPrinting)
- width += CharWidth(w, x, (unsigned char) '^');
+ 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;
+ 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.
+static
+void CalculateBearing(TextWidget ctx, XawTextPosition position, int x, int y,
+ int ascent, int descent, Bool highlight, Bool right)
+{
+/*
+ * Sample case:
+ *
+ * lbearing| width |rbearing
+ * | |
+ * | ####
+ * | ### |
+ * | #### |
+ * | #### |
+ * | ########## |
+ * | #### |
+ * | #### |
+ * | #### |
+ * | #### |
+ * |### |
+ * #### |
+ * | |
*
- * NOTE: If this string attempts to paint past the end of the window
- * then this function will return zero.
*/
+ 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 Dimension
-PaintText(w, gc, x, y, buf, len)
-Widget w;
-GC gc;
-Position x, y;
-unsigned char * buf;
-int len;
+static void
+AsciiPreparePaint(Widget w, int y, int line,
+ XawTextPosition from, XawTextPosition to, Bool highlight)
{
- AsciiSinkObject sink = (AsciiSinkObject) w;
- TextWidget ctx = (TextWidget) XtParent(w);
-
- Position max_x;
- Dimension width = XTextWidth(sink->ascii_sink.font, (char *) buf, len);
- max_x = (Position) ctx->core.width;
-
- if ( ((int) width) <= -x) /* Don't draw if we can't see it. */
- return(width);
-
- XDrawImageString(XtDisplay(ctx), XtWindow(ctx), gc,
- (int) x, (int) y, (char *) 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->ascii_sink.normgc, (int) x,
- (int) y - sink->ascii_sink.font->ascent,
- (unsigned int) width,
- (unsigned int) (sink->ascii_sink.font->ascent +
- sink->ascii_sink.font->descent));
- return(0);
- }
- return(width);
+ 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);
}
-/* Sink Object Functions */
+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
/*
- * This function does not know about drawing more than one line of text.
+ * 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 void
-DisplayText(w, x, y, pos1, pos2, highlight)
-Widget w;
-Position x, y;
-Boolean highlight;
-XawTextPosition pos1, pos2;
+static unsigned int
+PaintText(Widget w, GC gc, int x, int y, char *buf, int len, Bool clear_bg)
{
- AsciiSinkObject sink = (AsciiSinkObject) w;
- Widget source = XawTextGetSource(XtParent(w));
- unsigned char buf[BUFSIZ];
+ 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 = highlight ? sink->ascii_sink.invgc : sink->ascii_sink.normgc;
- GC invgc = highlight ? sink->ascii_sink.normgc : sink->ascii_sink.invgc;
+ 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;
- if (!sink->ascii_sink.echo) return;
+ 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, (int) pos2 - pos1);
+ for (j = 0; pos1 < pos2;) {
+ pos1 = XawTextSourceRead(source, pos1, &blk, 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 (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;
+ if (buf[j] == XawLF) /* line feeds ('\n') are not printed */
+ continue;
else if (buf[j] == '\t') {
- Position temp = 0;
- Dimension width;
-
- if ((j != 0) && ((temp = PaintText(w, gc, x, y, buf, j)) == 0))
- return;
-
- x += temp;
- width = CharWidth(w, x, (unsigned char) '\t');
- XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
- invgc, (int) x,
- (int) y - sink->ascii_sink.font->ascent,
- (unsigned int) width,
- (unsigned int) (sink->ascii_sink.font->ascent +
- sink->ascii_sink.font->descent));
- x += width;
+ 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] < (unsigned char) ' ' ) {
- if (sink->ascii_sink.display_nonprinting) {
- buf[j + 1] = buf[j] + '@';
- buf[j] = '^';
- j++;
+ 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] = ' ';
+ buf[j] = ' ';
}
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, (char*)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)
{
- AsciiSinkObject sink = (AsciiSinkObject) w;
+ 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->width = (unsigned short) insertCursor_width;
- rect->height = (unsigned short) insertCursor_height;
- rect->x = sink->ascii_sink.cursor_x - (short) (rect->width / 2);
- rect->y = sink->ascii_sink.cursor_y - (short) rect->height;
+ rect->x = sink->ascii_sink.cursor_x;
+ rect->y = sink->ascii_sink.cursor_y - font->ascent;
}
-/*
- * The following procedure manages the "insert" cursor.
+/* 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 (w, x, y, state)
-Widget w;
-Position x, y;
-XawTextInsertState state;
+InsertCursor(Widget w, int x, int y, XawTextInsertState state)
{
- AsciiSinkObject sink = (AsciiSinkObject) w;
- Widget text_widget = XtParent(w);
- XRectangle rect;
+ 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
- sink->ascii_sink.cursor_x = x;
- sink->ascii_sink.cursor_y = y;
+ 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);
- GetCursorBounds(w, &rect);
- if (state != sink->ascii_sink.laststate && XtIsRealized(text_widget))
- XCopyPlane(XtDisplay(text_widget),
- sink->ascii_sink.insertCursorOn,
- XtWindow(text_widget), sink->ascii_sink.xorgc,
- 0, 0, (unsigned int) rect.width, (unsigned int) rect.height,
- (int) rect.x, (int) rect.y, 1);
+ }
+ 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.
+ * 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)
{
- AsciiSinkObject sink = (AsciiSinkObject) w;
- Widget source = XawTextGetSource(XtParent(w));
-
- XawTextPosition index, lastPos;
+#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;
+ }
- /* 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 = blk.ptr[index - blk.firstPos];
- *resWidth += CharWidth(w, fromx + *resWidth, c);
+ *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) {
- index++;
+ idx++;
break;
}
}
- *resPos = index;
- *resHeight = sink->ascii_sink.font->ascent +sink->ascii_sink.font->descent;
-}
+ *resPos = idx;
+ *resWidth = rWidth;
+ *resHeight = font->ascent + font->descent + 1;
+#endif
+}
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)
{
- AsciiSinkObject sink = (AsciiSinkObject) w;
- Widget source = XawTextGetSource(XtParent(w));
-
- XawTextPosition lastPos, index, whiteSpacePosition;
- int lastWidth, whiteSpaceWidth;
+#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);
- lastPos = GETLASTPOS;
+ 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;
- XawTextSourceRead(source, fromPos, &blk, BUFSIZ);
- *resWidth = 0;
- whiteSpaceSeen = FALSE;
+ *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 (index = fromPos; *resWidth <= width && index < lastPos; index++) {
- lastWidth = *resWidth;
- if (index - blk.firstPos >= blk.length)
- XawTextSourceRead(source, index, &blk, BUFSIZ);
- c = blk.ptr[index - blk.firstPos];
- *resWidth += CharWidth(w, fromx + *resWidth, c);
-
- if ((c == XawSP || c == 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 = blk.ptr[i];
+ lastWidth = rWidth;
+ rWidth += CharWidth(sink, font, fromx + rWidth, c);
+
if (c == XawLF) {
- index++;
+ idx++;
break;
}
+ else if ((c == XawSP || c == 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 != XawLF) index = lastPos + 1;
- *resPos = index;
- *resHeight = sink->ascii_sink.font->ascent +sink->ascii_sink.font->descent;
+
+ 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 (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)
-AsciiSinkObject sink;
+GetGC(AsciiSinkObject sink)
{
- XtGCMask valuemask = (GCFont |
- GCGraphicsExposures | GCForeground | GCBackground );
+ 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 = (Bool) FALSE;
-
+ values.graphics_exposures = False;
+
values.foreground = sink->text_sink.foreground;
values.background = sink->text_sink.background;
- sink->ascii_sink.normgc = XtGetGC((Widget)sink, valuemask, &values);
-
+ 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;
- sink->ascii_sink.invgc = XtGetGC((Widget)sink, valuemask, &values);
-
- 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;
-
- sink->ascii_sink.xorgc = XtGetGC((Widget)sink, valuemask, &values);
-}
+#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);
-/***** Public routines *****/
+ XawAsciiSinkResize((Widget)sink);
+}
-/* Function Name: Initialize
- * Description: Initializes the TextSink Object.
- * Arguments: request, new - the requested and new values for the object
- * instance.
- * Returns: none.
+/* Function:
+ * XawAsciiSinkInitialize
*
+ * Parameters:
+ * request - the requested and new values for the object instance
+ * cnew - ""
+ *
+ * Description:
+ * Initializes the TextSink Object.
*/
-
-/* ARGSUSED */
+/*ARGSUSED*/
static void
-Initialize(request, new, args, num_args)
-Widget request, new;
-ArgList args;
-Cardinal *num_args;
+XawAsciiSinkInitialize(Widget request, Widget cnew,
+ ArgList args, Cardinal *num_args)
{
- AsciiSinkObject sink = (AsciiSinkObject) new;
+ AsciiSinkObject sink = (AsciiSinkObject)cnew;
GetGC(sink);
-
- sink->ascii_sink.insertCursorOn= CreateInsertCursor(XtScreenOfObject(new));
+
+ sink->ascii_sink.cursor_position = 0;
sink->ascii_sink.laststate = XawisOff;
sink->ascii_sink.cursor_x = sink->ascii_sink.cursor_y = 0;
}
-/* Function Name: Destroy
- * Description: This function cleans up when the object is
- * destroyed.
- * Arguments: w - the AsciiSink Object.
- * Returns: none.
+/*
+ * Function:
+ * XawAsciiSinkDestroy
+ *
+ * Parameters:
+ * w - AsciiSink Object
+ *
+ * Description:
+ * This function cleans up when the object is destroyed.
*/
-
static void
-Destroy(w)
-Widget w;
+XawAsciiSinkDestroy(Widget w)
{
- AsciiSinkObject sink = (AsciiSinkObject) w;
+ AsciiSinkObject sink = (AsciiSinkObject)w;
+
+ XtReleaseGC(w, sink->ascii_sink.normgc);
+ XtReleaseGC(w, sink->ascii_sink.invgc);
+ XtReleaseGC(w, sink->ascii_sink.xorgc);
- XtReleaseGC(w, sink->ascii_sink.normgc);
- XtReleaseGC(w, sink->ascii_sink.invgc);
- XtReleaseGC(w, sink->ascii_sink.xorgc);
- XFreePixmap(XtDisplayOfObject(w), sink->ascii_sink.insertCursorOn);
+ sink->ascii_sink.normgc =
+ sink->ascii_sink.invgc =
+ sink->ascii_sink.xorgc = NULL;
}
-/* Function Name: SetValues
- * Description: Sets the values for the AsciiSink
- * Arguments: current - current state of the object.
- * request - what was requested.
- * new - what the object will become.
- * Returns: True if redisplay is needed.
- */
+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);
+ }
+}
-/* ARGSUSED */
+/*
+ * 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
-SetValues(current, request, new, args, num_args)
-Widget current, request, new;
-ArgList args;
-Cardinal *num_args;
+XawAsciiSinkSetValues(Widget current, Widget request, Widget cnew,
+ ArgList args, Cardinal *num_args)
{
- AsciiSinkObject w = (AsciiSinkObject) new;
- AsciiSinkObject old_w = (AsciiSinkObject) current;
+ 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) {
- XtReleaseGC((Widget)w, w->ascii_sink.normgc);
- XtReleaseGC((Widget)w, w->ascii_sink.invgc);
- XtReleaseGC((Widget)w, w->ascii_sink.xorgc);
+ || 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);
- ((TextWidget)XtParent(new))->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(new))->text.redisplay_needed = True;
- }
-
- return False;
+#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 Name: MaxLines
- * Description: Finds the Maximum number of lines that will fit in
- * a given height.
- * Arguments: w - the AsciiSink Object.
- * height - height to fit lines into.
- * Returns: the number of lines that will fit.
+/*
+ * 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 */
+/*ARGSUSED*/
static int
-MaxLines(w, height)
-Widget w;
-Dimension height;
+MaxLines(Widget w, unsigned int height)
{
- AsciiSinkObject sink = (AsciiSinkObject) w;
- int font_height;
+ AsciiSinkObject sink = (AsciiSinkObject)w;
+ int font_height;
+
+ font_height = sink->ascii_sink.font->ascent + sink->ascii_sink.font->descent + 1;
- font_height = sink->ascii_sink.font->ascent + sink->ascii_sink.font->descent;
- return( ((int) height) / font_height );
+ return ((int)height / font_height);
}
-/* Function Name: MaxHeight
- * Description: Finds the Minium height that will contain a given number
- * lines.
- * Arguments: w - the AsciiSink Object.
- * lines - the number of lines.
- * Returns: the 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
*/
-
-/* ARGSUSED */
static int
-MaxHeight(w, lines)
-Widget w;
-int lines;
+MaxHeight(Widget w, int lines)
{
- AsciiSinkObject sink = (AsciiSinkObject) w;
+ AsciiSinkObject sink = (AsciiSinkObject)w;
- return(lines * (sink->ascii_sink.font->ascent +
- sink->ascii_sink.font->descent));
+ return (lines * (sink->ascii_sink.font->ascent +
+ sink->ascii_sink.font->descent + 1));
}
-/* Function Name: SetTabs
- * Description: Sets the Tab stops.
- * Arguments: w - the AsciiSink Object.
- * tab_count - the number of tabs in the list.
- * tabs - the text positions of the tabs.
- * Returns: none
+/*
+ * 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(w, tab_count, tabs)
-Widget w;
-int tab_count;
-short *tabs;
+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;
+ 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.
- */
+ /*
+ * 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));
+ }
- 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];
+ }
- 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;
+ 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);
- }
+ {
+ TextWidget ctx = (TextWidget)XtParent(w);
+ ctx->text.redisplay_needed = True;
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, True);
+ }
#endif
}