1 /*************************************<+>*************************************
2 *****************************************************************************
8 ** Description: Code/Definitions for StaticText widget class.
10 *****************************************************************************
12 ** Copyright (c) 1988 by Hewlett-Packard Company
13 ** Copyright (c) 1988 by the Massachusetts Institute of Technology
15 ** Permission to use, copy, modify, and distribute this software
16 ** and its documentation for any purpose and without fee is hereby
17 ** granted, provided that the above copyright notice appear in all
18 ** copies and that both that copyright notice and this permission
19 ** notice appear in supporting documentation, and that the names of
20 ** Hewlett-Packard or M.I.T. not be used in advertising or publicity
21 ** pertaining to distribution of the software without specific, written
24 *****************************************************************************
25 *************************************<+>*************************************/
28 * Include files & Static Routine Definitions
34 #include <X11/StringDefs.h>
35 #include <X11/IntrinsicP.h>
36 #include <X11/Intrinsic.h>
37 #include <X11/keysymdef.h>
41 #include <Xw/STextP.h>
43 static void Initialize ();
44 static void Realize();
45 static void Destroy();
47 static Boolean
SetValues();
48 static void Redisplay();
50 static void Release();
52 static void ClassInitialize();
55 /*************************************<->*************************************
58 * Description: default translation table for class: StaticText
61 * Matches events with string descriptors for internal routines.
63 *************************************<->***********************************/
65 static char defaultTranslations
[] =
66 "<EnterWindow>: enter()\n\
67 <LeaveWindow>: leave()\n\
68 <Btn1Down>: select()\n\
69 <Btn1Up>: release()\n\
70 <KeyDown>Select: select() \n\
71 <KeyUp>Select: release()";
74 /*************************************<->*************************************
77 * Description: action list for class: StaticText
80 * Matches string descriptors with internal routines.
81 * Note that Primitive will register additional event handlers
84 *************************************<->***********************************/
86 static XtActionsRec actionsList
[] =
88 { "enter", (XtActionProc
) _XwPrimitiveEnter
},
89 { "leave", (XtActionProc
) _XwPrimitiveLeave
},
90 { "select", (XtActionProc
) Select
},
91 { "release", (XtActionProc
) Release
},
92 {"toggle", (XtActionProc
) Toggle
},
96 /*************************************<->*************************************
99 * Description: resource list for class: StaticText
102 * Provides default resource settings for instances of this class.
103 * To get full set of default settings, examine resouce list of super
104 * classes of this class.
106 *************************************<->***********************************/
108 static XtResource resources
[] = {
113 XtOffset(XwStaticTextWidget
, static_text
.internal_width
),
121 XtOffset(XwStaticTextWidget
, static_text
.internal_height
),
129 XtOffset(XwStaticTextWidget
,static_text
.alignment
),
137 XtOffset(XwStaticTextWidget
,static_text
.gravity
),
145 XtOffset(XwStaticTextWidget
,static_text
.wrap
),
153 XtOffset(XwStaticTextWidget
,static_text
.strip
),
161 XtOffset(XwStaticTextWidget
,static_text
.line_space
),
168 sizeof(XFontStruct
*),
169 XtOffset(XwStaticTextWidget
,static_text
.font
),
177 XtOffset(XwStaticTextWidget
, static_text
.input_string
),
185 /*************************************<->*************************************
188 * Description: global class record for instances of class: StaticText
191 * Defines default field settings for this class record.
193 *************************************<->***********************************/
195 XwStaticTextClassRec XwstatictextClassRec
= {
196 { /* core_class fields */
197 /* superclass */ (WidgetClass
) &XwprimitiveClassRec
,
198 /* class_name */ "XwStaticText",
199 /* widget_size */ sizeof(XwStaticTextRec
),
200 /* class_initialize */ ClassInitialize
,
201 /* class_part_initialize */ NULL
,
202 /* class_inited */ FALSE
,
203 /* initialize */ (XtInitProc
) Initialize
,
204 /* initialize_hook */ NULL
,
205 /* realize */ (XtRealizeProc
) Realize
,
206 /* actions */ actionsList
,
207 /* num_actions */ XtNumber(actionsList
),
208 /* resources */ resources
,
209 /* num_resources */ XtNumber(resources
),
210 /* xrm_class */ NULLQUARK
,
211 /* compress_motion */ TRUE
,
212 /* compress_exposure */ TRUE
,
213 /* compress_enterleave */ TRUE
,
214 /* visible_interest */ FALSE
,
215 /* destroy */ (XtWidgetProc
) Destroy
,
216 /* resize */ (XtWidgetProc
) Resize
,
217 /* expose */ (XtExposeProc
) Redisplay
,
218 /* set_values */ (XtSetValuesFunc
) SetValues
,
219 /* set_values_hook */ NULL
,
220 /* set_values_almost */ (XtAlmostProc
) XtInheritSetValuesAlmost
,
221 /* get_values_hook */ NULL
,
222 /* accept_focus */ NULL
,
223 /* version */ XtVersion
,
224 /* callback private */ NULL
,
225 /* tm_table */ defaultTranslations
,
226 /* query_geometry */ NULL
,
227 /* display_accelerator */ XtInheritDisplayAccelerator
,
239 WidgetClass XwstatictextWidgetClass
= (WidgetClass
) &XwstatictextClassRec
;
240 WidgetClass XwstaticTextWidgetClass
= (WidgetClass
) &XwstatictextClassRec
;
244 /*************************************<->*************************************
250 * Set fields in primitive class part of our class record so that
251 * the traversal code can invoke our select/release procedures (note
252 * that for this class toggle is a empty proc).
254 *************************************<->***********************************/
255 static void ClassInitialize()
257 XwstatictextClassRec
.primitive_class
.select_proc
= (XwEventProc
) Select
;
258 XwstatictextClassRec
.primitive_class
.release_proc
= (XwEventProc
) Release
;
259 XwstatictextClassRec
.primitive_class
.toggle_proc
= (XwEventProc
) Toggle
;
263 /*************************************<->*************************************
265 * Procedures and variables private to StaticText
267 *************************************<->************************************/
269 static void ValidateInputs();
270 static void SetNormalGC();
271 static int RetCount();
272 static int Maxline();
273 static void FormatText();
274 static void GetTextRect();
275 static void SetSize();
278 /*************************************<->*************************************
280 * static void ValidateInputs(stw)
281 * XwStaticTextWidget stw;
285 * Checks a StaticText widget for nonsensical values, and changes
286 * nonsense values into meaninful values.
298 *************************************<->***********************************/
299 static void ValidateInputs(stw
)
300 XwStaticTextWidget stw
;
302 XwStaticTextPart
*stp
;
304 stp
= &(stw
->static_text
);
307 *Check line_spacing. We will allow text to over write,
308 * we will not allow it to move from bottom to top.
310 if (stp
->line_space
< -100)
312 XtWarning("XwStaticTextWidget: line_space was less than -100, set to 0\n");
320 switch(stp
->alignment
)
328 XtWarning("XwStaticTextWidget: Unknown alignment, set to Left instead");
329 stp
->alignment
= XwALIGN_LEFT
;
336 /*************************************<->*************************************
338 * static void SetNormalGC (stw)
339 * XwStaticTextWidget stw;
343 * Sets up a GC for the static text widget to write to.
347 * stw = Points to an instance structure which has primitive.foreground
348 * core.background_pixel and static_text.font appropriately
349 * filled in with values.
353 * Associates static_text.normal_GC with a GC.
360 *************************************<->***********************************/
361 static void SetNormalGC(stw
)
362 XwStaticTextWidget stw
;
368 valueMask
= GCForeground
| GCBackground
| GCFont
;
370 values
.foreground
= stw
->primitive
.foreground
;
371 values
.background
= stw
->core
.background_pixel
;
372 values
.font
= stw
->static_text
.font
->fid
;
374 stw
->static_text
.normal_GC
= XCreateGC(XtDisplay(stw
),XtWindow(stw
),
377 * Set the Clip Region.
379 ClipRect
.width
= stw
->core
.width
-
380 (2 * (stw
->static_text
.internal_width
+
381 stw
->primitive
.highlight_thickness
));
382 ClipRect
.height
= stw
->core
.height
-
383 (2 * (stw
->static_text
.internal_height
+
384 stw
->primitive
.highlight_thickness
));
385 ClipRect
.x
= stw
->primitive
.highlight_thickness
+
386 stw
->static_text
.internal_width
;
387 ClipRect
.y
= stw
->primitive
.highlight_thickness
+
388 stw
->static_text
.internal_height
;
390 XSetClipRectangles(XtDisplay(stw
),stw
->static_text
.normal_GC
,
391 0,0, &ClipRect
,1,Unsorted
);
395 /*************************************<->*************************************
397 * static int RetCount(string)
402 * This routine returns the number of '\n' characters in "string"
406 * string = The string to be counted.
410 * The number of '\n' characters in the string.
415 *************************************<->***********************************/
416 static int RetCount(string
)
421 numlines
= (*string
? 1 : 0);
432 /*************************************<->*************************************
434 * static int Maxline(string, font)
440 * For a given string and a given font, returns the length of
441 * '\n' delimited series of characters.
445 * string = The string to be analyzed.
446 * font = The font in which string is to be analyzed.
450 * The maximun length in pixels of the longest '\n' delimited series of
457 *************************************<->***********************************/
458 static int Maxline(stw
)
459 XwStaticTextWidget stw
;
463 char *str1
, *str2
, *str3
;
464 XwAlignment alignment
= stw
->static_text
.alignment
;
465 XFontStruct
*font
= stw
->static_text
.font
;
466 XwStaticTextPart
*stp
;
468 stp
= &(stw
->static_text
);
469 str1
= stp
->output_string
;
473 ((alignment
== XwALIGN_LEFT
) ||
474 (alignment
== XwALIGN_CENTER
)))
478 for(i
=0; ((*str1
!= '\n') && *str1
); i
++, str1
++);
480 ((alignment
== XwALIGN_RIGHT
) ||
481 (alignment
== XwALIGN_CENTER
)))
489 cur
= XTextWidth(font
,str2
,i
);
495 str1
++; /* Step past the \n */
501 /*************************************<->*************************************
503 * static void FormatText(stw)
504 * XwStaticTextWidget stw;
508 * Inserts newlines where necessary to fit stw->static_text.output_string
509 * into stw->core.width (if specified).
513 * stw = The StaticText widget to be formatted.
522 *************************************<->***********************************/
523 static void FormatText(stw
)
524 XwStaticTextWidget stw
;
526 int i
, width
, win
, wordindex
;
529 XwStaticTextPart
*stp
;
531 stp
= &(stw
->static_text
);
532 str1
= stp
->output_string
;
534 /* The available text window width is... */
535 win
= stw
->core
.width
- (2 * stp
->internal_width
)
536 - (2 * stw
->primitive
.highlight_thickness
);
547 if ((stp
->strip
) && (wordindex
== -1))
551 *Step through until a character that we can
554 while ((*str1
!= ' ') && (*str1
!= '\n') && (*str1
))
558 width
= (i
? XTextWidth(stp
->font
,str2
,i
) : 0);
563 * If the current string fragment is shorter than the
564 * available window. Check to see if we are at a
565 * forced break or not, and process accordingly.
571 * Add the space to the char count
575 * Check to see there's room to start another
578 width
= XTextWidth(stw
->static_text
.font
,
583 * Break the line if we can't start
590 * Step past the space
596 * Forced break. Step pase the \n.
597 * Note the fall through to default.
608 else if (width
> win
)
611 * We know that we have something
616 * See if there is at least one space to back up for.
627 * We have a single word which is too long
628 * for the available window. Let the text
629 * clip rectangle handle it.
634 else /* (width == win) */
640 * If we stopped on a space, change it.
658 /*************************************<->*************************************
660 * static void GetTextRect(newstw)
661 * XwStaticTextWidget newstw;
665 * Sets newstw->static_text.TextRect to appropriate values given
666 * newstw->core.width and newstw->static_text.input_string. The
667 * string is formatted if necessary.
669 * A newstw->core.width value of 0 tells this procedure to choose
670 * its own size based soley on newstw->static_text.input_string.
683 *************************************<->***********************************/
684 static void GetTextRect(newstw
)
685 XwStaticTextWidget newstw
;
687 int maxlen
, maxwin
, fheight
, numrets
;
688 XwStaticTextPart
*stp
;
690 stp
= &(newstw
->static_text
);
692 * Set the line height from the font structure.
694 fheight
= stp
->font
->ascent
+ stp
->font
->descent
;
695 if (newstw
->core
.width
)
698 * We were requested with a specific width. We must
699 * fit ourselves to it.
701 * The maximum available window width is...
703 maxwin
= newstw
->core
.width
- (2 * stp
->internal_width
)
704 - (2 * newstw
->primitive
.highlight_thickness
);
707 if ((maxlen
= Maxline(newstw
)) <=
710 * We fit without formatting.
712 stp
->TextRect
.width
= maxlen
;
715 stp
->TextRect
.width
= maxwin
;
717 * Make the string fit.
723 stp
->TextRect
.width
= Maxline(newstw
);
726 stp
->TextRect
.width
= Maxline(newstw
);
728 * See how tall the string wants to be.
730 numrets
= RetCount(stp
->output_string
);
731 stp
->TextRect
.height
= (fheight
* numrets
)
732 + (((numrets
- 1) * (stp
->line_space
/ 100.0)) * fheight
);
734 if ((newstw
->core
.height
) &&
735 ((newstw
->core
.height
- (2 * stp
->internal_height
)
736 - (2 * newstw
->primitive
.highlight_thickness
)) <
737 stp
->TextRect
.height
))
739 * Shorten the TextRect if the string wants
742 stp
->TextRect
.height
= newstw
->core
.height
743 - (2 * stp
->internal_height
)
744 - (2 * newstw
->primitive
.highlight_thickness
);
748 /*************************************<->*************************************
750 * static void SetSize(newstw)
751 * XwStaticTextWidget newstw;
755 * Copies newstw->static_text.input_string into output_string
757 * Sets newstw->core.width, newstw->core.height, and
758 * newstw->static_text.TextRect appropriately, formatting the
759 * string if necessary.
761 * The Clip Rectangle is placed in the window.
765 * stw = A meaningful StaticTextWidget.
775 *************************************<->***********************************/
776 static void SetSize(newstw
)
777 XwStaticTextWidget newstw
;
779 XwStaticTextPart
*stp
;
781 stp
= &(newstw
->static_text
);
783 * Copy the input string into the output string.
785 if (stp
->output_string
!= NULL
)
786 XtFree(stp
->output_string
);
787 stp
->output_string
= XtMalloc(XwStrlen(stp
->input_string
)+1);
788 if(stp
->input_string
)
789 strcpy(stp
->output_string
,stp
->input_string
);
790 if (*(stp
->output_string
))
792 * If we have a string then size it.
797 stp
->TextRect
.width
= 0;
798 stp
->TextRect
.height
= 0;
801 * Has a size been specified?
803 if (newstw
->core
.width
)
805 if ((newstw
->core
.width
806 - (2 * newstw
->primitive
.highlight_thickness
)
807 - (2 * stp
->internal_width
)) > stp
->TextRect
.width
)
810 * Use the extra space according to the gravity
813 switch (stp
->gravity
)
816 case NorthEastGravity
:
817 case SouthEastGravity
:
818 stp
->TextRect
.x
= newstw
->core
.width
-
819 (newstw
->primitive
.highlight_thickness
+
820 stp
->TextRect
.width
+ stp
->internal_width
);
823 case NorthWestGravity
:
824 case SouthWestGravity
:
825 stp
->TextRect
.x
= stp
->internal_width
+
826 newstw
->primitive
.highlight_thickness
;
829 stp
->TextRect
.x
= (newstw
->core
.width
830 - stp
->TextRect
.width
) / 2;
838 stp
->TextRect
.x
= newstw
->primitive
.highlight_thickness
839 + stp
->internal_width
;
846 stp
->TextRect
.x
= newstw
->primitive
.highlight_thickness
847 + stp
->internal_width
;
848 newstw
->core
.width
= stp
->TextRect
.width
849 + (2 * stp
->internal_width
)
850 + (2 * newstw
->primitive
.highlight_thickness
);
853 * Has a height been specified?
855 if (newstw
->core
.height
)
857 if ((newstw
->core
.height
- (2 * stp
->internal_height
)
858 - (2 * newstw
->primitive
.highlight_thickness
)) >
859 stp
->TextRect
.height
)
862 * Use the extra space according to the gravity
865 switch (stp
->gravity
)
868 case NorthEastGravity
:
869 case NorthWestGravity
:
870 stp
->TextRect
.y
= stp
->internal_height
+
871 newstw
->primitive
.highlight_thickness
;
874 case SouthEastGravity
:
875 case SouthWestGravity
:
876 stp
->TextRect
.y
= newstw
->core
.height
-
877 (newstw
->primitive
.highlight_thickness
+
878 stp
->TextRect
.height
+ stp
->internal_width
);
881 stp
->TextRect
.y
= (newstw
->core
.height
882 - stp
->TextRect
.height
)/ 2;
891 stp
->TextRect
.y
= newstw
->primitive
.highlight_thickness
892 + stp
->internal_height
;
900 stp
->TextRect
.y
= newstw
->primitive
.highlight_thickness
901 + stp
->internal_height
;
903 * We add our size to the current size.
904 * (Primitive has already added highlight_thicknesses.)
906 newstw
->core
.height
= stp
->TextRect
.height
907 + (2 * stp
->internal_height
)
908 + (2 * newstw
->primitive
.highlight_thickness
);
913 static void ProcessBackslashes(output
,input
)
914 char *output
, *input
;
953 /*************************************<->*************************************
955 * static void Initialize (request, new)
956 * Widget request, new;
960 * See XToolKit Documentation
976 *************************************<->***********************************/
977 static void Initialize (req
, new)
978 XwStaticTextWidget req
, new;
982 new->static_text
.output_string
= NULL
;
984 if (new->static_text
.input_string
!= NULL
)
988 * Copy the input string into local space.
990 s
= XtMalloc(XwStrlen(new->static_text
.input_string
)+1);
991 ProcessBackslashes(s
,new->static_text
.input_string
);
992 new->static_text
.input_string
= s
;
996 new->core
.width
= req
->core
.width
;
997 new->core
.height
= req
->core
.height
;
1002 /*************************************<->*************************************
1004 * static Boolean SetValues(current, request, new, last)
1005 * XwStaticTextWidget current, request, new;
1010 * See XToolKit Documentation
1026 *************************************<->***********************************/
1027 static Boolean
SetValues(current
, request
, new, last
)
1028 XwStaticTextWidget current
, request
, new;
1031 Boolean flag
= FALSE
;
1032 Boolean newstring
= FALSE
;
1033 Boolean layoutchanges
= FALSE
;
1034 Boolean otherchanges
= FALSE
;
1035 char *newstr
, *curstr
;
1037 XwStaticTextPart
*newstp
, *curstp
;
1040 newstp
= &(new->static_text
);
1041 curstp
= &(current
->static_text
);
1042 if (newstp
->input_string
!= curstp
->input_string
)
1046 * Copy the input string into local space.
1048 s
= XtMalloc(XwStrlen(newstp
->input_string
)+1);
1049 ProcessBackslashes(s
,new->static_text
.input_string
);
1051 * Deallocate the old string.
1053 XtFree(curstp
->input_string
);
1055 * Have everybody point to the new string.
1057 newstp
->input_string
= s
;
1058 curstp
->input_string
= s
;
1059 request
->static_text
.input_string
= s
;
1062 ValidateInputs(new);
1065 (newstp
->font
!= curstp
->font
) ||
1066 (newstp
->internal_height
!= curstp
->internal_height
) ||
1067 (newstp
->internal_width
!= curstp
->internal_width
) ||
1068 ((new->core
.width
<= 0) || (new->core
.height
<= 0)) ||
1069 (request
->core
.width
!= current
->core
.width
) ||
1070 (request
->core
.height
!= current
->core
.height
))
1072 if (request
->primitive
.recompute_size
)
1074 if (request
->core
.width
== current
->core
.width
)
1075 new->core
.width
= 0;
1076 if (request
->core
.height
== current
->core
.height
)
1077 new->core
.height
= 0;
1081 * Call SetSize to get the new size.
1086 * Save changes that SetSize does to the layout.
1088 new_w
= new->core
.width
;
1089 new_h
= new->core
.height
;
1091 * In case our parent won't let us change size we must
1092 * now restore the widget to the current size.
1094 new->core
.width
= current
->core
.width
;
1095 new->core
.height
= current
->core
.height
;
1098 * Reload new with the new sizes in order cause XtSetValues
1099 * to invoke our parent's geometry management procedure.
1101 new->core
.width
= new_w
;
1102 new->core
.height
= new_h
;
1107 if ((new->primitive
.foreground
!=
1108 current
->primitive
.foreground
) ||
1109 (new->core
.background_pixel
!=
1110 current
->core
.background_pixel
) ||
1111 (newstp
->font
!= curstp
->font
))
1113 if (XtIsRealized((Widget
)new))
1115 XFreeGC(XtDisplay(new),new->static_text
.normal_GC
);
1125 /*************************************<->*************************************
1127 * static void Realize(w , valueMask, attributes)
1129 * XtValueMask *valueMask;
1130 * XSetWindowAttributes *attributes;
1134 * See XToolKit Documentation
1147 *************************************<->***********************************/
1148 static void Realize(stw
, valueMask
, attributes
)
1149 XwStaticTextWidget stw
;
1150 XtValueMask
*valueMask
;
1151 XSetWindowAttributes
*attributes
;
1154 XtCreateWindow((Widget
)stw
,InputOutput
,(Visual
*) CopyFromParent
,
1155 *valueMask
,attributes
);
1157 _XwRegisterName(stw
);
1161 /*************************************<->*************************************
1163 * static void Destroy(stw)
1164 * XwStaticTextWidget stw;
1168 * See XToolKit Documentation
1181 *************************************<->***********************************/
1182 static void Destroy(stw
)
1183 XwStaticTextWidget stw
;
1185 XtFree(stw
->static_text
.input_string
);
1186 XtFree(stw
->static_text
.output_string
);
1187 if (XtIsRealized((Widget
)stw
))
1189 XFreeGC(XtDisplay(stw
),stw
->static_text
.normal_GC
);
1194 /*************************************<->*************************************
1196 * static void Redisplay(stw)
1197 * XwStaticTextWidget stw;
1201 * See XToolKit Documentation
1215 *************************************<->***********************************/
1216 static void Redisplay(stw
)
1217 XwStaticTextWidget stw
;
1221 int cur_x
, cur_y
; /* Current start of baseline */
1222 int y_delta
; /* Absolute space between baselines */
1223 int x_delta
; /* For left bearing of the first char in a line */
1224 int dir
, asc
, desc
; /* Junk parameters for XTextExtents */
1225 char *str1
, *str2
, *str3
;
1227 XCharStruct overall
;
1228 XRectangle
*ClipRect
;
1229 XwStaticTextPart
*stp
;
1232 * This is to save typing for me and
1233 * pointer arithmetic for the machine.
1235 stp
= &(stw
->static_text
);
1236 str1
= str2
= stp
->output_string
;
1238 normal_GC
= stp
->normal_GC
;
1239 ClipRect
= &(stp
->TextRect
);
1241 if (XtIsRealized((Widget
)stw
))
1242 XClearArea(XtDisplay(stw
),XtWindow(stw
),
1243 0,0,stw
->core
.width
,stw
->core
.height
,FALSE
);
1246 * We don't get to start drawing at the top of the text box.
1247 * See X11 font manual pages.
1249 cur_y
= ClipRect
->y
+ font
->ascent
;
1252 * Set up the total line spacing.
1254 y_delta
= ((stp
->line_space
/ 100.0) + 1) * (font
->descent
+ font
->ascent
);
1256 switch (stp
->alignment
)
1259 cur_x
= ClipRect
->x
;
1263 * Left alignment strips leading blanks.
1270 * Look for a newline and count characters.
1272 for(i
=0; ((*str1
!= '\n') && *str1
); i
++, str1
++);
1274 * Did we get anything?
1279 * Handle the left bearing of the first char
1280 * in this substring.
1282 XTextExtents(font
,str2
,1,&dir
,&asc
,&desc
,
1284 x_delta
= overall
.lbearing
;
1286 * Write to the window
1288 XDrawString(XtDisplay(stw
),XtWindow(stw
),
1289 normal_GC
,(cur_x
+ x_delta
),cur_y
,str2
,i
);
1290 x_delta
= overall
.lbearing
= 0;/* I'm paranoid...*/
1293 * Move to the next line.
1297 str1
++; /* Step past the \n */
1300 case XwALIGN_CENTER
:
1301 cur_x
= ClipRect
->x
+ (ClipRect
->width
/ 2);
1305 * Strip leading blanks.
1311 for(i
=0; ((*str1
!= '\n') && *str1
); i
++, str1
++);
1313 * Strip trailing blanks.
1319 while (*str3
== ' ')
1325 * Center the substring.
1327 x_delta
= XTextWidth(font
,str2
,i
) / 2;
1328 XDrawString(XtDisplay(stw
),XtWindow(stw
),
1329 normal_GC
,(cur_x
- x_delta
),cur_y
,str2
,i
);
1330 x_delta
= 0; /* ... still paranoid...*/
1334 str1
++; /* Step past the \n */
1338 cur_x
= ClipRect
->x
+ ClipRect
->width
;
1342 for(i
=0; ((*str1
!= '\n') && *str1
); i
++, str1
++);
1344 * Strip trailing blanks.
1350 while (*str3
== ' ')
1355 XDrawString(XtDisplay(stw
),XtWindow(stw
),
1357 (cur_x
- XTextWidth(font
,str2
,i
)),
1362 str1
++; /* Step past the \n */
1367 * How did we get here?
1369 XtWarning("XwStaticTextWidget: An Unknown Alignment has crept into the code\n");
1374 * We don't want to lose the highlight on redisplay
1377 if (stw
->primitive
.highlighted
)
1379 _XwHighlightBorder(stw
);
1380 stw
->primitive
.display_highlighted
= TRUE
;
1383 if (stw
->primitive
.display_highlighted
)
1385 _XwUnhighlightBorder(stw
);
1386 stw
->primitive
.display_highlighted
= FALSE
;
1391 /*************************************<->*************************************
1393 * static void Resize(stw)
1394 * XwStaticTextWidget stw;
1398 * See XToolKit Documentation
1409 * XSetClipRectangles
1411 *************************************<->***********************************/
1412 static void Resize(stw
)
1413 XwStaticTextWidget stw
;
1415 XRectangle ClipRect
;
1418 * Same as at initialization except just look at the new widget.
1422 if (XtIsRealized((Widget
)stw
))
1425 * Set the Clip Region.
1427 ClipRect
.width
= stw
->core
.width
-
1428 (2 * (stw
->static_text
.internal_width
+
1429 stw
->primitive
.highlight_thickness
));
1430 ClipRect
.height
= stw
->core
.height
-
1431 (2 * (stw
->static_text
.internal_height
+
1432 stw
->primitive
.highlight_thickness
));
1433 ClipRect
.x
= stw
->primitive
.highlight_thickness
+
1434 stw
->static_text
.internal_width
;
1435 ClipRect
.y
= stw
->primitive
.highlight_thickness
+
1436 stw
->static_text
.internal_height
;
1438 XSetClipRectangles(XtDisplay(stw
),stw
->static_text
.normal_GC
,
1439 0,0, &ClipRect
,1,Unsorted
);
1446 /****************************************************************
1450 * Select - Call the callback when the left button goes down.
1452 * Release - Call the callback when the left button goes up.
1454 ****************************************************************/
1456 static void Select(w
,event
)
1457 XwStaticTextWidget w
;
1460 XtCallCallbacks((Widget
)w
,XtNselect
,event
);
1463 static void Release(w
,event
)
1464 XwStaticTextWidget w
;
1467 XtCallCallbacks((Widget
)w
,XtNrelease
,event
);
1470 static void Toggle(w
,event
)
1471 XwStaticTextWidget w
;