1 /* $XConsortium: TextSink.c,v 1.19 94/04/17 20:13:11 kaleb Exp $ */
4 Copyright (c) 1989, 1994 X Consortium
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
30 * Author: Chris Peterson, MIT X Consortium.
32 * Much code taken from X11R3 AsciiSink.
36 * TextSink.c - TextSink object. (For use with the text widget).
42 #include <X11/IntrinsicP.h>
43 #include <X11/StringDefs.h>
44 #include <X11/Xaw/XawInit.h>
45 #include <X11/Xaw/TextSinkP.h>
46 #include <X11/Xaw/TextP.h>
48 /****************************************************************
50 * Full class record constant
52 ****************************************************************/
54 static void ClassPartInitialize(), Initialize(), Destroy();
55 static Boolean
SetValues();
57 static int MaxHeight(), MaxLines();
58 static void DisplayText(), InsertCursor(), ClearToBackground(), FindPosition();
59 static void FindDistance(), Resolve(), SetTabs(), GetCursorBounds();
61 #define offset(field) XtOffsetOf(TextSinkRec, text_sink.field)
62 static XtResource resources
[] = {
63 {XtNforeground
, XtCForeground
, XtRPixel
, sizeof (Pixel
),
64 offset(foreground
), XtRString
, XtDefaultForeground
},
65 {XtNbackground
, XtCBackground
, XtRPixel
, sizeof (Pixel
),
66 offset(background
), XtRString
, XtDefaultBackground
},
70 #define SuperClass (&objectClassRec)
71 TextSinkClassRec textSinkClassRec
= {
73 /* core_class fields */
74 /* superclass */ (WidgetClass
) SuperClass
,
75 /* class_name */ "TextSink",
76 /* widget_size */ sizeof(TextSinkRec
),
77 /* class_initialize */ XawInitializeWidgetSet
,
78 /* class_part_initialize */ ClassPartInitialize
,
79 /* class_inited */ FALSE
,
80 /* initialize */ Initialize
,
81 /* initialize_hook */ NULL
,
85 /* resources */ resources
,
86 /* num_resources */ XtNumber(resources
),
87 /* xrm_class */ NULLQUARK
,
92 /* destroy */ Destroy
,
95 /* set_values */ SetValues
,
96 /* set_values_hook */ NULL
,
98 /* get_values_hook */ NULL
,
100 /* version */ XtVersion
,
101 /* callback_private */ NULL
,
107 /* textSink_class fields */
109 /* DisplayText */ DisplayText
,
110 /* InsertCursor */ InsertCursor
,
111 /* ClearToBackground */ ClearToBackground
,
112 /* FindPosition */ FindPosition
,
113 /* FindDistance */ FindDistance
,
114 /* Resolve */ Resolve
,
115 /* MaxLines */ MaxLines
,
116 /* MaxHeight */ MaxHeight
,
117 /* SetTabs */ SetTabs
,
118 /* GetCursorBounds */ GetCursorBounds
,
122 WidgetClass textSinkObjectClass
= (WidgetClass
)&textSinkClassRec
;
125 ClassPartInitialize(wc
)
128 TextSinkObjectClass t_src
, superC
;
130 t_src
= (TextSinkObjectClass
) wc
;
131 superC
= (TextSinkObjectClass
) t_src
->object_class
.superclass
;
134 * We don't need to check for null super since we'll get to TextSink
138 if (t_src
->text_sink_class
.DisplayText
== XtInheritDisplayText
)
139 t_src
->text_sink_class
.DisplayText
= superC
->text_sink_class
.DisplayText
;
141 if (t_src
->text_sink_class
.InsertCursor
== XtInheritInsertCursor
)
142 t_src
->text_sink_class
.InsertCursor
=
143 superC
->text_sink_class
.InsertCursor
;
145 if (t_src
->text_sink_class
.ClearToBackground
== XtInheritClearToBackground
)
146 t_src
->text_sink_class
.ClearToBackground
=
147 superC
->text_sink_class
.ClearToBackground
;
149 if (t_src
->text_sink_class
.FindPosition
== XtInheritFindPosition
)
150 t_src
->text_sink_class
.FindPosition
=
151 superC
->text_sink_class
.FindPosition
;
153 if (t_src
->text_sink_class
.FindDistance
== XtInheritFindDistance
)
154 t_src
->text_sink_class
.FindDistance
=
155 superC
->text_sink_class
.FindDistance
;
157 if (t_src
->text_sink_class
.Resolve
== XtInheritResolve
)
158 t_src
->text_sink_class
.Resolve
= superC
->text_sink_class
.Resolve
;
160 if (t_src
->text_sink_class
.MaxLines
== XtInheritMaxLines
)
161 t_src
->text_sink_class
.MaxLines
= superC
->text_sink_class
.MaxLines
;
163 if (t_src
->text_sink_class
.MaxHeight
== XtInheritMaxHeight
)
164 t_src
->text_sink_class
.MaxHeight
= superC
->text_sink_class
.MaxHeight
;
166 if (t_src
->text_sink_class
.SetTabs
== XtInheritSetTabs
)
167 t_src
->text_sink_class
.SetTabs
= superC
->text_sink_class
.SetTabs
;
169 if (t_src
->text_sink_class
.GetCursorBounds
== XtInheritGetCursorBounds
)
170 t_src
->text_sink_class
.GetCursorBounds
=
171 superC
->text_sink_class
.GetCursorBounds
;
174 /* Function Name: Initialize
175 * Description: Initializes the TextSink Object.
176 * Arguments: request, new - the requested and new values for the object
184 Initialize(request
, new, args
, num_args
)
189 TextSinkObject sink
= (TextSinkObject
) new;
191 sink
->text_sink
.tab_count
= 0; /* Initialize the tab stops. */
192 sink
->text_sink
.tabs
= NULL
;
193 sink
->text_sink
.char_tabs
= NULL
;
196 /* Function Name: Destroy
197 * Description: This function cleans up when the object is
199 * Arguments: w - the TextSink Object.
207 TextSinkObject sink
= (TextSinkObject
) w
;
209 XtFree((char *) sink
->text_sink
.tabs
);
210 XtFree((char *) sink
->text_sink
.char_tabs
);
213 /* Function Name: SetValues
214 * Description: Sets the values for the TextSink
215 * Arguments: current - current state of the object.
216 * request - what was requested.
217 * new - what the object will become.
218 * Returns: True if redisplay is needed.
223 SetValues(current
, request
, new, args
, num_args
)
224 Widget current
, request
, new;
228 TextSinkObject w
= (TextSinkObject
) new;
229 TextSinkObject old_w
= (TextSinkObject
) current
;
231 if (w
->text_sink
.foreground
!= old_w
->text_sink
.foreground
)
232 ((TextWidget
)XtParent(new))->text
.redisplay_needed
= True
;
237 /************************************************************
239 * Class specific methods.
241 ************************************************************/
243 /* Function Name: DisplayText
244 * Description: Stub function that in subclasses will display text.
245 * Arguments: w - the TextSink Object.
246 * x, y - location to start drawing text.
247 * pos1, pos2 - location of starting and ending points
248 * in the text buffer.
249 * highlight - hightlight this text?
252 * This function doesn't actually display anything, it is only a place
258 DisplayText(w
, x
, y
, pos1
, pos2
, highlight
)
262 XawTextPosition pos1
, pos2
;
267 /* Function Name: InsertCursor
268 * Description: Places the InsertCursor.
269 * Arguments: w - the TextSink Object.
270 * x, y - location for the cursor.
271 * staye - whether to turn the cursor on, or off.
274 * This function doesn't actually display anything, it is only a place
280 InsertCursor(w
, x
, y
, state
)
283 XawTextInsertState state
;
288 /* Function Name: ClearToBackground
289 * Description: Clears a region of the sink to the background color.
290 * Arguments: w - the TextSink Object.
291 * x, y - location of area to clear.
292 * width, height - size of area to clear
299 ClearToBackground (w
, x
, y
, width
, height
)
302 Dimension width
, height
;
305 * Don't clear in height or width are zero.
306 * XClearArea() has special semantic for these values.
309 if ( (height
== 0) || (width
== 0) ) return;
310 XClearArea(XtDisplayOfObject(w
), XtWindowOfObject(w
),
311 x
, y
, width
, height
, False
);
314 /* Function Name: FindPosition
315 * Description: Finds a position in the text.
316 * Arguments: w - the TextSink Object.
317 * fromPos - reference position.
318 * fromX - reference location.
319 * width, - width of section to paint text.
320 * stopAtWordBreak - returned position is a word break?
321 * resPos - Position to return. *** RETURNED ***
322 * resWidth - Width actually used. *** RETURNED ***
323 * resHeight - Height actually used. *** RETURNED ***
324 * Returns: none (see above).
329 FindPosition(w
, fromPos
, fromx
, width
, stopAtWordBreak
,
330 resPos
, resWidth
, resHeight
)
332 XawTextPosition fromPos
;
334 Boolean stopAtWordBreak
;
335 XawTextPosition
*resPos
;
336 int *resWidth
, *resHeight
;
339 *resHeight
= *resWidth
= 0;
342 /* Function Name: FindDistance
343 * Description: Find the Pixel Distance between two text Positions.
344 * Arguments: w - the TextSink Object.
345 * fromPos - starting Position.
346 * fromX - x location of starting Position.
347 * toPos - end Position.
348 * resWidth - Distance between fromPos and toPos.
349 * resPos - Acutal toPos used.
350 * resHeight - Height required by this text.
356 FindDistance (w
, fromPos
, fromx
, toPos
, resWidth
, resPos
, resHeight
)
358 XawTextPosition fromPos
;
360 XawTextPosition toPos
;
362 XawTextPosition
*resPos
;
365 *resWidth
= *resHeight
= 0;
369 /* Function Name: Resolve
370 * Description: Resloves a location to a position.
371 * Arguments: w - the TextSink Object.
372 * pos - a reference Position.
373 * fromx - a reference Location.
374 * width - width to move.
375 * resPos - the resulting position.
381 Resolve (w
, pos
, fromx
, width
, resPos
)
385 XawTextPosition
*resPos
;
390 /* Function Name: MaxLines
391 * Description: Finds the Maximum number of lines that will fit in
393 * Arguments: w - the TextSink Object.
394 * height - height to fit lines into.
395 * Returns: the number of lines that will fit.
405 * The fontset has gone down to descent Sink Widget, so
406 * the functions such MaxLines, SetTabs... are bound to the descent.
408 * by Li Yuhong, Jan. 15, 1991
413 /* Function Name: MaxHeight
414 * Description: Finds the Minium height that will contain a given number
416 * Arguments: w - the TextSink Object.
417 * lines - the number of lines.
418 * Returns: the height.
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.
440 SetTabs(w
, tab_count
, tabs
)
448 /* Function Name: GetCursorBounds
449 * Description: Finds the bounding box for the insert curor (caret).
450 * Arguments: w - the TextSinkObject.
451 * rect - an X rectance containing the cursor bounds.
452 * Returns: none (fills in rect).
457 GetCursorBounds(w
, rect
)
461 rect
->x
= rect
->y
= rect
->width
= rect
->height
= 0;
463 /************************************************************
467 ************************************************************/
470 /* Function Name: XawTextSinkDisplayText
471 * Description: Stub function that in subclasses will display text.
472 * Arguments: w - the TextSink Object.
473 * x, y - location to start drawing text.
474 * pos1, pos2 - location of starting and ending points
475 * in the text buffer.
476 * highlight - hightlight this text?
479 * This function doesn't actually display anything, it is only a place
485 #if NeedFunctionPrototypes
486 XawTextSinkDisplayText(Widget w
,
487 #if NeedWidePrototypes
488 /* Position */ int x
, /* Position */ int y
,
490 Position x
, Position y
,
492 XawTextPosition pos1
, XawTextPosition pos2
,
493 #if NeedWidePrototypes
494 /* Boolean */ int highlight
)
499 XawTextSinkDisplayText(w
, x
, y
, pos1
, pos2
, highlight
)
503 XawTextPosition pos1
, pos2
;
506 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
508 (*class->text_sink_class
.DisplayText
)(w
, x
, y
, pos1
, pos2
, highlight
);
511 /* Function Name: XawTextSinkInsertCursor
512 * Description: Places the InsertCursor.
513 * Arguments: w - the TextSink Object.
514 * x, y - location for the cursor.
515 * staye - whether to turn the cursor on, or off.
518 * This function doesn't actually display anything, it is only a place
524 #if NeedFunctionPrototypes
525 XawTextSinkInsertCursor(Widget w
,
526 #if NeedWidePrototypes
527 int x
, int y
, int state
)
529 Position x
, Position y
, XawTextInsertState state
)
532 XawTextSinkInsertCursor(w
, x
, y
, state
)
535 XawTextInsertState state
;
538 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
540 (*class->text_sink_class
.InsertCursor
)(w
, x
, y
, state
);
544 /* Function Name: XawTextSinkClearToBackground
545 * Description: Clears a region of the sink to the background color.
546 * Arguments: w - the TextSink Object.
547 * x, y - location of area to clear.
548 * width, height - size of area to clear
551 * This function doesn't actually display anything, it is only a place
557 #if NeedFunctionPrototypes
558 XawTextSinkClearToBackground (Widget w
,
559 #if NeedWidePrototypes
560 int x
, int y
, unsigned int width
, unsigned int height
)
562 Position x
, Position y
,
563 Dimension width
, Dimension height
)
566 XawTextSinkClearToBackground (w
, x
, y
, width
, height
)
569 Dimension width
, height
;
572 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
574 (*class->text_sink_class
.ClearToBackground
)(w
, x
, y
, width
, height
);
577 /* Function Name: XawTextSinkFindPosition
578 * Description: Finds a position in the text.
579 * Arguments: w - the TextSink Object.
580 * fromPos - reference position.
581 * fromX - reference location.
582 * width, - width of section to paint text.
583 * stopAtWordBreak - returned position is a word break?
584 * resPos - Position to return. *** RETURNED ***
585 * resWidth - Width actually used. *** RETURNED ***
586 * resHeight - Height actually used. *** RETURNED ***
587 * Returns: none (see above).
592 #if NeedFunctionPrototypes
593 XawTextSinkFindPosition(Widget w
, XawTextPosition fromPos
, int fromx
,
595 #if NeedWidePrototypes
596 /* Boolean */ int stopAtWordBreak
,
598 Boolean stopAtWordBreak
,
600 XawTextPosition
*resPos
, int *resWidth
, int *resHeight
)
602 XawTextSinkFindPosition(w
, fromPos
, fromx
, width
, stopAtWordBreak
,
603 resPos
, resWidth
, resHeight
)
605 XawTextPosition fromPos
;
607 Boolean stopAtWordBreak
;
608 XawTextPosition
*resPos
;
609 int *resWidth
, *resHeight
;
612 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
614 (*class->text_sink_class
.FindPosition
)(w
, fromPos
, fromx
, width
,
616 resPos
, resWidth
, resHeight
);
619 /* Function Name: XawTextSinkFindDistance
620 * Description: Find the Pixel Distance between two text Positions.
621 * Arguments: w - the TextSink Object.
622 * fromPos - starting Position.
623 * fromX - x location of starting Position.
624 * toPos - end Position.
625 * resWidth - Distance between fromPos and toPos.
626 * resPos - Acutal toPos used.
627 * resHeight - Height required by this text.
633 #if NeedFunctionPrototypes
634 XawTextSinkFindDistance (Widget w
, XawTextPosition fromPos
, int fromx
,
635 XawTextPosition toPos
, int *resWidth
,
636 XawTextPosition
*resPos
, int *resHeight
)
638 XawTextSinkFindDistance (w
, fromPos
, fromx
, toPos
, resWidth
, resPos
, resHeight
)
640 XawTextPosition fromPos
, toPos
, *resPos
;
641 int fromx
, *resWidth
, *resHeight
;
644 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
646 (*class->text_sink_class
.FindDistance
)(w
, fromPos
, fromx
, toPos
,
647 resWidth
, resPos
, resHeight
);
650 /* Function Name: XawTextSinkResolve
651 * Description: Resloves a location to a position.
652 * Arguments: w - the TextSink Object.
653 * pos - a reference Position.
654 * fromx - a reference Location.
655 * width - width to move.
656 * resPos - the resulting position.
662 #if NeedFunctionPrototypes
663 XawTextSinkResolve(Widget w
, XawTextPosition pos
, int fromx
, int width
,
664 XawTextPosition
*resPos
)
666 XawTextSinkResolve(w
, pos
, fromx
, width
, resPos
)
670 XawTextPosition
*resPos
;
673 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
675 (*class->text_sink_class
.Resolve
)(w
, pos
, fromx
, width
, resPos
);
678 /* Function Name: XawTextSinkMaxLines
679 * Description: Finds the Maximum number of lines that will fit in
681 * Arguments: w - the TextSink Object.
682 * height - height to fit lines into.
683 * Returns: the number of lines that will fit.
688 #if NeedFunctionPrototypes
689 XawTextSinkMaxLines(Widget w
,
690 #if NeedWidePrototypes
691 /* Dimension */ unsigned int height
)
696 XawTextSinkMaxLines(w
, height
)
701 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
703 return((*class->text_sink_class
.MaxLines
)(w
, height
));
706 /* Function Name: XawTextSinkMaxHeight
707 * Description: Finds the Minimum height that will contain a given number
709 * Arguments: w - the TextSink Object.
710 * lines - the number of lines.
711 * Returns: the height.
716 #if NeedFunctionPrototypes
717 XawTextSinkMaxHeight(Widget w
, int lines
)
719 XawTextSinkMaxHeight(w
, lines
)
724 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
726 return((*class->text_sink_class
.MaxHeight
)(w
, lines
));
729 /* Function Name: XawTextSinkSetTabs
730 * Description: Sets the Tab stops.
731 * Arguments: w - the TextSink Object.
732 * tab_count - the number of tabs in the list.
733 * tabs - the text positions of the tabs.
738 #if NeedFunctionPrototypes
739 XawTextSinkSetTabs(Widget w
, int tab_count
, int *tabs
)
741 XawTextSinkSetTabs(w
, tab_count
, tabs
)
743 int tab_count
, *tabs
;
747 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
748 short *char_tabs
= (short*)XtMalloc( (unsigned)tab_count
*sizeof(short) );
752 for (i
= tab_count
, tab
= char_tabs
; i
; i
--) *tab
++ = (short)*tabs
++;
754 (*class->text_sink_class
.SetTabs
)(w
, tab_count
, char_tabs
);
755 XtFree((char *)char_tabs
);
759 /* Function Name: XawTextSinkGetCursorBounds
760 * Description: Finds the bounding box for the insert curor (caret).
761 * Arguments: w - the TextSinkObject.
762 * rect - an X rectance containing the cursor bounds.
763 * Returns: none (fills in rect).
768 #if NeedFunctionPrototypes
769 XawTextSinkGetCursorBounds(Widget w
, XRectangle
*rect
)
771 XawTextSinkGetCursorBounds(w
, rect
)
776 TextSinkObjectClass
class = (TextSinkObjectClass
) w
->core
.widget_class
;
778 (*class->text_sink_class
.GetCursorBounds
)(w
, rect
);