glslang: add 14.3.0
[oi-userland.git] / components / x11 / libXaw4 / src / Xaw3_1TextSink.c
blob6371db9112597d4761d72ba48ed24ab70945c278
1 #if ( !defined(lint) && !defined(SABER) )
2 static char Xrcsid[] = "$XConsortium: TextSink.c,v 1.9 89/11/21 15:53:22 swick Exp $";
3 #endif
5 /*
6 * Copyright 1989 Massachusetts Institute of Technology
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of M.I.T. not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. M.I.T. makes no representations about the
15 * suitability of this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
18 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
20 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 * Author: Chris Peterson, MIT X Consortium.
27 * Much code taken from X11R3 AsciiSink.
31 * TextSink.c - TextSink object. (For use with the text widget).
35 #include <stdio.h>
36 #include <ctype.h>
37 #include <X11/IntrinsicP.h>
38 #include <X11/StringDefs.h>
39 #include <./Xaw3_1XawInit.h>
40 #include <./Xaw3_1TextSinkP.h>
41 #include <./Xaw3_1TextP.h>
43 /****************************************************************
45 * Full class record constant
47 ****************************************************************/
49 static void ClassPartInitialize(), Initialize(), Destroy();
50 static Boolean SetValues();
52 static int MaxHeight(), MaxLines();
53 static void DisplayText(), InsertCursor(), ClearToBackground(), FindPosition();
54 static void FindDistance(), Resolve(), SetTabs(), GetCursorBounds();
56 #define offset(field) XtOffset(TextSinkObject, text_sink.field)
57 static XtResource resources[] = {
58 {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
59 offset(font), XtRString, XtDefaultFont},
60 {XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
61 offset(foreground), XtRString, XtDefaultForeground},
62 {XtNbackground, XtCBackground, XtRPixel, sizeof (Pixel),
63 offset(background), XtRString, XtDefaultBackground},
65 #undef offset
67 #define SuperClass (&objectClassRec)
68 TextSinkClassRec textSinkClassRec = {
70 /* core_class fields */
71 /* superclass */ (WidgetClass) SuperClass,
72 /* class_name */ "TextSink",
73 /* widget_size */ sizeof(TextSinkRec),
74 /* class_initialize */ XawInitializeWidgetSet,
75 /* class_part_initialize */ ClassPartInitialize,
76 /* class_inited */ FALSE,
77 /* initialize */ Initialize,
78 /* initialize_hook */ NULL,
79 /* obj1 */ NULL,
80 /* obj2 */ NULL,
81 /* obj3 */ 0,
82 /* resources */ resources,
83 /* num_resources */ XtNumber(resources),
84 /* xrm_class */ NULLQUARK,
85 /* obj4 */ FALSE,
86 /* obj5 */ FALSE,
87 /* obj6 */ FALSE,
88 /* obj7 */ FALSE,
89 /* destroy */ Destroy,
90 /* obj8 */ NULL,
91 /* obj9 */ NULL,
92 /* set_values */ SetValues,
93 /* set_values_hook */ NULL,
94 /* obj10 */ NULL,
95 /* get_values_hook */ NULL,
96 /* obj11 */ NULL,
97 /* version */ XtVersion,
98 /* callback_private */ NULL,
99 /* obj12 */ NULL,
100 /* obj13 */ NULL,
101 /* obj14 */ NULL,
102 /* extension */ NULL
104 /* textSink_class fields */
106 /* DisplayText */ DisplayText,
107 /* InsertCursor */ InsertCursor,
108 /* ClearToBackground */ ClearToBackground,
109 /* FindPosition */ FindPosition,
110 /* FindDistance */ FindDistance,
111 /* Resolve */ Resolve,
112 /* MaxLines */ MaxLines,
113 /* MaxHeight */ MaxHeight,
114 /* SetTabs */ SetTabs,
115 /* GetCursorBounds */ GetCursorBounds,
119 WidgetClass textSinkObjectClass = (WidgetClass)&textSinkClassRec;
121 static void
122 ClassPartInitialize(wc)
123 WidgetClass wc;
125 register TextSinkObjectClass t_src, superC;
127 t_src = (TextSinkObjectClass) wc;
128 superC = (TextSinkObjectClass) t_src->object_class.superclass;
131 * We don't need to check for null super since we'll get to TextSink
132 * eventually.
135 if (t_src->text_sink_class.DisplayText == XtInheritDisplayText)
136 t_src->text_sink_class.DisplayText = superC->text_sink_class.DisplayText;
138 if (t_src->text_sink_class.InsertCursor == XtInheritInsertCursor)
139 t_src->text_sink_class.InsertCursor =
140 superC->text_sink_class.InsertCursor;
142 if (t_src->text_sink_class.ClearToBackground== XtInheritClearToBackground)
143 t_src->text_sink_class.ClearToBackground =
144 superC->text_sink_class.ClearToBackground;
146 if (t_src->text_sink_class.FindPosition == XtInheritFindPosition)
147 t_src->text_sink_class.FindPosition =
148 superC->text_sink_class.FindPosition;
150 if (t_src->text_sink_class.FindDistance == XtInheritFindDistance)
151 t_src->text_sink_class.FindDistance =
152 superC->text_sink_class.FindDistance;
154 if (t_src->text_sink_class.Resolve == XtInheritResolve)
155 t_src->text_sink_class.Resolve = superC->text_sink_class.Resolve;
157 if (t_src->text_sink_class.MaxLines == XtInheritMaxLines)
158 t_src->text_sink_class.MaxLines = superC->text_sink_class.MaxLines;
160 if (t_src->text_sink_class.MaxHeight == XtInheritMaxHeight)
161 t_src->text_sink_class.MaxHeight = superC->text_sink_class.MaxHeight;
163 if (t_src->text_sink_class.SetTabs == XtInheritSetTabs)
164 t_src->text_sink_class.SetTabs = superC->text_sink_class.SetTabs;
166 if (t_src->text_sink_class.GetCursorBounds == XtInheritGetCursorBounds)
167 t_src->text_sink_class.GetCursorBounds =
168 superC->text_sink_class.GetCursorBounds;
171 /* Function Name: Initialize
172 * Description: Initializes the TextSink Object.
173 * Arguments: request, new - the requested and new values for the object
174 * instance.
175 * Returns: none.
179 /* ARGSUSED */
180 static void
181 Initialize(request, new)
182 Widget request, new;
184 TextSinkObject sink = (TextSinkObject) new;
186 sink->text_sink.tab_count = 0; /* Initialize the tab stops. */
187 sink->text_sink.tabs = NULL;
188 sink->text_sink.char_tabs = NULL;
191 /* Function Name: Destroy
192 * Description: This function cleans up when the object is
193 * destroyed.
194 * Arguments: w - the TextSink Object.
195 * Returns: none.
198 static void
199 Destroy(w)
201 TextSinkObject sink = (TextSinkObject) w;
203 if (sink->text_sink.tabs != NULL)
204 XtFree((char *) sink->text_sink.tabs);
207 /* Function Name: SetValues
208 * Description: Sets the values for the TextSink
209 * Arguments: current - current state of the object.
210 * request - what was requested.
211 * new - what the object will become.
212 * Returns: True if redisplay is needed.
215 /* ARGSUSED */
216 static Boolean
217 SetValues(current, request, new)
218 Widget current, request, new;
220 TextSinkObject w = (TextSinkObject) new;
221 TextSinkObject old_w = (TextSinkObject) current;
222 TextSinkObjectClass class = (TextSinkObjectClass) w->object.widget_class;
224 if (w->text_sink.font != old_w->text_sink.font) {
225 (*class->text_sink_class.SetTabs)(new, w->text_sink.tab_count,
226 w->text_sink.char_tabs);
227 ((TextWidget)XtParent(new))->text.redisplay_needed = True;
228 } else {
229 if (w->text_sink.foreground != old_w->text_sink.foreground)
230 ((TextWidget)XtParent(new))->text.redisplay_needed = True;
233 return FALSE;
236 /************************************************************
238 * Class specific methods.
240 ************************************************************/
242 /* Function Name: DisplayText
243 * Description: Stub function that in subclasses will display text.
244 * Arguments: w - the TextSink Object.
245 * x, y - location to start drawing text.
246 * pos1, pos2 - location of starting and ending points
247 * in the text buffer.
248 * highlight - hightlight this text?
249 * Returns: none.
251 * This function doesn't actually display anything, it is only a place
252 * holder.
255 /* ARGSUSED */
256 static void
257 DisplayText(w, x, y, pos1, pos2, highlight)
258 Widget w;
259 Position x, y;
260 Boolean highlight;
261 XawTextPosition pos1, pos2;
263 return;
266 /* Function Name: InsertCursor
267 * Description: Places the InsertCursor.
268 * Arguments: w - the TextSink Object.
269 * x, y - location for the cursor.
270 * staye - whether to turn the cursor on, or off.
271 * Returns: none.
273 * This function doesn't actually display anything, it is only a place
274 * holder.
277 /* ARGSUSED */
278 static void
279 InsertCursor(w, x, y, state)
280 Widget w;
281 Position x, y;
282 XawTextInsertState state;
284 return;
287 /* Function Name: ClearToBackground
288 * Description: Clears a region of the sink to the background color.
289 * Arguments: w - the TextSink Object.
290 * x, y - location of area to clear.
291 * width, height - size of area to clear
292 * Returns: void.
296 /* ARGSUSED */
297 static void
298 ClearToBackground (w, x, y, width, height)
299 Widget w;
300 Position x, y;
301 Dimension width, height;
304 * Don't clear in height or width are zero.
305 * XClearArea() has special semantic for these values.
308 if ( (height == 0) || (width == 0) ) return;
309 XClearArea(XtDisplayOfObject(w), XtWindowOfObject(w),
310 x, y, width, height, False);
313 /* Function Name: FindPosition
314 * Description: Finds a position in the text.
315 * Arguments: w - the TextSink Object.
316 * fromPos - reference position.
317 * fromX - reference location.
318 * width, - width of section to paint text.
319 * stopAtWordBreak - returned position is a word break?
320 * resPos - Position to return. *** RETURNED ***
321 * resWidth - Width actually used. *** RETURNED ***
322 * resHeight - Height actually used. *** RETURNED ***
323 * Returns: none (see above).
326 /* ARGSUSED */
327 static void
328 FindPosition(w, fromPos, fromx, width, stopAtWordBreak,
329 resPos, resWidth, resHeight)
330 Widget w;
331 XawTextPosition fromPos;
332 int fromx, width;
333 Boolean stopAtWordBreak;
334 XawTextPosition *resPos;
335 int *resWidth, *resHeight;
337 *resPos = fromPos;
338 *resHeight = *resWidth = 0;
341 /* Function Name: FindDistance
342 * Description: Find the Pixel Distance between two text Positions.
343 * Arguments: w - the TextSink Object.
344 * fromPos - starting Position.
345 * fromX - x location of starting Position.
346 * toPos - end Position.
347 * resWidth - Distance between fromPos and toPos.
348 * resPos - Acutal toPos used.
349 * resHeight - Height required by this text.
350 * Returns: none.
353 /* ARGSUSED */
354 static void
355 FindDistance (w, fromPos, fromx, toPos, resWidth, resPos, resHeight)
356 Widget w;
357 XawTextPosition fromPos;
358 int fromx;
359 XawTextPosition toPos;
360 int *resWidth;
361 XawTextPosition *resPos;
362 int *resHeight;
364 *resWidth = *resHeight = 0;
365 *resPos = fromPos;
368 /* Function Name: Resolve
369 * Description: Resloves a location to a position.
370 * Arguments: w - the TextSink Object.
371 * pos - a reference Position.
372 * fromx - a reference Location.
373 * width - width to move.
374 * resPos - the resulting position.
375 * Returns: none
378 /* ARGSUSED */
379 static void
380 Resolve (w, pos, fromx, width, resPos)
381 Widget w;
382 XawTextPosition pos;
383 int fromx, width;
384 XawTextPosition *resPos;
386 *resPos = pos;
389 /* Function Name: MaxLines
390 * Description: Finds the Maximum number of lines that will fit in
391 * a given height.
392 * Arguments: w - the TextSink Object.
393 * height - height to fit lines into.
394 * Returns: the number of lines that will fit.
397 /* ARGSUSED */
398 static int
399 MaxLines(w, height)
400 Widget w;
401 Dimension height;
403 TextSinkObject sink = (TextSinkObject) w;
404 int font_height;
406 font_height = sink->text_sink.font->ascent + sink->text_sink.font->descent;
407 return( ((int) height) / font_height );
410 /* Function Name: MaxHeight
411 * Description: Finds the Minium height that will contain a given number
412 * lines.
413 * Arguments: w - the TextSink Object.
414 * lines - the number of lines.
415 * Returns: the height.
418 /* ARGSUSED */
419 static int
420 MaxHeight(w, lines)
421 Widget w;
422 int lines;
424 TextSinkObject sink = (TextSinkObject) w;
426 return(lines * (sink->text_sink.font->ascent +
427 sink->text_sink.font->descent));
430 /* Function Name: SetTabs
431 * Description: Sets the Tab stops.
432 * Arguments: w - the TextSink Object.
433 * tab_count - the number of tabs in the list.
434 * tabs - the text positions of the tabs.
435 * Returns: none
438 static void
439 SetTabs(w, tab_count, tabs)
440 Widget w;
441 int tab_count;
442 short *tabs;
444 TextSinkObject sink = (TextSinkObject) w;
445 int i;
446 Atom XA_FIGURE_WIDTH;
447 unsigned long figure_width = 0;
448 XFontStruct *font = sink->text_sink.font;
451 * Find the figure width of the current font.
454 XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", FALSE);
455 if ( (XA_FIGURE_WIDTH != NULL) &&
456 ( (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width)) ||
457 (figure_width == 0)) )
458 if (font->per_char && font->min_char_or_byte2 <= '$' &&
459 font->max_char_or_byte2 >= '$')
460 figure_width = font->per_char['$' - font->min_char_or_byte2].width;
461 else
462 figure_width = font->max_bounds.width;
464 if (tab_count > sink->text_sink.tab_count) {
465 sink->text_sink.tabs = (Position *) XtRealloc((caddr_t)sink->text_sink.tabs,
466 (Cardinal) (tab_count * sizeof(Position)));
467 sink->text_sink.char_tabs = (short *) XtRealloc(
468 (caddr_t) sink->text_sink.char_tabs,
469 (Cardinal) (tab_count * sizeof(short)));
472 for ( i = 0 ; i < tab_count ; i++ ) {
473 sink->text_sink.tabs[i] = tabs[i] * figure_width;
474 sink->text_sink.char_tabs[i] = tabs[i];
477 sink->text_sink.tab_count = tab_count;
480 /* Function Name: GetCursorBounds
481 * Description: Finds the bounding box for the insert curor (caret).
482 * Arguments: w - the TextSinkObject.
483 * rect - an X rectance containing the cursor bounds.
484 * Returns: none (fills in rect).
487 /* ARGSUSED */
488 static void
489 GetCursorBounds(w, rect)
490 Widget w;
491 XRectangle * rect;
493 rect->x = rect->y = rect->width = rect->height = 0;
495 /************************************************************
497 * Public Functions.
499 ************************************************************/
502 /* Function Name: XawTextSinkDisplayText
503 * Description: Stub function that in subclasses will display text.
504 * Arguments: w - the TextSink Object.
505 * x, y - location to start drawing text.
506 * pos1, pos2 - location of starting and ending points
507 * in the text buffer.
508 * highlight - hightlight this text?
509 * Returns: none.
511 * This function doesn't actually display anything, it is only a place
512 * holder.
515 /* ARGSUSED */
516 void
517 XawTextSinkDisplayText(w, x, y, pos1, pos2, highlight)
518 Widget w;
519 Position x, y;
520 Boolean highlight;
521 XawTextPosition pos1, pos2;
523 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
525 (*class->text_sink_class.DisplayText)(w, x, y, pos1, pos2, highlight);
528 /* Function Name: XawTextSinkInsertCursor
529 * Description: Places the InsertCursor.
530 * Arguments: w - the TextSink Object.
531 * x, y - location for the cursor.
532 * staye - whether to turn the cursor on, or off.
533 * Returns: none.
535 * This function doesn't actually display anything, it is only a place
536 * holder.
539 /* ARGSUSED */
540 void
541 XawTextSinkInsertCursor(w, x, y, state)
542 Widget w;
543 Position x, y;
544 XawTextInsertState state;
546 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
548 (*class->text_sink_class.InsertCursor)(w, x, y, state);
552 /* Function Name: XawTextSinkClearToBackground
553 * Description: Clears a region of the sink to the background color.
554 * Arguments: w - the TextSink Object.
555 * x, y - location of area to clear.
556 * width, height - size of area to clear
557 * Returns: void.
559 * This function doesn't actually display anything, it is only a place
560 * holder.
563 /* ARGSUSED */
564 void
565 XawTextSinkClearToBackground (w, x, y, width, height)
566 Widget w;
567 Position x, y;
568 Dimension width, height;
570 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
572 (*class->text_sink_class.ClearToBackground)(w, x, y, width, height);
575 /* Function Name: XawTextSinkFindPosition
576 * Description: Finds a position in the text.
577 * Arguments: w - the TextSink Object.
578 * fromPos - reference position.
579 * fromX - reference location.
580 * width, - width of section to paint text.
581 * stopAtWordBreak - returned position is a word break?
582 * resPos - Position to return. *** RETURNED ***
583 * resWidth - Width actually used. *** RETURNED ***
584 * resHeight - Height actually used. *** RETURNED ***
585 * Returns: none (see above).
588 /* ARGSUSED */
589 void
590 XawTextSinkFindPosition(w, fromPos, fromx, width, stopAtWordBreak,
591 resPos, resWidth, resHeight)
592 Widget w;
593 XawTextPosition fromPos;
594 int fromx, width;
595 Boolean stopAtWordBreak;
596 XawTextPosition *resPos;
597 int *resWidth, *resHeight;
599 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
601 (*class->text_sink_class.FindPosition)(w, fromPos, fromx, width,
602 stopAtWordBreak,
603 resPos, resWidth, resHeight);
606 /* Function Name: XawTextSinkFindDistance
607 * Description: Find the Pixel Distance between two text Positions.
608 * Arguments: w - the TextSink Object.
609 * fromPos - starting Position.
610 * fromX - x location of starting Position.
611 * toPos - end Position.
612 * resWidth - Distance between fromPos and toPos.
613 * resPos - Acutal toPos used.
614 * resHeight - Height required by this text.
615 * Returns: none.
618 /* ARGSUSED */
619 void
620 XawTextSinkFindDistance (w, fromPos, fromx, toPos, resWidth, resPos, resHeight)
621 Widget w;
622 XawTextPosition fromPos, toPos, *resPos;
623 int fromx, *resWidth, *resHeight;
625 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
627 (*class->text_sink_class.FindDistance)(w, fromPos, fromx, toPos,
628 resWidth, resPos, resHeight);
631 /* Function Name: XawTextSinkResolve
632 * Description: Resloves a location to a position.
633 * Arguments: w - the TextSink Object.
634 * pos - a reference Position.
635 * fromx - a reference Location.
636 * width - width to move.
637 * resPos - the resulting position.
638 * Returns: none
641 /* ARGSUSED */
642 void
643 XawTextSinkResolve(w, pos, fromx, width, resPos)
644 Widget w;
645 XawTextPosition pos;
646 int fromx, width;
647 XawTextPosition *resPos;
649 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
651 (*class->text_sink_class.Resolve)(w, pos, fromx, width, resPos);
654 /* Function Name: XawTextSinkMaxLines
655 * Description: Finds the Maximum number of lines that will fit in
656 * a given height.
657 * Arguments: w - the TextSink Object.
658 * height - height to fit lines into.
659 * Returns: the number of lines that will fit.
662 /* ARGSUSED */
664 XawTextSinkMaxLines(w, height)
665 Widget w;
666 Dimension height;
668 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
670 return((*class->text_sink_class.MaxLines)(w, height));
673 /* Function Name: XawTextSinkMaxHeight
674 * Description: Finds the Minium height that will contain a given number
675 * lines.
676 * Arguments: w - the TextSink Object.
677 * lines - the number of lines.
678 * Returns: the height.
681 /* ARGSUSED */
683 XawTextSinkMaxHeight(w, lines)
684 Widget w;
685 int lines;
687 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
689 return((*class->text_sink_class.MaxHeight)(w, lines));
692 /* Function Name: XawTextSinkSetTabs
693 * Description: Sets the Tab stops.
694 * Arguments: w - the TextSink Object.
695 * tab_count - the number of tabs in the list.
696 * tabs - the text positions of the tabs.
697 * Returns: none
700 void
701 XawTextSinkSetTabs(w, tab_count, tabs)
702 Widget w;
703 int tab_count, *tabs;
705 if (tab_count > 0) {
706 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
707 short *char_tabs = (short*)XtMalloc( (unsigned)tab_count*sizeof(short) );
708 register short *tab;
709 register int i;
711 for (i = tab_count, tab = char_tabs; i; i--) *tab++ = (short)*tabs++;
713 (*class->text_sink_class.SetTabs)(w, tab_count, char_tabs);
714 XtFree((XtPointer)char_tabs);
718 /* Function Name: XawTextSinkGetCursorBounds
719 * Description: Finds the bounding box for the insert curor (caret).
720 * Arguments: w - the TextSinkObject.
721 * rect - an X rectance containing the cursor bounds.
722 * Returns: none (fills in rect).
725 /* ARGSUSED */
726 void
727 XawTextSinkGetCursorBounds(w, rect)
728 Widget w;
729 XRectangle * rect;
731 TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
733 (*class->text_sink_class.GetCursorBounds)(w, rect);