Bug Summary

File:AsciiSink.c
Location:line 1498, column 18
Description:Value stored to 'font' during its initialization is never read

Annotated Source Code

1/***********************************************************
2
3Copyright 1987, 1988, 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25
26Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28 All Rights Reserved
29
30Permission to use, copy, modify, and distribute this software and its
31documentation for any purpose and without fee is hereby granted,
32provided that the above copyright notice appear in all copies and that
33both that copyright notice and this permission notice appear in
34supporting documentation, and that the name of Digital not be
35used in advertising or publicity pertaining to distribution of the
36software without specific, written prior permission.
37
38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44SOFTWARE.
45
46******************************************************************/
47
48#ifdef HAVE_CONFIG_H1
49#include <config.h>
50#endif
51#include <stdio.h>
52#include <stdlib.h>
53#include <X11/IntrinsicP.h>
54#include <X11/StringDefs.h>
55#include <X11/Xatom.h>
56#include <X11/Xaw/XawInit.h>
57#include <X11/Xaw/AsciiSinkP.h>
58#include <X11/Xaw/AsciiSrcP.h>
59#include <X11/Xaw/TextP.h>
60#include "Private.h"
61
62#ifdef GETLASTPOSXawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, 1)
63#undef GETLASTPOSXawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, 1) /* We will use our own GETLASTPOS */
64#endif
65
66#define GETLASTPOSXawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, 1) \
67 XawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, True1)
68
69/*
70 * Class Methods
71 */
72static void XawAsciiSinkClassPartInitialize(WidgetClass);
73static void XawAsciiSinkInitialize(Widget, Widget, ArgList, Cardinal*);
74static void XawAsciiSinkDestroy(Widget);
75static void XawAsciiSinkResize(Widget);
76static Boolean XawAsciiSinkSetValues(Widget, Widget, Widget,
77 ArgList, Cardinal*);
78static int MaxLines(Widget, unsigned int);
79static int MaxHeight(Widget, int);
80static void SetTabs(Widget, int, short*);
81static void DisplayText(Widget, int, int,
82 XawTextPosition, XawTextPosition, Boolint);
83static void InsertCursor(Widget, int, int, XawTextInsertState);
84static void FindPosition(Widget, XawTextPosition, int, int, Boolint,
85 XawTextPosition*, int*, int*);
86static void FindDistance(Widget, XawTextPosition, int, XawTextPosition, int*,
87 XawTextPosition*, int*);
88static void Resolve(Widget, XawTextPosition, int, int, XawTextPosition*);
89static void GetCursorBounds(Widget, XRectangle*);
90#ifndef OLDXAW
91static void AsciiPreparePaint(Widget, int, int,
92 XawTextPosition, XawTextPosition, Boolint);
93static void AsciiDoPaint(Widget);
94#endif
95
96/*
97 * Prototypes
98 */
99static void GetGC(AsciiSinkObject);
100static int CharWidth(AsciiSinkObject, XFontStruct*, int, unsigned int);
101static unsigned int PaintText(Widget w, GC gc, int x, int y,
102 char *buf, int len, Boolint);
103
104/*
105 * Defined in TextSink.c
106 */
107void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned);
108
109/*
110 * Initialization
111 */
112#define offset(field) XtOffsetOf(AsciiSinkRec, ascii_sink.field)__builtin_offsetof(AsciiSinkRec, ascii_sink.field)
113static XtResource resources[] = {
114 {
115 XtNfont((char*)&XtStrings[199]),
116 XtCFont((char*)&XtStrings[1017]),
117 XtRFontStruct((char*)&XtStrings[1666]),
118 sizeof(XFontStruct*),
119 offset(font),
120 XtRString((char*)&XtStrings[1797]),
121 XtDefaultFont"XtDefaultFont"
122 },
123 {
124 XtNecho"echo",
125 XtCOutput"Output",
126 XtRBoolean((char*)&XtStrings[1561]),
127 sizeof(Boolean),
128 offset(echo),
129 XtRImmediate((char*)&XtStrings[1695]),
130 (XtPointer)True1
131 },
132 {
133 XtNdisplayNonprinting"displayNonprinting",
134 XtCOutput"Output",
135 XtRBoolean((char*)&XtStrings[1561]),
136 sizeof(Boolean),
137 offset(display_nonprinting),
138 XtRImmediate((char*)&XtStrings[1695]),
139 (XtPointer)
140 True1
141 },
142};
143#undef offset
144
145#define Superclass(&textSinkClassRec) (&textSinkClassRec)
146AsciiSinkClassRec asciiSinkClassRec = {
147 /* object */
148 {
149 (WidgetClass)Superclass(&textSinkClassRec), /* superclass */
150 "AsciiSink", /* class_name */
151 sizeof(AsciiSinkRec), /* widget_size */
152 XawInitializeWidgetSet, /* class_initialize */
153 XawAsciiSinkClassPartInitialize, /* class_part_initialize */
154 False0, /* class_inited */
155 XawAsciiSinkInitialize, /* initialize */
156 NULL((void*)0), /* initialize_hook */
157 NULL((void*)0), /* obj1 */
158 NULL((void*)0), /* obj2 */
159 0, /* obj3 */
160 resources, /* resources */
161 XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), /* num_resources */
162 NULLQUARK((XrmQuark) 0), /* xrm_class */
163 False0, /* obj4 */
164 False0, /* obj5 */
165 False0, /* obj6 */
166 False0, /* obj7 */
167 XawAsciiSinkDestroy, /* destroy */
168 (XtProc)XawAsciiSinkResize, /* obj8 */
169 NULL((void*)0), /* obj9 */
170 XawAsciiSinkSetValues, /* set_values */
171 NULL((void*)0), /* set_values_hook */
172 NULL((void*)0), /* obj10 */
173 NULL((void*)0), /* get_values_hook */
174 NULL((void*)0), /* obj11 */
175 XtVersion(11 * 1000 + 6), /* version */
176 NULL((void*)0), /* callback_private */
177 NULL((void*)0), /* obj12 */
178 NULL((void*)0), /* obj13 */
179 NULL((void*)0), /* obj14 */
180 NULL((void*)0), /* extension */
181 },
182 /* text_sink */
183 {
184 DisplayText, /* DisplayText */
185 InsertCursor, /* InsertCursor */
186 XtInheritClearToBackground((_XawSinkClearToBackgroundProc)_XtInherit), /* ClearToBackground */
187 FindPosition, /* FindPosition */
188 FindDistance, /* FindDistance */
189 Resolve, /* Resolve */
190 MaxLines, /* MaxLines */
191 MaxHeight, /* MaxHeight */
192 SetTabs, /* SetTabs */
193 GetCursorBounds, /* GetCursorBounds */
194#ifndef OLDXAW
195 NULL((void*)0) /* extension */
196#endif
197 },
198 /* ascii_sink */
199 {
200 NULL((void*)0), /* extension */
201 }
202};
203
204WidgetClass asciiSinkObjectClass = (WidgetClass)&asciiSinkClassRec;
205
206/*
207 * Implementation
208 */
209static void
210XawAsciiSinkClassPartInitialize(WidgetClass wc)
211{
212#ifndef OLDXAW
213 AsciiSinkObjectClass cclass = (AsciiSinkObjectClass)wc;
214 XrmQuark record_type = XrmPermStringToQuark("TextSink");
215 TextSinkExt ext = cclass->text_sink_class.extension;
216
217 while (ext) {
218 if (ext->record_type == record_type &&
219 ext->version == 1) {
220 ext->PreparePaint = AsciiPreparePaint;
221 ext->DoPaint = AsciiDoPaint;
222 break;
223 }
224 ext = (TextSinkExt)ext->next_extension;
225 }
226 if (ext == NULL((void*)0))
227 XtError("TextSinkClass: cannot resolve extension.\n");
228#endif
229}
230
231static int
232CharWidth(AsciiSinkObject sink, XFontStruct *font, int x, unsigned int c)
233{
234 int width = 0;
235
236 if (c == XawLF0x0a)
237 return (0);
238
239 if (c == XawTAB0x09) {
240 int i;
241 Position *tab;
242
243 width = x;
244 /* Adjust for Left Margin */
245 x -= ((TextWidget)XtParent((Widget)sink)(((Widget)sink)->core.parent))->text.left_margin;
246
247 i = 0;
248 tab = sink->text_sink.tabs;
249 /*CONSTCOND*/
250 while (1) {
251 if (x >= 0 && x < *tab)
252 return (*tab - x);
253 /* Start again */
254 if (++i >= sink->text_sink.tab_count) {
255 x -= *tab;
256 i = 0;
257 tab = sink->text_sink.tabs;
258 if (width == x)
259 return (0);
260 }
261 else
262 ++tab;
263 }
264 /*NOTREACHED*/
265 }
266
267 if ((c & 0177) < XawSP0x20 || c == 0177) {
268 if (sink->ascii_sink.display_nonprinting) {
269 if (c > 0177) {
270 width = CharWidth(sink, font, x, '\\');
271 width += CharWidth(sink, font, x, ((c >> 6) & 7) + '0');
272 width += CharWidth(sink, font, x, ((c >> 3) & 7) + '0');
273 c = (c & 7) + '0';
274 }
275 else {
276 width = CharWidth(sink, font, x, '^');
277 if ((c |= 0100) == 0177)
278 c = '?';
279 }
280 }
281 else
282 c = XawSP0x20;
283 }
284
285 if (font->per_char
286 && (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
287 width += font->per_char[c - font->min_char_or_byte2].width;
288 else
289 width += font->min_bounds.width;
290
291 return (width);
292}
293
294#ifndef OLDXAW
295static int
296GetTextWidth(TextWidget ctx, int current_width, XFontStruct *font,
297 XawTextPosition from, int length)
298{
299 int i, width = 0;
300 XawTextBlock block;
301 XawTextPosition pos = from;
302
303 while (length > 0) {
304 pos = XawTextSourceRead(ctx->text.source, from, &block, length);
305 length -= pos - from;
306 from = pos;
307 for (i = 0; i < block.length; i++)
308 width += CharWidth((AsciiSinkObject)ctx->text.sink, font,
309 current_width + width,
310 (unsigned char)block.ptr[i]);
311 }
312
313 return (width);
314}
315
316static
317void CalculateBearing(TextWidget ctx, XawTextPosition position, int x, int y,
318 int ascent, int descent, Boolint highlight, Boolint right)
319{
320/*
321 * Sample case:
322 *
323 * lbearing| width |rbearing
324 * | |
325 * | ####
326 * | ### |
327 * | #### |
328 * | #### |
329 * | ########## |
330 * | #### |
331 * | #### |
332 * | #### |
333 * | #### |
334 * |### |
335 * #### |
336 * | |
337 *
338 */
339 AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink;
340 XawTextAnchor *anchor;
341 XawTextEntity *entity;
342 XawTextProperty *property;
343 XawTextPaintStruct *paint;
344 XawTextBlock block;
345 XFontStruct *font;
346
347 property = NULL((void*)0);
348 if (XawTextSourceAnchorAndEntity(ctx->text.source, position,
349 &anchor, &entity) &&
350 (property = XawTextSinkGetProperty((Widget)sink,
351 entity->property)) != NULL((void*)0) &&
352 (property->mask & XAW_TPROP_FONT(1<<0)))
353 font = property->font;
354 else
355 font = sink->ascii_sink.font;
356 if (right) {
357 if (font->max_bounds.rbearing > 0) {
358 int rbearing = font->max_bounds.rbearing - font->max_bounds.width;
359 unsigned char c;
360
361 (void)XawTextSourceRead(ctx->text.source, position, &block, 1);
362 c = *(unsigned char*)block.ptr;
363 if (c == '\t' || c == '\n')
364 c = ' ';
365 else if ((c & 0177) < XawSP0x20 || c == 0177) {
366 if (sink->ascii_sink.display_nonprinting)
367 c = c > 0177 ? (c & 7) + '0' : c + '@';
368 else
369 c = ' ';
370 }
371 if (font->per_char &&
372 (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
373 rbearing = font->per_char[c - font->min_char_or_byte2].rbearing -
374 font->per_char[c - font->min_char_or_byte2].width;
375 if (rbearing > 0) {
376 paint = XtNew(XawTextPaintStruct)((XawTextPaintStruct *) XtMalloc((unsigned) sizeof(XawTextPaintStruct
)))
;
377 paint->next = sink->text_sink.paint->bearings;
378 sink->text_sink.paint->bearings = paint;
379 paint->x = x - (paint->width = CharWidth(sink, font, 0, c));
380 paint->y = y + ascent;
381 paint->property = property;
382 paint->max_ascent = ascent;
383 paint->max_descent = descent;
384 paint->backtabs = NULL((void*)0);
385 paint->highlight = highlight;
386 paint->length = 1;
387 paint->text = XtMalloc(1);
388 paint->text[0] = c;
389 }
390 }
391 }
392 else {
393 if (font->min_bounds.lbearing < 0) {
394 int lbearing = font->min_bounds.lbearing;
395 unsigned char c;
396
397 (void)XawTextSourceRead(ctx->text.source, position, &block, 1);
398 c = *(unsigned char*)block.ptr;
399 if (c == '\t' || c == '\n')
400 c = ' ';
401 else if ((c & 0177) < XawSP0x20 || c == 0177) {
402 if (sink->ascii_sink.display_nonprinting)
403 c = c > 0177 ? '\\' : c + '^';
404 else
405 c = ' ';
406 }
407 if (font->per_char &&
408 (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
409 lbearing = font->per_char[c - font->min_char_or_byte2].lbearing;
410 if (lbearing < 0) {
411 paint = XtNew(XawTextPaintStruct)((XawTextPaintStruct *) XtMalloc((unsigned) sizeof(XawTextPaintStruct
)))
;
412 paint->next = sink->text_sink.paint->bearings;
413 sink->text_sink.paint->bearings = paint;
414 paint->x = x;
415 paint->width = -CharWidth(sink, font, 0, c);
416 paint->y = y + ascent;
417 paint->property = property;
418 paint->max_ascent = ascent;
419 paint->max_descent = descent;
420 paint->backtabs = NULL((void*)0);
421 paint->highlight = highlight;
422 paint->length = 1;
423 paint->text = XtMalloc(1);
424 paint->text[0] = c;
425 }
426 }
427 }
428}
429
430static void
431AsciiPreparePaint(Widget w, int y, int line,
432 XawTextPosition from, XawTextPosition to, Boolint highlight)
433{
434 static XmuSegment segment;
435 static XmuScanline next;
436 static XmuScanline scanline = {0, &segment, &next};
437 static XmuArea area = {&scanline};
438
439 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
440 AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink;
441 XawTextPosition left, right, pos, pos2, tmp, length;
442 XawTextAnchor *anchor;
443 XawTextEntity *entity;
444 XawTextProperty *property;
445 int i, ascent = 0, descent = 0, xl, xr, x = ctx->text.left_margin, bufsiz;
446 XawTextBlock block;
447 XFontStruct *font;
448 XawTextPaintStruct *paint;
449
450 if (!sink->ascii_sink.echo)
451 return;
452
453 /* pass 1: calculate ascent/descent values and x coordinate */
454 /* XXX the MAX ascent/descent value should be in the line table XXX */
455 /* XXX the x coordinate can be a parameter, but since it is required
456 to calculate the ascent/descent, do it here to avoid an extra
457 search in the entities */
458 pos = tmp = left = ctx->text.lt.info[line].position;
459 right = ctx->text.lt.info[line + 1].position;
460 right = XawMin(right, ctx->text.lastPos + 1)((right) < (ctx->text.lastPos + 1) ? (right) : (ctx->
text.lastPos + 1))
;
461 while (pos < right) {
462 if (XawTextSourceAnchorAndEntity(ctx->text.source, pos,
463 &anchor, &entity)) {
464 if ((property = XawTextSinkGetProperty((Widget)sink,
465 entity->property)) != NULL((void*)0) &&
466 (property->mask & XAW_TPROP_FONT(1<<0)))
467 font = property->font;
468 else
469 font = sink->ascii_sink.font;
470 tmp = pos;
471 pos = anchor->position + entity->offset + entity->length;
472 if ((length = XawMin(from, pos)((from) < (pos) ? (from) : (pos)) - tmp) > 0)
473 x += GetTextWidth(ctx, x, font, tmp, length);
474 ascent = XawMax(font->ascent, ascent)((font->ascent) > (ascent) ? (font->ascent) : (ascent
))
;
475 descent = XawMax(font->descent, descent)((font->descent) > (descent) ? (font->descent) : (descent
))
;
476 }
477 else if (anchor) {
478 ascent = XawMax(sink->ascii_sink.font->ascent, ascent)((sink->ascii_sink.font->ascent) > (ascent) ? (sink->
ascii_sink.font->ascent) : (ascent))
;
479 descent = XawMax(sink->ascii_sink.font->descent, descent)((sink->ascii_sink.font->descent) > (descent) ? (sink
->ascii_sink.font->descent) : (descent))
;
480 while (entity && pos < right) {
481 tmp = pos;
482 if ((pos = anchor->position + entity->offset) < tmp)
483 pos = tmp;
484 else {
485 if ((length = XawMin(from, pos)((from) < (pos) ? (from) : (pos)) - tmp) > 0) {
486 x += GetTextWidth(ctx, x, sink->ascii_sink.font, tmp,
487 length);
488 tmp += length;
489 }
490 if (pos < right) {
491 pos += entity->length;
492 if ((property = XawTextSinkGetProperty((Widget)sink,
493 entity->property)) != NULL((void*)0) &&
494 (property->mask & XAW_TPROP_FONT(1<<0)))
495 font = property->font;
496 else
497 font = sink->ascii_sink.font;
498 if ((length = XawMin(from, pos)((from) < (pos) ? (from) : (pos)) - tmp) > 0)
499 x += GetTextWidth(ctx, x, font, tmp, length);
500 ascent = XawMax(font->ascent, ascent)((font->ascent) > (ascent) ? (font->ascent) : (ascent
))
;
501 descent = XawMax(font->descent, descent)((font->descent) > (descent) ? (font->descent) : (descent
))
;
502 }
503 }
504 entity = entity->next;
505 }
506
507 if (anchor->entities == NULL((void*)0)) {
508 tmp = XawMin(pos, from)((pos) < (from) ? (pos) : (from));
509 if ((length = from - tmp) > 0)
510 x += GetTextWidth(ctx, x, sink->ascii_sink.font, tmp, length);
511 break;
512 }
513 }
514 else {
515 tmp = XawMin(pos, from)((pos) < (from) ? (pos) : (from));
516 if ((length = from - tmp) > 0)
517 x += GetTextWidth(ctx, x, sink->ascii_sink.font, tmp, length);
518 ascent = XawMax(sink->ascii_sink.font->ascent, ascent)((sink->ascii_sink.font->ascent) > (ascent) ? (sink->
ascii_sink.font->ascent) : (ascent))
;
519 descent = XawMax(sink->ascii_sink.font->descent, descent)((sink->ascii_sink.font->descent) > (descent) ? (sink
->ascii_sink.font->descent) : (descent))
;
520 break;
521 }
522 }
523 if (!ascent)
524 ascent = sink->ascii_sink.font->ascent;
525 if (!descent)
526 descent = sink->ascii_sink.font->descent;
527
528 xl = x;
529
530 /* pass 2: feed the XawTextPaintStruct lists */
531 pos = from;
532 while (pos < to) {
533 paint = XtNew(XawTextPaintStruct)((XawTextPaintStruct *) XtMalloc((unsigned) sizeof(XawTextPaintStruct
)))
;
534 paint->next = sink->text_sink.paint->paint;
535 sink->text_sink.paint->paint = paint;
536 paint->x = x;
537 paint->y = y + ascent;
538 paint->property = NULL((void*)0);
539 paint->max_ascent = ascent;
540 paint->max_descent = descent;
541 paint->backtabs = NULL((void*)0);
542 paint->highlight = highlight;
543
544 tmp = pos;
545 if (XawTextSourceAnchorAndEntity(ctx->text.source, pos,
546 &anchor, &entity)) {
547 pos = anchor->position + entity->offset + entity->length;
548 if ((paint->property = XawTextSinkGetProperty((Widget)sink,
549 entity->property)) != NULL((void*)0) &&
550 (paint->property->mask & XAW_TPROP_FONT(1<<0)))
551 font = paint->property->font;
552 else
553 font = sink->ascii_sink.font;
554 }
555 else {
556 if (anchor) {
557 while (entity && anchor->position + entity->offset < pos)
558 entity = entity->next;
559 if (entity)
560 pos = anchor->position + entity->offset;
561 else
562 pos = to;
563 }
564 else
565 pos = to;
566 font = sink->ascii_sink.font;
567 }
568 pos = XawMin(pos, to)((pos) < (to) ? (pos) : (to));
569 length = pos - tmp;
570
571 paint->text = XtMalloc(bufsiz = pos - tmp + 4);
572 paint->length = 0;
573 segment.x1 = x;
574
575 pos2 = tmp;
576 while (length > 0) {
577 pos2 = XawTextSourceRead(ctx->text.source, tmp, &block, length);
578 length = pos - pos2;
579 tmp = pos2;
580 for (i = 0; i < block.length; i++) {
581 unsigned char c = (unsigned char)block.ptr[i];
582
583 if (paint->length + 4 > bufsiz)
584 paint->text = XtRealloc(paint->text, bufsiz += 32);
585 paint->text[paint->length] = c;
586 if (c == '\n') {
587 x += CharWidth(sink, font, 0, ' ');
588 continue;
589 }
590 if (c == '\t') {
591 x += XTextWidth(font, paint->text, paint->length);
592 segment.x2 = x + CharWidth(sink, font, x, '\t');
593
594 if (XmuValidSegment(&segment)((&segment)->x1 < (&segment)->x2)) {
595 if (!highlight && (paint->property &&
596 (paint->property->mask & XAW_TPROP_BACKGROUND(1<<3)))) {
597 if (ascent > font->ascent) {
598 scanline.y = y;
599 next.y = y + ascent - font->ascent;
600 XmuAreaOr(sink->text_sink.paint->clip, &area)XmuAreaOrXor((sink->text_sink.paint->clip), (&area)
, 1)
;
601 }
602 if (descent >= font->descent) {
603 scanline.y = y + ascent + font->descent;
604 next.y = scanline.y + descent - font->descent + 1;
605 XmuAreaOr(sink->text_sink.paint->clip, &area)XmuAreaOrXor((sink->text_sink.paint->clip), (&area)
, 1)
;
606 }
607 if (paint->backtabs == NULL((void*)0))
608 paint->backtabs = XmuCreateArea()XmuNewArea(0, 0, 0, 0);
609 scanline.y = y + ascent - font->ascent;
610 next.y = y + ascent + font->descent;
611 XmuAreaOr(paint->backtabs, &area)XmuAreaOrXor((paint->backtabs), (&area), 1);
612 }
613 else {
614 scanline.y = y;
615 next.y = ctx->text.lt.info[line + 1].y;
616 if (highlight) {
617 if (!sink->text_sink.paint->hightabs)
618 sink->text_sink.paint->hightabs =
619 XmuCreateArea()XmuNewArea(0, 0, 0, 0);
620 XmuAreaOr(sink->text_sink.paint->hightabs, &area)XmuAreaOrXor((sink->text_sink.paint->hightabs), (&area
), 1)
;
621 }
622 else
623 XmuAreaOr(sink->text_sink.paint->clip, &area)XmuAreaOrXor((sink->text_sink.paint->clip), (&area)
, 1)
;
624 }
625 }
626
627 paint->width = segment.x2 - segment.x1;
628 x = segment.x1 = segment.x2;
629
630 if (paint->length == 0) {
631 paint->x = x;
632 continue;
633 }
634 paint->text = XtRealloc(paint->text, paint->length);
635 property = paint->property;
636 paint = XtNew(XawTextPaintStruct)((XawTextPaintStruct *) XtMalloc((unsigned) sizeof(XawTextPaintStruct
)))
;
637 paint->next = sink->text_sink.paint->paint;
638 sink->text_sink.paint->paint = paint;
639 paint->x = x;
640 paint->y = y + ascent;
641 paint->property = property;
642 paint->max_ascent = ascent;
643 paint->max_descent = descent;
644 paint->backtabs = NULL((void*)0);
645 paint->highlight = highlight;
646 paint->text = XtMalloc(bufsiz = pos - tmp - length +
647 block.length - i + 4);
648 paint->length = 0;
649 continue;
650 }
651 if ((c & 0177) < XawSP0x20 || c == 0177) {
652 if (sink->ascii_sink.display_nonprinting) {
653 if (c > 0177) {
654 paint->text[paint->length++] = '\\';
655 paint->text[paint->length++] = ((c >> 6) & 7) + '0';
656 paint->text[paint->length++] = ((c >> 3) & 7) + '0';
657 paint->text[paint->length] = (c & 7) + '0';
658 }
659 else {
660 c |= 0100;
661 paint->text[paint->length++] = '^';
662 paint->text[paint->length] = c == 0177 ? '?' : c;
663 }
664 }
665 else
666 paint->text[paint->length] = ' ';
667 }
668 paint->length++;
669 }
670 }
671
672 x += XTextWidth(font, paint->text, paint->length);
673 segment.x2 = x;
674 if (XmuValidSegment(&segment)((&segment)->x1 < (&segment)->x2)) {
675 /* erase only what really is needed */
676 /*if (!highlight || (paint->property &&
677 (paint->property->mask & XAW_TPROP_BACKGROUND))) {
678 if (ascent > font->ascent) {
679 scanline.y = y;
680 next.y = y + ascent - font->ascent;
681 XmuAreaOr(sink->text_sink.paint->clip, &area);
682 }
683 if (descent > font->descent) {
684 scanline.y = y + ascent + font->descent;
685 next.y = scanline.y + descent - font->descent;
686 XmuAreaOr(sink->text_sink.paint->clip, &area);
687 }
688 }
689 else*/ {
690 scanline.y = y;
691 next.y = ctx->text.lt.info[line + 1].y;
692 XmuAreaOr(sink->text_sink.paint->clip, &area)XmuAreaOrXor((sink->text_sink.paint->clip), (&area)
, 1)
;
693 }
694 }
695
696 paint->width = x - segment.x1;
697 }
698
699 xr = x;
700
701 /* pass 3: bearing clipping */
702 if (left < from) {
703 CalculateBearing(ctx, from - 1, xl, y, ascent, descent, highlight, True1);
704 if (ctx->text.s.left < ctx->text.s.right) {
705 if (ctx->text.s.right == from)
706 CalculateBearing(ctx, from, xl, y, ascent, descent, True1, False0);
707 else if (ctx->text.s.left == from)
708 CalculateBearing(ctx, from, xl, y, ascent, descent, False0, False0);
709 }
710 }
711 right = XawMin(right, ctx->text.lastPos)((right) < (ctx->text.lastPos) ? (right) : (ctx->text
.lastPos))
;
712 if (right >= to && to > from) {
713 if (to < right)
714 CalculateBearing(ctx, to, xr, y, ascent, descent, highlight, False0);
715 if (ctx->text.s.left < ctx->text.s.right) {
716 if (ctx->text.s.right == to)
717 CalculateBearing(ctx, to - 1, xr, y, ascent, descent, False0, True1);
718 else if (ctx->text.s.left == to)
719 CalculateBearing(ctx, to - 1, xr, y, ascent, descent, True1, True1);
720 }
721 }
722}
723
724static int
725qcmp_paint_struct(_Xconstconst void *left, _Xconstconst void *right)
726{
727 return ((*(XawTextPaintStruct**)left)->property -
728 (*(XawTextPaintStruct**)right)->property);
729}
730
731static void
732AsciiDoPaint(Widget w)
733{
734 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
735 AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink;
736 XmuScanline *scan;
737 XmuSegment *seg;
738 XawTextPaintList *list = sink->text_sink.paint;
739#if 0
740 XawTextPaintStruct *base, *head;
741#endif
742 XawTextPaintStruct *paint = list->paint;
743 XawTextProperty *property;
744 XFontStruct *font = NULL((void*)0);
745 XRectangle *rects;
746 int n_rects, i_rects;
747 GC gc;
748 Boolint highlight;
749 XRectangle rect;
750 int width, height, line_width = -1;
751 XGCValues values;
752
753 /* pass 1: clear clipping areas */
754 /* XXX Don't use XDrawImageString because the font may be italic, and
755 will get incorrectly drawn. Probably, it could be a good idea to
756 check if this is the case, and do special processing. But this
757 will need to be checked if required. */
758 for (scan = list->clip->scanline; scan && scan->next; scan = scan->next)
759 for (seg = scan->segment; seg; seg = seg->next)
760 _XawTextSinkClearToBackground(ctx->text.sink,
761 seg->x1, scan->y,
762 seg->x2 - seg->x1,
763 scan->next->y - scan->y);
764
765 /* pass 2: optimize drawing list to avoid too much GC change requests */
766 /* XXX this assumes there will not exist entities drawn over other
767 entities. */
768#if 0
769 while (paint) {
770 base = paint;
771 head = paint->next;
772 while (head) {
773 if (head->property == paint->property) {
774 base->next = head->next;
775 head->next = paint->next;
776 paint->next = head;
777 paint = head;
778 }
779 base = head;
780 head = head->next;
781 }
782 paint = paint->next;
783 }
784#endif
785 if (paint && paint->next) {
786 XawTextPaintStruct **paints;
787 int i = 0, n_paints = 0;
788
789 while (paint) {
790 paint = paint->next;
791 ++n_paints;
792 }
793 paints = (XawTextPaintStruct**)
794 XtMalloc(n_paints * sizeof(XawTextPaintStruct));
795 paint = list->paint;
796 while (paint) {
797 paints[i++] = paint;
798 paint = paint->next;
799 }
800 qsort((void*)paints, n_paints, sizeof(XawTextPaintStruct*),
801 qcmp_paint_struct);
802 list->paint = paints[0];
803 for (i = 0; i < n_paints - 1; i++)
804 paints[i]->next = paints[i + 1];
805 paints[i]->next = NULL((void*)0);
806 XtFree((XtPointer)paints);
807 }
808
809 /* pass 3: clip gc */
810 gc = sink->ascii_sink.normgc;
811
812 rect.x = ctx->text.r_margin.left;
813 rect.y = ctx->text.r_margin.top;
814 width = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - RHMargins(ctx)((ctx)->text.r_margin.left + (ctx)->text.r_margin.right
)
;
815 height = (int)XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - RVMargins(ctx)((ctx)->text.r_margin.top + (ctx)->text.r_margin.bottom
)
;
816 rect.width = width;
817 rect.height = height;
818 if (width >= 0 && height >= 0)
819 XSetClipRectangles(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), gc,
820 0, 0, &rect, 1, Unsorted0);
821 else
822 XSetClipMask(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), gc, None0L);
823
824 /* pass 4: draw backgrounds */
825 paint = list->paint;
826 property = NULL((void*)0);
827 rects = NULL((void*)0);
828 i_rects = n_rects = 0;
829 while (paint) {
830 if (paint->property && (paint->property->mask & XAW_TPROP_BACKGROUND(1<<3))) {
831 if (property != paint->property) {
832 if (i_rects)
833 XFillRectangles(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), gc,
834 rects, i_rects);
835 i_rects = 0;
836 property = paint->property;
837 if (property->mask & XAW_TPROP_FONT(1<<0))
838 font = property->font;
839 else
840 font = sink->ascii_sink.font;
841 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, property->background);
842 }
843 if (i_rects <= n_rects)
844 rects = (XRectangle*)
845 XtRealloc((XtPointer)rects, sizeof(XRectangle) *
846 ++n_rects);
847 rects[i_rects].x = paint->x;
848 rects[i_rects].y = paint->y - font->ascent;
849 rects[i_rects].width = paint->width;
850 rects[i_rects++].height = font->ascent + font->descent;
851
852 if (paint->backtabs) {
853 for (scan = paint->backtabs->scanline; scan && scan->next;
854 scan = scan->next)
855 for (seg = scan->segment; seg; seg = seg->next) {
856 if (i_rects <= n_rects)
857 rects = (XRectangle*)
858 XtRealloc((XtPointer)rects, sizeof(XRectangle) *
859 ++n_rects);
860 rects[i_rects].x = seg->x1;
861 rects[i_rects].y = scan->y;
862 rects[i_rects].width = seg->x2 - seg->x1;
863 rects[i_rects++].height = scan->next->y - scan->y;
864 }
865 }
866
867
868 }
869 paint = paint->next;
870 }
871 if (i_rects)
872 XFillRectangles(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), gc, rects, i_rects);
873
874 paint = list->paint;
875 i_rects = 0;
876 while (paint) {
877 if (paint->highlight) {
878 if (i_rects == 0)
879 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, sink->text_sink.cursor_color);
880 if (i_rects <= n_rects)
881 rects = (XRectangle*)
882 XtRealloc((XtPointer)rects, sizeof(XRectangle) *
883 ++n_rects);
884 rects[i_rects].x = paint->x;
885 rects[i_rects].y = paint->y - paint->max_ascent;
886 rects[i_rects].width = paint->width;
887 rects[i_rects++].height = paint->max_ascent + paint->max_descent + 1;
888 }
889 paint = paint->next;
890 }
891 if (list->hightabs) {
892 for (scan = list->hightabs->scanline; scan && scan->next;
893 scan = scan->next)
894 for (seg = scan->segment; seg; seg = seg->next) {
895 if (i_rects == 0)
896 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc,
897 sink->text_sink.cursor_color);
898 if (i_rects <= n_rects)
899 rects = (XRectangle*)
900 XtRealloc((XtPointer)rects, sizeof(XRectangle) *
901 ++n_rects);
902 rects[i_rects].x = seg->x1;
903 rects[i_rects].y = scan->y;
904 rects[i_rects].width = seg->x2 - seg->x1;
905 rects[i_rects++].height = scan->next->y - scan->y;
906 }
907 }
908
909 if (i_rects)
910 XFillRectangles(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), gc, rects, i_rects);
911 if (rects)
912 XtFree((XtPointer)rects);
913
914 /* pass 5: draw text! */
915 paint = list->paint;
916 if (paint && (property = paint->property) == NULL((void*)0)) {
917 font = sink->ascii_sink.font;
918 XSetFont(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, font->fid);
919 if (!paint->highlight)
920 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, sink->text_sink.foreground);
921 }
922 else
923 property = NULL((void*)0);
924 highlight = False0;
925 while (paint) {
926 if (!highlight && paint->highlight)
927 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, sink->text_sink.background);
928 if (highlight || paint->highlight || paint->property != property) {
929 if (!paint->property || !(paint->property->mask & XAW_TPROP_FONT(1<<0)))
930 font = sink->ascii_sink.font;
931 else
932 font = paint->property->font;
933 XSetFont(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, font->fid);
934 if (!paint->highlight) {
935 if (!paint->property ||
936 !(paint->property->mask & XAW_TPROP_FOREGROUND(1<<2)))
937 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc,
938 sink->text_sink.foreground);
939 else
940 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc,
941 paint->property->foreground);
942 }
943 highlight = paint->highlight;
944 property = paint->property;
945 }
946
947 if (paint->x < XtWidth(ctx)(((RectObj)ctx)->rectangle.width) && paint->x + paint->width > 0) {
948 XDrawString(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), gc, paint->x, paint->y,
949 paint->text, paint->length);
950 if (property) {
951 if (property->mask & XAW_TPROP_UNDERLINE(1<<6)) {
952 if (line_width != property->underline_thickness) {
953 values.line_width = line_width =
954 property->underline_thickness;
955 XChangeGC(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, GCLineWidth(1L<<4), &values);
956 }
957
958 XDrawLine(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), gc, paint->x,
959 paint->y + property->underline_position,
960 paint->x + paint->width,
961 paint->y + property->underline_position);
962 }
963 if (property->mask & XAW_TPROP_OVERSTRIKE(1<<7)) {
964 if (line_width != property->underline_thickness) {
965 values.line_width = line_width =
966 property->underline_thickness;
967 XChangeGC(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, GCLineWidth(1L<<4), &values);
968 }
969
970 XDrawLine(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), gc, paint->x,
971 paint->y - (font->ascent>>1) + (font->descent>>1),
972 paint->x + paint->width,
973 paint->y - (font->ascent>>1) + (font->descent>>1));
974 }
975 }
976 }
977
978 paint = paint->next;
979 }
980
981 /* pass 6: bearing clipping */
982 /* dont care on order of drawing or caching of state (by now) */
983 paint = list->bearings;
984 while (paint) {
985 XRectangle rect;
986
987 if (paint->highlight)
988 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, sink->text_sink.background);
989 if (!paint->property || !(paint->property->mask & XAW_TPROP_FONT(1<<0)))
990 font = sink->ascii_sink.font;
991 else
992 font = paint->property->font;
993 XSetFont(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, font->fid);
994 if (!paint->highlight) {
995 if (!paint->property ||
996 !(paint->property->mask & XAW_TPROP_FOREGROUND(1<<2)))
997 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, sink->text_sink.foreground);
998 else
999 XSetForeground(XtDisplay(ctx)(((ctx)->core.screen)->display), gc, paint->property->foreground);
1000 }
1001 if (paint->x < XtWidth(ctx)(((RectObj)ctx)->rectangle.width) && paint->x + paint->width > 0) {
1002 rect.x = paint->x + paint->width;
1003 rect.width = XawAbs(paint->width)((paint->width) < 0 ? -(paint->width) : (paint->width
))
; /* more than enough */
1004 rect.y = paint->y - font->ascent;
1005 rect.height = rect.y + font->ascent + font->descent;
1006 XSetClipRectangles(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), gc,
1007 0, 0, &rect, 1, Unsorted0);
1008 XDrawString(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), gc, paint->x, paint->y,
1009 paint->text, paint->length);
1010 }
1011 paint = paint->next;
1012 }
1013}
1014#endif
1015
1016/*
1017 * Function:
1018 * PaintText
1019 *
1020 * Parameters:
1021 * w - text sink object
1022 * gc - gc to paint text with
1023 * x - location to paint the text
1024 * y - ""
1025 * buf - buffer and length of text to paint.
1026 * len - ""
1027 * clear_bg - clear background before drawing ?
1028 *
1029 * Description:
1030 * Actually paints the text into the window.
1031 *
1032 * Returns:
1033 * the width of the text painted
1034 */
1035static unsigned int
1036PaintText(Widget w, GC gc, int x, int y, char *buf, int len, Boolint clear_bg)
1037{
1038 AsciiSinkObject sink = (AsciiSinkObject)w;
1039 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1040 int width = XTextWidth(sink->ascii_sink.font, buf, len);
1041
1042 if ((x > XtWidth(ctx)(((RectObj)ctx)->rectangle.width)) || width <= -x) /* Don't draw if we can't see it */
1043 return (width);
1044
1045 if (clear_bg) {
1046 _XawTextSinkClearToBackground(w, x, y - sink->ascii_sink.font->ascent,
1047 width, sink->ascii_sink.font->ascent
1048 + sink->ascii_sink.font->descent);
1049 XDrawString(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), gc, x, y, buf, len);
1050 }
1051 else
1052 XDrawImageString(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), gc, x, y, buf, len);
1053
1054 return (width);
1055}
1056
1057static void
1058DisplayText(Widget w, int x, int y,
1059 XawTextPosition pos1, XawTextPosition pos2, Boolint highlight)
1060{
1061 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1062 AsciiSinkObject sink = (AsciiSinkObject)w;
1063 XFontStruct *font = sink->ascii_sink.font;
1064 Widget source = XawTextGetSource(XtParent(w)((w)->core.parent));
1065 unsigned char buf[260];
1066 int j, k;
1067 XawTextBlock blk;
1068 GC gc, invgc, tabgc;
1069 int max_x;
1070 Boolint clear_bg;
1071
1072 if (!sink->ascii_sink.echo || !ctx->text.lt.lines)
1073 return;
1074
1075 max_x = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - ctx->text.r_margin.right;
1076 clear_bg = !highlight && ctx->core.background_pixmap != XtUnspecifiedPixmap((Pixmap)2);
1077
1078 gc = highlight ? sink->ascii_sink.invgc : sink->ascii_sink.normgc;
1079 invgc = highlight ? sink->ascii_sink.normgc : sink->ascii_sink.invgc;
1080
1081 if (highlight && sink->ascii_sink.xorgc)
1082 tabgc = sink->ascii_sink.xorgc;
1083 else
1084 tabgc = invgc;
1085
1086 y += sink->ascii_sink.font->ascent;
1087 for (j = 0; pos1 < pos2;) {
1088 pos1 = XawTextSourceRead(source, pos1, &blk, pos2 - pos1);
1089 for (k = 0; k < blk.length; k++) {
1090 if (j >= sizeof(buf) - 4) { /* buffer full, dump the text */
1091 if ((x += PaintText(w, gc, x, y, (char*)buf, j, clear_bg))
1092 >= max_x)
1093 return;
1094 j = 0;
1095 }
1096 buf[j] = blk.ptr[k];
1097 if (buf[j] == XawLF0x0a) /* line feeds ('\n') are not printed */
1098 continue;
1099
1100 else if (buf[j] == '\t') {
1101 int width;
1102
1103 if (j != 0
1104 && (x += PaintText(w, gc, x, y, (char*)buf, j, clear_bg))
1105 >= max_x)
1106 return;
1107
1108 if ((width = CharWidth(sink, font, x, '\t')) > -x) {
1109 if (clear_bg)
1110 _XawTextSinkClearToBackground(w, x, y-font->ascent, width,
1111 font->ascent+font->descent);
1112 else
1113 XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
1114 tabgc, x, y - font->ascent, width,
1115 font->ascent + font->descent);
1116 }
1117
1118 if ((x += width) >= max_x)
1119 return;
1120
1121 j = -1;
1122 }
1123 else if ((buf[j] & 0177) < XawSP0x20 || buf[j] == 0177) {
1124 if (sink->ascii_sink.display_nonprinting) {
1125 unsigned char c = buf[j];
1126
1127 if (c > 0177) {
1128 buf[j++] = '\\';
1129 buf[j++] = ((c >> 6) & 7) + '0';
1130 buf[j++] = ((c >> 3) & 7) + '0';
1131 buf[j] = (c & 7) + '0';
1132 }
1133 else {
1134 c |= 0100;
1135 buf[j++] = '^';
1136 buf[j] = c == 0177 ? '?' : c;
1137 }
1138 }
1139 else
1140 buf[j] = ' ';
1141 }
1142 j++;
1143 }
1144 }
1145
1146 if (j > 0)
1147 (void)PaintText(w, gc, x, y, (char*)buf, j, clear_bg);
1148}
1149
1150/*
1151 * Function:
1152 * GetCursorBounds
1153 *
1154 * Parameters:
1155 * w - text sink object
1156 * rect - X rectangle to return the cursor bounds
1157 *
1158 * Description:
1159 * Returns the size and location of the cursor.
1160 */
1161static void
1162GetCursorBounds(Widget w, XRectangle *rect)
1163{
1164 AsciiSinkObject sink = (AsciiSinkObject)w;
1165 XFontStruct *font = sink->ascii_sink.font;
1166 unsigned char ch;
1167#ifndef OLDXAW
1168 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1169 XawTextBlock block;
1170 XawTextAnchor *anchor;
1171 XawTextEntity *entity;
1172 XawTextProperty *property;
1173
1174 if (XawTextSourceAnchorAndEntity(XawTextGetSource(XtParent(w)((w)->core.parent)),
1175 sink->ascii_sink.cursor_position,
1176 &anchor, &entity)) {
1177 if ((property = XawTextSinkGetProperty((Widget)sink,
1178 entity->property)) != NULL((void*)0) &&
1179 (property->mask & XAW_TPROP_FONT(1<<0)))
1180 font = property->font;
1181 }
1182 (void)XawTextSourceRead(XawTextGetSource((Widget)ctx),
1183 ctx->text.insertPos, &block, 1);
1184 if (!block.length || block.ptr[0] == '\n' || block.ptr[0] == '\t')
1185 ch = ' ';
1186 else if ((*((unsigned char*)block.ptr) & 0177) < XawSP0x20 ||
1187 *(unsigned char*)block.ptr == 0177) {
1188 if (sink->ascii_sink.display_nonprinting)
1189 ch = *((unsigned char*)block.ptr) > 0177 ? '\\' : '^';
1190 else
1191 ch = ' ';
1192 }
1193 else
1194 ch = *(unsigned char*)block.ptr;
1195#else
1196 ch = ' ';
1197#endif
1198
1199 rect->width = CharWidth(sink, font, 0, ch);
1200 rect->height = font->descent + font->ascent + 1;
1201
1202 rect->x = sink->ascii_sink.cursor_x;
1203 rect->y = sink->ascii_sink.cursor_y - font->ascent;
1204}
1205
1206/* this function is required to support diferent fonts and correctly place
1207 * the cursor. There are better ways to calculate the base line, but there is
1208 * no place/code (yet) to store this information.
1209 */
1210static int
1211FindCursorY(TextWidget ctx, XawTextPosition position)
1212{
1213 int y, line, ascent;
1214 AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink;
1215#ifndef OLDXAW
1216 XawTextAnchor *anchor;
1217 XawTextEntity *entity;
1218 XawTextProperty *property;
1219 XawTextPosition left, right;
1220#endif
1221
1222 for (line = 0; line < ctx->text.lt.lines; line++)
1223 if (position < ctx->text.lt.info[line + 1].position)
1224 break;
1225
1226 y = ctx->text.lt.info[line].y;
1227#ifndef OLDXAW
1228 ascent = 0;
1229 left = ctx->text.lt.info[line].position;
1230 right = ctx->text.lt.info[line + 1].position;
1231 right = XawMin(right, ctx->text.lastPos + 1)((right) < (ctx->text.lastPos + 1) ? (right) : (ctx->
text.lastPos + 1))
;
1232 while (left < right) {
1233 if (XawTextSourceAnchorAndEntity(ctx->text.source, left,
1234 &anchor, &entity)) {
1235 if ((property = XawTextSinkGetProperty((Widget)sink,
1236 entity->property)) != NULL((void*)0) &&
1237 (property->mask & XAW_TPROP_FONT(1<<0)))
1238 ascent = XawMax(property->font->ascent, ascent)((property->font->ascent) > (ascent) ? (property->
font->ascent) : (ascent))
;
1239 else
1240 ascent = XawMax(sink->ascii_sink.font->ascent, ascent)((sink->ascii_sink.font->ascent) > (ascent) ? (sink->
ascii_sink.font->ascent) : (ascent))
;
1241 left = anchor->position + entity->offset + entity->length;
1242 }
1243 else if (anchor) {
1244 ascent = XawMax(sink->ascii_sink.font->ascent, ascent)((sink->ascii_sink.font->ascent) > (ascent) ? (sink->
ascii_sink.font->ascent) : (ascent))
;
1245 while (entity) {
1246 XawTextPosition tmp = anchor->position + entity->offset + entity->length;
1247
1248 if (tmp > left && tmp < right) {
1249 left = tmp;
1250 if ((property = XawTextSinkGetProperty((Widget)sink,
1251 entity->property)) != NULL((void*)0) &&
1252 (property->mask & XAW_TPROP_FONT(1<<0)))
1253 ascent = XawMax(property->font->ascent, ascent)((property->font->ascent) > (ascent) ? (property->
font->ascent) : (ascent))
;
1254 else
1255 ascent = XawMax(sink->ascii_sink.font->ascent, ascent)((sink->ascii_sink.font->ascent) > (ascent) ? (sink->
ascii_sink.font->ascent) : (ascent))
;
1256 }
1257 entity = entity->next;
1258 }
1259 if (entity == NULL((void*)0))
1260 break;
1261 }
1262 else {
1263 ascent = XawMax(sink->ascii_sink.font->ascent, ascent)((sink->ascii_sink.font->ascent) > (ascent) ? (sink->
ascii_sink.font->ascent) : (ascent))
;
1264 break;
1265 }
1266 }
1267 if (!ascent)
1268 ascent = sink->ascii_sink.font->ascent;
1269#else
1270 ascent = sink->ascii_sink.font->ascent;
1271#endif
1272
1273 return (y + ascent);
1274}
1275
1276static void
1277InsertCursor(Widget w, int x, int y, XawTextInsertState state)
1278{
1279 AsciiSinkObject sink = (AsciiSinkObject)w;
1280 XFontStruct *font = sink->ascii_sink.font;
1281 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1282 XawTextPosition position = XawTextGetInsertionPoint((Widget)ctx);
1283 Boolean overflow = (x & 0xffff8000) != 0;
1284#ifndef OLDXAW
1285 XawTextAnchor *anchor;
1286 XawTextEntity *entity;
1287 XawTextProperty *property;
1288#endif
1289
1290 if (XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L)) {
1291 int fheight;
1292 XawTextBlock block;
1293 XawTextPosition selection_start, selection_end;
1294 Boolean has_selection;
1295
1296 if (!sink->ascii_sink.echo) {
1297 if (sink->ascii_sink.laststate != state) {
1298 int width = CharWidth(sink, font, 0, ' ') - 1;
1299
1300 x = ctx->text.margin.left;
1301 y = ctx->text.margin.top;
1302 font = sink->ascii_sink.font;
1303 fheight = font->ascent + font->descent;
1304 if (state == XawisOn) {
1305 if (ctx->text.hasfocus)
1306 XFillRectangle(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window),
1307 sink->ascii_sink.xorgc, x, y,
1308 width + 1, fheight + 1);
1309 else
1310 XDrawRectangle(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window),
1311 sink->ascii_sink.xorgc, x, y,
1312 width, fheight);
1313
1314 }
1315 else
1316 _XawTextSinkClearToBackground(w, x, y,
1317 width + 1, fheight + 1);
1318 }
1319 sink->ascii_sink.cursor_x = x;
1320 sink->ascii_sink.cursor_y = y;
1321 sink->ascii_sink.laststate = state;
1322 return;
1323 }
1324
1325
1326 XawTextGetSelectionPos((Widget)ctx, &selection_start, &selection_end);
1327 has_selection = selection_start != selection_end;
1328
1329 if (sink->ascii_sink.laststate != state) {
1330 unsigned char ch;
1331
1332#ifndef OLDXAW
1333 if (XawTextSourceAnchorAndEntity(ctx->text.source,
1334 position, &anchor, &entity) &&
1335 (property = XawTextSinkGetProperty((Widget)sink,
1336 entity->property)) != NULL((void*)0) &&
1337 (property->mask & XAW_TPROP_FONT(1<<0)))
1338 font = property->font;
1339 else
1340 font = sink->ascii_sink.font;
1341#endif
1342
1343 fheight = font->ascent + font->descent;
1344 (void)XawTextSourceRead(XawTextGetSource((Widget)ctx),
1345 position, &block, 1);
1346 if (!block.length || block.ptr[0] == '\n' || block.ptr[0] == '\t')
1347 ch = ' ';
1348 else if ((*((unsigned char*)block.ptr) & 0177) < XawSP0x20
1349 || *(unsigned char*)block.ptr == 0177) {
1350 if (sink->ascii_sink.display_nonprinting)
1351 ch = *((unsigned char*)block.ptr) > 0177 ? '\\' : '^';
1352 else
1353 ch = ' ';
1354 }
1355 else
1356 ch = *(unsigned char*)block.ptr;
1357
1358 y = FindCursorY(ctx, position);
1359 if (ctx->text.hasfocus && !has_selection)
1360 XFillRectangle(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window),
1361 sink->ascii_sink.xorgc, x, y - font->ascent,
1362 CharWidth(sink, font, 0, ch), fheight + 1);
1363 else
1364 XDrawRectangle(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window),
1365 sink->ascii_sink.xorgc, x, y - font->ascent,
1366 CharWidth(sink, font, 0, ch) - 1, fheight);
1367 }
1368 }
1369
1370 sink->ascii_sink.cursor_x = overflow ? -16384 : x;
1371 sink->ascii_sink.cursor_y = y;
1372 sink->ascii_sink.laststate = state;
1373 sink->ascii_sink.cursor_position = position;
1374}
1375
1376/*
1377 * Given two positions, find the distance between them
1378 */
1379static void
1380FindDistance(Widget w, XawTextPosition fromPos, int fromx,
1381 XawTextPosition toPos, int *resWidth,
1382 XawTextPosition *resPos, int *resHeight)
1383{
1384#ifndef OLDXAW
1385 AsciiSinkObject sink = (AsciiSinkObject)w;
1386 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1387 XFontStruct *font = sink->ascii_sink.font;
1388 Widget source = ctx->text.source;
1389 XawTextPosition idx, pos;
1390 unsigned char c;
1391 XawTextBlock blk;
1392 int i, rWidth, ascent = 0, descent = 0;
1393 XawTextAnchor *anchor;
1394 XawTextEntity *entity;
1395 XawTextProperty *property;
1396 Cardinal length;
1397 Boolint done = False0;
1398
1399 pos = idx = fromPos;
1400 rWidth = 0;
1401 c = 0;
1402
1403 while (!done) {
1404 if (XawTextSourceAnchorAndEntity(source, pos, &anchor, &entity)) {
1405 length = anchor->position + entity->offset + entity->length;
1406 length = XawMin(toPos, length)((toPos) < (length) ? (toPos) : (length)) - pos;
1407 if ((property = XawTextSinkGetProperty((Widget)sink,
1408 entity->property)) != NULL((void*)0) &&
1409 (property->mask & XAW_TPROP_FONT(1<<0)))
1410 font = property->font;
1411 else
1412 font = sink->ascii_sink.font;
1413 }
1414 else {
1415 if (anchor) {
1416 while (entity && anchor->position + entity->offset < pos)
1417 entity = entity->next;
1418 if (entity) {
1419 length = anchor->position + entity->offset;
1420 length = XawMin(toPos, length)((toPos) < (length) ? (toPos) : (length)) - pos;
1421 }
1422 else
1423 length = XawMin(toPos - pos, 4096)((toPos - pos) < (4096) ? (toPos - pos) : (4096));
1424 }
1425 else
1426 length = XawMin(toPos - pos, 4096)((toPos - pos) < (4096) ? (toPos - pos) : (4096));
1427 font = sink->ascii_sink.font;
1428 }
1429
1430 ascent = XawMax(font->ascent, ascent)((font->ascent) > (ascent) ? (font->ascent) : (ascent
))
;
1431 descent = XawMax(font->descent, descent)((font->descent) > (descent) ? (font->descent) : (descent
))
;
1432
1433 pos = XawTextSourceRead(source, pos, &blk, length);
1434 if (blk.length == 0 && pos == idx) /* eof reached */
1435 break;
1436
1437 idx = blk.firstPos;
1438 for (i = 0; idx < toPos; i++, idx++) {
1439 if (i >= blk.length)
1440 break;
1441 c = blk.ptr[i];
1442 rWidth += CharWidth(sink, font, fromx + rWidth, c);
1443 if (c == XawLF0x0a) {
1444 idx++;
1445 done = True1;
1446 break;
1447 }
1448 }
1449 if (idx >= toPos)
1450 break;
1451 }
1452
1453 *resPos = idx;
1454 *resWidth = rWidth;
1455 *resHeight = ascent + descent + 1;
1456#else
1457 AsciiSinkObject sink = (AsciiSinkObject)w;
1458 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1459 XFontStruct *font = sink->ascii_sink.font;
1460 Widget source = ctx->text.source;
1461 XawTextPosition idx, pos;
1462 unsigned char c;
1463 XawTextBlock blk;
1464 int i, rWidth;
1465
1466 pos = XawTextSourceRead(source, fromPos, &blk, toPos - fromPos);
1467 rWidth = 0;
1468 for (i = 0, idx = fromPos; idx < toPos; i++, idx++) {
1469 if (i >= blk.length) {
1470 i = 0;
1471 pos = XawTextSourceRead(source, pos, &blk, toPos - pos);
1472 if (blk.length == 0)
1473 break;
1474 }
1475 c = blk.ptr[i];
1476 rWidth += CharWidth(sink, font, fromx + rWidth, c);
1477 if (c == XawLF0x0a) {
1478 idx++;
1479 break;
1480 }
1481 }
1482
1483 *resPos = idx;
1484 *resWidth = rWidth;
1485 *resHeight = font->ascent + font->descent + 1;
1486#endif
1487}
1488
1489static void
1490FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width,
1491 Boolint stopAtWordBreak, XawTextPosition *resPos,
1492 int *resWidth, int *resHeight)
1493{
1494#ifndef OLDXAW
1495 AsciiSinkObject sink = (AsciiSinkObject)w;
1496 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1497 Widget source = ctx->text.source;
1498 XFontStruct *font = sink->ascii_sink.font;
Value stored to 'font' during its initialization is never read
1499 XawTextPosition idx, pos, whiteSpacePosition = 0;
1500 int i, lastWidth, whiteSpaceWidth, rWidth, ascent = 0, descent = 0;
1501 Boolean whiteSpaceSeen;
1502 unsigned char c;
1503 XawTextBlock blk;
1504 XawTextAnchor *anchor;
1505 XawTextEntity *entity;
1506 XawTextProperty *property;
1507 Cardinal length;
1508 Boolint done = False0;
1509
1510 pos = idx = fromPos;
1511 rWidth = lastWidth = whiteSpaceWidth = 0;
1512 whiteSpaceSeen = False0;
1513 c = 0;
1514
1515 while (!done) {
1516 font = sink->ascii_sink.font;
1517 if (XawTextSourceAnchorAndEntity(source, pos, &anchor, &entity)) {
1518 length = anchor->position + entity->offset + entity->length - pos;
1519 if ((property = XawTextSinkGetProperty((Widget)sink,
1520 entity->property)) != NULL((void*)0) &&
1521 (property->mask & XAW_TPROP_FONT(1<<0)))
1522 font = property->font;
1523 }
1524 else {
1525 if (anchor) {
1526 while (entity && anchor->position + entity->offset < pos)
1527 entity = entity->next;
1528 if (entity)
1529 length = anchor->position + entity->offset - pos;
1530 else
1531 length = 4096;
1532 }
1533 else
1534 length = 4096;
1535 }
1536
1537 ascent = XawMax(font->ascent, ascent)((font->ascent) > (ascent) ? (font->ascent) : (ascent
))
;
1538 descent = XawMax(font->descent, descent)((font->descent) > (descent) ? (font->descent) : (descent
))
;
1539
1540 pos = XawTextSourceRead(source, pos, &blk, length);
1541 if (blk.length == 0 && pos == idx) /* eof reached */
1542 break;
1543
1544 idx = blk.firstPos;
1545 for (i = 0; rWidth <= width && i < blk.length; i++, idx++) {
1546 c = blk.ptr[i];
1547 lastWidth = rWidth;
1548 rWidth += CharWidth(sink, font, fromx + rWidth, c);
1549
1550 if (c == XawLF0x0a) {
1551 idx++;
1552 done = True1;
1553 break;
1554 }
1555 else if ((c == XawSP0x20 || c == XawTAB0x09) && rWidth <= width) {
1556 whiteSpaceSeen = True1;
1557 whiteSpacePosition = idx;
1558 whiteSpaceWidth = rWidth;
1559 }
1560 }
1561 if (rWidth > width)
1562 break;
1563 }
1564
1565 if (rWidth > width && idx > fromPos) {
1566 idx--;
1567 rWidth = lastWidth;
1568 if (stopAtWordBreak && whiteSpaceSeen) {
1569 idx = whiteSpacePosition + 1;
1570 rWidth = whiteSpaceWidth;
1571 }
1572 }
1573
1574 if (idx >= ctx->text.lastPos && c != XawLF0x0a)
1575 idx = ctx->text.lastPos + 1;
1576
1577 *resPos = idx;
1578 *resWidth = rWidth;
1579 *resHeight = ascent + descent + 1;
1580#else
1581 AsciiSinkObject sink = (AsciiSinkObject)w;
1582 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1583 Widget source = ctx->text.source;
1584 XFontStruct *font = sink->ascii_sink.font;
1585 XawTextPosition idx, pos, whiteSpacePosition = 0;
1586 int i, lastWidth, whiteSpaceWidth, rWidth;
1587 Boolean whiteSpaceSeen;
1588 unsigned char c;
1589 XawTextBlock blk;
1590
1591 pos = XawTextSourceRead(source, fromPos, &blk, BUFSIZ8192);
1592 rWidth = lastWidth = whiteSpaceWidth = 0;
1593 whiteSpaceSeen = False0;
1594 c = 0;
1595
1596 for (i = 0, idx = fromPos; rWidth <= width; i++, idx++) {
1597 if (i >= blk.length) {
1598 i = 0;
1599 pos = XawTextSourceRead(source, pos, &blk, BUFSIZ8192);
1600 if (blk.length == 0)
1601 break;
1602 }
1603 c = blk.ptr[i];
1604 lastWidth = rWidth;
1605 rWidth += CharWidth(sink, font, fromx + rWidth, c);
1606
1607 if (c == XawLF0x0a) {
1608 idx++;
1609 break;
1610 }
1611 else if ((c == XawSP0x20 || c == XawTAB0x09) && rWidth <= width) {
1612 whiteSpaceSeen = True1;
1613 whiteSpacePosition = idx;
1614 whiteSpaceWidth = rWidth;
1615 }
1616 }
1617
1618 if (rWidth > width && idx > fromPos) {
1619 idx--;
1620 rWidth = lastWidth;
1621 if (stopAtWordBreak && whiteSpaceSeen) {
1622 idx = whiteSpacePosition + 1;
1623 rWidth = whiteSpaceWidth;
1624 }
1625 }
1626
1627 if (idx >= ctx->text.lastPos && c != XawLF0x0a)
1628 idx = ctx->text.lastPos + 1;
1629
1630 *resPos = idx;
1631 *resWidth = rWidth;
1632 *resHeight = font->ascent + font->descent + 1;
1633#endif
1634}
1635
1636static void
1637Resolve(Widget w, XawTextPosition pos, int fromx, int width,
1638 XawTextPosition *pos_return)
1639{
1640 int resWidth, resHeight;
1641 Widget source = XawTextGetSource(XtParent(w)((w)->core.parent));
1642
1643 FindPosition(w, pos, fromx, width, False0, pos_return, &resWidth, &resHeight);
1644 if (*pos_return > GETLASTPOSXawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, 1))
1645 *pos_return = GETLASTPOSXawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, 1);
1646}
1647
1648static void
1649GetGC(AsciiSinkObject sink)
1650{
1651 XtGCMask valuemask = (GCFont(1L<<14) | GCGraphicsExposures(1L<<16) | GCClipXOrigin(1L<<17) |
1652 GCForeground(1L<<2) | GCBackground(1L<<3));
1653 XGCValues values;
1654
1655 /* XXX We dont want do share a gc that will change the clip-mask */
1656 values.clip_x_origin = (long)sink;
1657 values.clip_mask = None0L;
1658 values.font = sink->ascii_sink.font->fid;
1659 values.graphics_exposures = False0;
1660
1661 values.foreground = sink->text_sink.foreground;
1662 values.background = sink->text_sink.background;
1663 sink->ascii_sink.normgc = XtAllocateGC((Widget)sink, 0, valuemask, &values,
1664 GCClipMask(1L<<19) | GCFont(1L<<14) | GCForeground(1L<<2) |
1665 GCBackground(1L<<3), 0);
1666
1667 values.foreground = sink->text_sink.background;
1668#ifndef OLDXAW
1669 values.background = sink->text_sink.cursor_color;
1670#else
1671 values.background = sink->text_sink.foreground;
1672#endif
1673 sink->ascii_sink.invgc = XtAllocateGC((Widget)sink, 0, valuemask, &values,
1674 GCClipMask(1L<<19) | GCFont(1L<<14), 0);
1675
1676 valuemask |= GCFunction(1L<<0);
1677 values.function = GXxor0x6;
1678#ifndef OLDXAW
1679 values.foreground = sink->text_sink.background ^ sink->text_sink.cursor_color;
1680#else
1681 values.foreground = sink->text_sink.background ^ sink->text_sink.foreground;
1682#endif
1683 values.background = 0L;
1684 sink->ascii_sink.xorgc = XtAllocateGC((Widget)sink, 0, valuemask,
1685 &values, GCClipMask(1L<<19) | GCFont(1L<<14), 0);
1686
1687 XawAsciiSinkResize((Widget)sink);
1688}
1689
1690/* Function:
1691 * XawAsciiSinkInitialize
1692 *
1693 * Parameters:
1694 * request - the requested and new values for the object instance
1695 * cnew - ""
1696 *
1697 * Description:
1698 * Initializes the TextSink Object.
1699 */
1700/*ARGSUSED*/
1701static void
1702XawAsciiSinkInitialize(Widget request, Widget cnew,
1703 ArgList args, Cardinal *num_args)
1704{
1705 AsciiSinkObject sink = (AsciiSinkObject)cnew;
1706
1707 GetGC(sink);
1708
1709 if (!sink->ascii_sink.font) XtError("Aborting: no font found\n");
1710
1711 sink->ascii_sink.cursor_position = 0;
1712 sink->ascii_sink.laststate = XawisOff;
1713 sink->ascii_sink.cursor_x = sink->ascii_sink.cursor_y = 0;
1714}
1715
1716/*
1717 * Function:
1718 * XawAsciiSinkDestroy
1719 *
1720 * Parameters:
1721 * w - AsciiSink Object
1722 *
1723 * Description:
1724 * This function cleans up when the object is destroyed.
1725 */
1726static void
1727XawAsciiSinkDestroy(Widget w)
1728{
1729 AsciiSinkObject sink = (AsciiSinkObject)w;
1730
1731 XtReleaseGC(w, sink->ascii_sink.normgc);
1732 XtReleaseGC(w, sink->ascii_sink.invgc);
1733 XtReleaseGC(w, sink->ascii_sink.xorgc);
1734
1735 sink->ascii_sink.normgc =
1736 sink->ascii_sink.invgc =
1737 sink->ascii_sink.xorgc = NULL((void*)0);
1738}
1739
1740static void
1741XawAsciiSinkResize(Widget w)
1742{
1743 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1744 AsciiSinkObject sink = (AsciiSinkObject)w;
1745 XRectangle rect;
1746 int width, height;
1747
1748 if (w->core.widget_class != asciiSinkObjectClass)
1749 return;
1750
1751 rect.x = ctx->text.r_margin.left;
1752 rect.y = ctx->text.r_margin.top;
1753 width = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - RHMargins(ctx)((ctx)->text.r_margin.left + (ctx)->text.r_margin.right
)
;
1754 height = (int)XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - RVMargins(ctx)((ctx)->text.r_margin.top + (ctx)->text.r_margin.bottom
)
;
1755 rect.width = width;
1756 rect.height = height;
1757
1758 if (sink->ascii_sink.normgc) {
1759 if (width >= 0 && height >= 0)
1760 XSetClipRectangles(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), sink->ascii_sink.normgc,
1761 0, 0, &rect, 1, Unsorted0);
1762 else
1763 XSetClipMask(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), sink->ascii_sink.normgc, None0L);
1764 }
1765 if (sink->ascii_sink.invgc) {
1766 if (width >= 0 && height >= 0)
1767 XSetClipRectangles(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), sink->ascii_sink.invgc,
1768 0, 0, &rect, 1, Unsorted0);
1769 else
1770 XSetClipMask(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), sink->ascii_sink.invgc, None0L);
1771 }
1772 if (sink->ascii_sink.xorgc) {
1773 if (width >= 0 && height >= 0)
1774 XSetClipRectangles(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), sink->ascii_sink.xorgc,
1775 0, 0, &rect, 1, Unsorted0);
1776 else
1777 XSetClipMask(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display), sink->ascii_sink.xorgc, None0L);
1778 }
1779}
1780
1781/*
1782 * Function:
1783 * XawAsciiSinkSetValues
1784 *
1785 * Parameters:
1786 * current - current state of the object
1787 * request - what was requested
1788 * cnew - what the object will become
1789 *
1790 * Description:
1791 * Sets the values for the AsciiSink.
1792 *
1793 * Returns:
1794 * True if redisplay is needed
1795 */
1796/*ARGSUSED*/
1797static Boolean
1798XawAsciiSinkSetValues(Widget current, Widget request, Widget cnew,
1799 ArgList args, Cardinal *num_args)
1800{
1801 AsciiSinkObject w = (AsciiSinkObject)cnew;
1802 AsciiSinkObject old_w = (AsciiSinkObject)current;
1803
1804 if (w->ascii_sink.font != old_w->ascii_sink.font
1805 || w->text_sink.background != old_w->text_sink.background
1806 || w->text_sink.foreground != old_w->text_sink.foreground
1807#ifndef OLDXAW
1808 || w->text_sink.cursor_color != old_w->text_sink.cursor_color
1809 || w->text_sink.properties != old_w->text_sink.properties
1810#endif
1811 ) {
1812#ifdef OLDXAW
1813 XtReleaseGC(cnew, w->ascii_sink.normgc);
1814 XtReleaseGC(cnew, w->ascii_sink.invgc);
1815 XtReleaseGC(cnew, w->ascii_sink.xorgc);
1816 GetGC(w);
1817#endif
1818 ((TextWidget)XtParent(cnew)((cnew)->core.parent))->text.redisplay_needed = True1;
1819 }
1820 else if (w->ascii_sink.echo != old_w->ascii_sink.echo
1821 || w->ascii_sink.display_nonprinting
1822 != old_w->ascii_sink.display_nonprinting)
1823 ((TextWidget)XtParent(cnew)((cnew)->core.parent))->text.redisplay_needed = True1;
1824#ifndef OLDXAW
1825 if (w->text_sink.properties != old_w->text_sink.properties) {
1826 XawTextProperty *property =
1827 XawTextSinkGetProperty(cnew, XrmStringToQuark("default"));
1828
1829 if (property) {
1830 if (property->mask & XAW_TPROP_FONT(1<<0))
1831 w->ascii_sink.font = property->font;
1832 if (property->mask & XAW_TPROP_FOREGROUND(1<<2))
1833 w->text_sink.foreground = property->foreground;
1834 if (property->mask & XAW_TPROP_BACKGROUND(1<<3))
1835 w->text_sink.background = property->background;
1836 }
1837 }
1838#endif
1839
1840 return (False0);
1841}
1842
1843/*
1844 * Function:
1845 * MaxLines
1846 *
1847 * Parameters:
1848 * w - AsciiSink Object
1849 * height - height to fit lines into
1850 *
1851 * Description:
1852 * Finds the Maximum number of lines that will fit in a given height.
1853 *
1854 * Returns:
1855 * The number of lines that will fit
1856 */
1857/*ARGSUSED*/
1858static int
1859MaxLines(Widget w, unsigned int height)
1860{
1861 AsciiSinkObject sink = (AsciiSinkObject)w;
1862 int font_height;
1863
1864 font_height = sink->ascii_sink.font->ascent + sink->ascii_sink.font->descent + 1;
1865
1866 return ((int)height / font_height);
1867}
1868
1869/*
1870 * Function:
1871 * MaxHeight
1872 *
1873 * Parameters:
1874 * w - AsciiSink Object
1875 * lines - number of lines
1876 *
1877 * Description:
1878 * Finds the Minium height that will contain a given number lines.
1879 *
1880 * Returns:
1881 * the height
1882 */
1883static int
1884MaxHeight(Widget w, int lines)
1885{
1886 AsciiSinkObject sink = (AsciiSinkObject)w;
1887
1888 return (lines * (sink->ascii_sink.font->ascent +
1889 sink->ascii_sink.font->descent + 1));
1890}
1891
1892/*
1893 * Function:
1894 * SetTabs
1895 *
1896 * Parameters:
1897 * w - AsciiSink Object
1898 * tab_count - number of tabs in the list
1899 * tabs - text positions of the tabs
1900 *
1901 * Description:
1902 * Sets the Tab stops.
1903 */
1904static void
1905SetTabs(Widget w, int tab_count, short *tabs)
1906{
1907 AsciiSinkObject sink = (AsciiSinkObject)w;
1908 int i;
1909 Atom XA_FIGURE_WIDTH;
1910 unsigned long figure_width = 0;
1911 XFontStruct *font = sink->ascii_sink.font;
1912
1913 /*
1914 * Find the figure width of the current font
1915 */
1916 XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", False0);
1917 if (XA_FIGURE_WIDTH != None0L
1918 && (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width)
1919 || figure_width == 0)) {
1920 if (font->per_char && font->min_char_or_byte2 <= '$'
1921 && font->max_char_or_byte2 >= '$')
1922 figure_width = font->per_char['$' - font->min_char_or_byte2].width;
1923 else
1924 figure_width = font->max_bounds.width;
1925 }
1926
1927 if (tab_count > sink->text_sink.tab_count) {
1928 sink->text_sink.tabs = (Position *)
1929 XtRealloc((char*)sink->text_sink.tabs, tab_count * sizeof(Position));
1930 sink->text_sink.char_tabs = (short *)
1931 XtRealloc((char*)sink->text_sink.char_tabs, tab_count * sizeof(short));
1932 }
1933
1934 for (i = 0 ; i < tab_count ; i++) {
1935 sink->text_sink.tabs[i] = tabs[i] * figure_width;
1936 sink->text_sink.char_tabs[i] = tabs[i];
1937 }
1938
1939 sink->text_sink.tab_count = tab_count;
1940
1941#ifndef NO_TAB_FIX
1942 {
1943 TextWidget ctx = (TextWidget)XtParent(w)((w)->core.parent);
1944 ctx->text.redisplay_needed = True1;
1945 _XawTextBuildLineTable(ctx, ctx->text.lt.top, True1);
1946 }
1947#endif
1948}