One more check on valid display which is known to be in the startup
[xcircuit.git] / Xw / SText.c
blobbbdcba8d8c1e9b91ce4b318a943b44469b0fac94
1 /*************************************<+>*************************************
2 *****************************************************************************
3 **
4 ** File: SText.c
5 **
6 ** Project: X Widgets
7 **
8 ** Description: Code/Definitions for StaticText widget class.
9 **
10 *****************************************************************************
11 **
12 ** Copyright (c) 1988 by Hewlett-Packard Company
13 ** Copyright (c) 1988 by the Massachusetts Institute of Technology
14 **
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
22 ** prior permission.
23 **
24 *****************************************************************************
25 *************************************<+>*************************************/
28 * Include files & Static Routine Definitions
31 #include <stdio.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <X11/StringDefs.h>
35 #include <X11/IntrinsicP.h>
36 #include <X11/Intrinsic.h>
37 #include <X11/keysymdef.h>
38 #include <Xw/Xw.h>
39 #include <Xw/XwP.h>
40 #include <Xw/SText.h>
41 #include <Xw/STextP.h>
43 static void Initialize ();
44 static void Realize();
45 static void Destroy();
46 static void Resize();
47 static Boolean SetValues();
48 static void Redisplay();
49 static void Select();
50 static void Release();
51 static void Toggle();
52 static void ClassInitialize();
55 /*************************************<->*************************************
58 * Description: default translation table for class: StaticText
59 * -----------
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
78 * -----------
80 * Matches string descriptors with internal routines.
81 * Note that Primitive will register additional event handlers
82 * for traversal.
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
100 * -----------
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[] = {
109 { XtNhSpace,
110 XtCHSpace,
111 XtRDimension,
112 sizeof(Dimension),
113 XtOffset(XwStaticTextWidget, static_text.internal_width),
114 XtRString,
117 { XtNvSpace,
118 XtCVSpace,
119 XtRDimension,
120 sizeof(Dimension),
121 XtOffset(XwStaticTextWidget, static_text.internal_height),
122 XtRString,
125 { XtNalignment,
126 XtCAlignment,
127 XtRAlignment,
128 sizeof(XwAlignment),
129 XtOffset(XwStaticTextWidget,static_text.alignment),
130 XtRString,
131 "Left"
133 { XtNgravity,
134 XtCGravity,
135 XtRGravity,
136 sizeof(int),
137 XtOffset(XwStaticTextWidget,static_text.gravity),
138 XtRString,
139 "CenterGravity"
141 { XtNwrap,
142 XtCWrap,
143 XtRBoolean,
144 sizeof(Boolean),
145 XtOffset(XwStaticTextWidget,static_text.wrap),
146 XtRString,
147 "TRUE"
149 { XtNstrip,
150 XtCStrip,
151 XtRBoolean,
152 sizeof(Boolean),
153 XtOffset(XwStaticTextWidget,static_text.strip),
154 XtRString,
155 "TRUE"
157 { XtNlineSpace,
158 XtCLineSpace,
159 XtRInt,
160 sizeof(int),
161 XtOffset(XwStaticTextWidget,static_text.line_space),
162 XtRString,
165 { XtNfont,
166 XtCFont,
167 XtRFontStruct,
168 sizeof(XFontStruct *),
169 XtOffset(XwStaticTextWidget,static_text.font),
170 XtRString,
171 "Fixed"
173 { XtNstring,
174 XtCString,
175 XtRString,
176 sizeof(char *),
177 XtOffset(XwStaticTextWidget, static_text.input_string),
178 XtRString,
179 NULL
185 /*************************************<->*************************************
188 * Description: global class record for instances of class: StaticText
189 * -----------
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,
228 /* extension */ NULL
231 NULL,
232 NULL,
233 NULL,
234 NULL,
235 NULL,
239 WidgetClass XwstatictextWidgetClass = (WidgetClass) &XwstatictextClassRec;
240 WidgetClass XwstaticTextWidgetClass = (WidgetClass) &XwstatictextClassRec;
244 /*************************************<->*************************************
246 * ClassInitialize
248 * Description:
249 * -----------
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;
283 * Description:
284 * -----------
285 * Checks a StaticText widget for nonsensical values, and changes
286 * nonsense values into meaninful values.
288 * Inputs:
289 * ------
291 * Outputs:
292 * -------
294 * Procedures Called
295 * -----------------
296 * XtWarning
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");
313 stp->line_space = 0;
317 * Check Alignment
320 switch(stp->alignment)
322 case XwALIGN_LEFT:
323 case XwALIGN_CENTER:
324 case XwALIGN_RIGHT:
325 /* Valid values. */
326 break;
327 default:
328 XtWarning("XwStaticTextWidget: Unknown alignment, set to Left instead");
329 stp->alignment = XwALIGN_LEFT;
330 break;
336 /*************************************<->*************************************
338 * static void SetNormalGC (stw)
339 * XwStaticTextWidget stw;
341 * Description:
342 * -----------
343 * Sets up a GC for the static text widget to write to.
345 * Inputs:
346 * ------
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.
351 * Outputs:
352 * -------
353 * Associates static_text.normal_GC with a GC.
355 * Procedures Called
356 * -----------------
357 * XCreateGC
358 * XSetClipRectangles
360 *************************************<->***********************************/
361 static void SetNormalGC(stw)
362 XwStaticTextWidget stw;
364 XGCValues values;
365 XtGCMask valueMask;
366 XRectangle ClipRect;
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),
375 valueMask,&values);
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)
398 * char *string;
400 * Description:
401 * -----------
402 * This routine returns the number of '\n' characters in "string"
404 * Inputs:
405 * ------
406 * string = The string to be counted.
408 * Outputs:
409 * -------
410 * The number of '\n' characters in the string.
412 * Procedures Called
413 * -----------------
415 *************************************<->***********************************/
416 static int RetCount(string)
417 char *string;
419 int numlines;
421 numlines = (*string ? 1 : 0);
422 while (*string)
424 if (*string == '\n')
425 numlines++;
426 string++;
428 return(numlines);
432 /*************************************<->*************************************
434 * static int Maxline(string, font)
435 * char *string;
436 * XFontStruct *font;
438 * Description:
439 * -----------
440 * For a given string and a given font, returns the length of
441 * '\n' delimited series of characters.
443 * Inputs:
444 * ------
445 * string = The string to be analyzed.
446 * font = The font in which string is to be analyzed.
448 * Outputs:
449 * -------
450 * The maximun length in pixels of the longest '\n' delimited series of
451 * characters.
453 * Procedures Called
454 * -----------------
455 * XTextWidth
457 *************************************<->***********************************/
458 static int Maxline(stw)
459 XwStaticTextWidget stw;
461 int i, cur;
462 int max = 0;
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;
470 while(*str1)
472 if ((stp->strip) &&
473 ((alignment == XwALIGN_LEFT) ||
474 (alignment == XwALIGN_CENTER)))
475 while (*str1 == ' ')
476 str1++;
477 str2 = str1;
478 for(i=0; ((*str1 != '\n') && *str1); i++, str1++);
479 if ((stp->strip) &&
480 ((alignment == XwALIGN_RIGHT) ||
481 (alignment == XwALIGN_CENTER)))
483 str3 = str1;
484 str3--;
485 while (*str3 == ' ')
486 i--, str3--;
488 if (i)
489 cur = XTextWidth(font,str2,i);
490 else
491 cur = 0;
492 if (cur > max)
493 max = cur;
494 if (*str1)
495 str1++; /* Step past the \n */
497 return(max);
501 /*************************************<->*************************************
503 * static void FormatText(stw)
504 * XwStaticTextWidget stw;
506 * Description:
507 * -----------
508 * Inserts newlines where necessary to fit stw->static_text.output_string
509 * into stw->core.width (if specified).
511 * Inputs:
512 * ------
513 * stw = The StaticText widget to be formatted.
515 * Outputs:
516 * -------
518 * Procedures Called
519 * -----------------
520 * XTextWidth
522 *************************************<->***********************************/
523 static void FormatText(stw)
524 XwStaticTextWidget stw;
526 int i, width, win, wordindex;
527 char *str1, *str2;
528 Boolean gotone;
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);
538 while (*str1)
540 i = 0;
541 width = 0;
542 wordindex = -1;
543 gotone = FALSE;
544 str2 = str1;
545 while (!gotone)
547 if ((stp->strip) && (wordindex == -1))
548 while (*str1 == ' ')
549 str1++;
551 *Step through until a character that we can
552 * break on.
554 while ((*str1 != ' ') && (*str1 != '\n') && (*str1))
555 i++, str1++;
557 wordindex++;
558 width = (i ? XTextWidth(stp->font,str2,i) : 0);
559 width;
560 if (width < win)
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.
567 switch (*str1)
569 case ' ':
571 * Add the space to the char count
573 i++;
575 * Check to see there's room to start another
576 * word.
578 width = XTextWidth(stw->static_text.font,
579 str2,i);
580 if (width >= win)
583 * Break the line if we can't start
584 * another word.
586 *str1 = '\n';
587 gotone = TRUE;
590 * Step past the space
592 str1++;
593 break;
594 case '\n':
596 * Forced break. Step pase the \n.
597 * Note the fall through to default.
599 str1++;
600 default:
602 * End of string.
604 gotone = TRUE;
605 break;
608 else if (width > win)
611 * We know that we have something
613 gotone = TRUE;
616 * See if there is at least one space to back up for.
618 if (wordindex)
620 str1--;
621 while (*str1 != ' ')
622 str1--;
623 *str1++ = '\n';
625 else
627 * We have a single word which is too long
628 * for the available window. Let the text
629 * clip rectangle handle it.
631 if (*str1)
632 *str1++ = '\n';
634 else /* (width == win) */
636 switch (*str1)
638 case ' ':
640 * If we stopped on a space, change it.
642 *str1 = '\n';
643 case '\n':
645 * Step past the \n.
647 str1++;
648 default:
649 gotone = TRUE;
650 break;
658 /*************************************<->*************************************
660 * static void GetTextRect(newstw)
661 * XwStaticTextWidget newstw;
663 * Description:
664 * -----------
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.
672 * Inputs:
673 * ------
675 * Outputs:
676 * -------
678 * Procedures Called
679 * -----------------
680 * Maxline
681 * RetCount
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);
705 if (stp->wrap)
707 if ((maxlen = Maxline(newstw)) <=
708 maxwin)
710 * We fit without formatting.
712 stp->TextRect.width = maxlen;
713 else
715 stp->TextRect.width = maxwin;
717 * Make the string fit.
719 FormatText(newstw);
722 else
723 stp->TextRect.width = Maxline(newstw);
725 else
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
740 * to be too tall.
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;
753 * Description:
754 * -----------
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.
763 * Inputs:
764 * ------
765 * stw = A meaningful StaticTextWidget.
767 * Outputs:
768 * -------
770 * Procedures Called
771 * -----------------
772 * strcpy
773 * GetTextRect
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.
794 GetTextRect(newstw);
795 else
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
811 * resource setting.
813 switch (stp->gravity)
815 case EastGravity:
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);
821 break;
822 case WestGravity:
823 case NorthWestGravity:
824 case SouthWestGravity:
825 stp->TextRect.x = stp->internal_width +
826 newstw->primitive.highlight_thickness;
827 break;
828 default:
829 stp->TextRect.x = (newstw->core.width
830 - stp->TextRect.width) / 2;
831 break;
834 else
836 * We go to the left.
838 stp->TextRect.x = newstw->primitive.highlight_thickness
839 + stp->internal_width;
841 else
844 * We go to the left.
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
863 * resource setting.
865 switch (stp->gravity)
867 case NorthGravity:
868 case NorthEastGravity:
869 case NorthWestGravity:
870 stp->TextRect.y = stp->internal_height +
871 newstw->primitive.highlight_thickness;
872 break;
873 case SouthGravity:
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);
879 break;
880 default:
881 stp->TextRect.y = (newstw->core.height
882 - stp->TextRect.height)/ 2;
883 break;
886 else
889 * We go to the top.
891 stp->TextRect.y = newstw->primitive.highlight_thickness
892 + stp->internal_height;
895 else
898 * We go to the top.
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;
916 char *out, *in;
918 out = output;
919 in = input;
920 while(*in)
921 if (*in == '\\')
923 in++;
924 switch (*in)
926 case 'n':
927 *out++ = '\n';
928 break;
929 case 't':
930 *out++ = '\t';
931 break;
932 case 'b':
933 *out++ = '\b';
934 break;
935 case 'r':
936 *out++ = '\r';
937 break;
938 case 'f':
939 *out++ = '\f';
940 break;
941 default:
942 *out++ = '\\';
943 *out++ = *in;
944 break;
946 in++;
948 else
949 *out++ = *in++;
950 *out = '\0';
953 /*************************************<->*************************************
955 * static void Initialize (request, new)
956 * Widget request, new;
958 * Description:
959 * -----------
960 * See XToolKit Documentation
963 * Inputs:
964 * ------
966 * Outputs:
967 * -------
969 * Procedures Called
970 * -----------------
971 * Xmalloc
972 * ProcessBackslashes
973 * XwStrlen
974 * SetSize
976 *************************************<->***********************************/
977 static void Initialize (req, new)
978 XwStaticTextWidget req, new;
980 char *s;
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;
995 ValidateInputs(new);
996 new->core.width = req->core.width;
997 new->core.height = req->core.height;
998 SetSize(new);
1002 /*************************************<->*************************************
1004 * static Boolean SetValues(current, request, new, last)
1005 * XwStaticTextWidget current, request, new;
1006 * Boolean last;
1008 * Description:
1009 * -----------
1010 * See XToolKit Documentation
1013 * Inputs:
1014 * ------
1016 * Outputs:
1017 * -------
1019 * Procedures Called
1020 * -----------------
1021 * ValidateInputs
1022 * strcmp
1023 * SetSize
1024 * SetNormalGC
1026 *************************************<->***********************************/
1027 static Boolean SetValues(current, request, new, last)
1028 XwStaticTextWidget current, request, new;
1029 Boolean last;
1031 Boolean flag = FALSE;
1032 Boolean newstring = FALSE;
1033 Boolean layoutchanges = FALSE;
1034 Boolean otherchanges = FALSE;
1035 char *newstr, *curstr;
1036 char *s;
1037 XwStaticTextPart *newstp, *curstp;
1038 int new_w, new_h;
1040 newstp = &(new->static_text);
1041 curstp = &(current->static_text);
1042 if (newstp->input_string != curstp->input_string)
1044 newstring = TRUE;
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);
1064 if ((newstring) ||
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.
1083 SetSize(new);
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;
1096 SetSize(new);
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;
1104 flag = TRUE;
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);
1116 SetNormalGC(new);
1118 flag = TRUE;
1121 return(flag);
1125 /*************************************<->*************************************
1127 * static void Realize(w , valueMask, attributes)
1128 * Widget w;
1129 * XtValueMask *valueMask;
1130 * XSetWindowAttributes *attributes;
1132 * Description:
1133 * -----------
1134 * See XToolKit Documentation
1136 * Inputs:
1137 * ------
1139 * Outputs:
1140 * -------
1142 * Procedures Called
1143 * -----------------
1144 * XtCreateWindow
1145 * SetNormalGC
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);
1156 SetNormalGC(stw);
1157 _XwRegisterName(stw);
1161 /*************************************<->*************************************
1163 * static void Destroy(stw)
1164 * XwStaticTextWidget stw;
1166 * Description:
1167 * -----------
1168 * See XToolKit Documentation
1170 * Inputs:
1171 * ------
1173 * Outputs:
1174 * -------
1176 * Procedures Called
1177 * -----------------
1178 * XtFree
1179 * XFreeGC
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;
1199 * Description:
1200 * -----------
1201 * See XToolKit Documentation
1203 * Inputs:
1204 * ------
1206 * Outputs:
1207 * -------
1209 * Procedures Called
1210 * -----------------
1211 * XTextExtents
1212 * XDrawString
1213 * XtWarning
1215 *************************************<->***********************************/
1216 static void Redisplay(stw)
1217 XwStaticTextWidget stw;
1219 GC normal_GC;
1220 int i;
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;
1226 XFontStruct *font;
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;
1237 font = stp->font;
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)
1258 case XwALIGN_LEFT:
1259 cur_x = ClipRect->x;
1260 while(*str1)
1263 * Left alignment strips leading blanks.
1265 if (stp->strip)
1266 while(*str1 == ' ')
1267 str1++;
1268 str2 = str1;
1270 * Look for a newline and count characters.
1272 for(i=0; ((*str1 != '\n') && *str1); i++, str1++);
1274 * Did we get anything?
1276 if (i)
1279 * Handle the left bearing of the first char
1280 * in this substring.
1282 XTextExtents(font,str2,1,&dir,&asc,&desc,
1283 &overall);
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.
1295 cur_y += y_delta;
1296 if (*str1)
1297 str1++; /* Step past the \n */
1299 break;
1300 case XwALIGN_CENTER:
1301 cur_x = ClipRect->x + (ClipRect->width / 2);
1302 while(*str1)
1305 * Strip leading blanks.
1307 if (stp->strip)
1308 while(*str1 == ' ')
1309 str1++;
1310 str2 = str1;
1311 for(i=0; ((*str1 != '\n') && *str1); i++, str1++);
1313 * Strip trailing blanks.
1315 if (stp->strip)
1317 str3 = str1;
1318 str3--;
1319 while (*str3 == ' ')
1320 i--, str3--;
1322 if (i)
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...*/
1332 cur_y += y_delta;
1333 if (*str1)
1334 str1++; /* Step past the \n */
1336 break;
1337 case XwALIGN_RIGHT:
1338 cur_x = ClipRect->x + ClipRect->width;
1339 while(*str1)
1341 str2 = str1;
1342 for(i=0; ((*str1 != '\n') && *str1); i++, str1++);
1344 * Strip trailing blanks.
1346 if (stp->strip)
1348 str3 = str1;
1349 str3--;
1350 while (*str3 == ' ')
1351 i--, str3--;
1353 if (i)
1355 XDrawString(XtDisplay(stw),XtWindow(stw),
1356 normal_GC,
1357 (cur_x - XTextWidth(font,str2,i)),
1358 cur_y,str2,i);
1360 cur_y += y_delta;
1361 if (*str1)
1362 str1++; /* Step past the \n */
1364 break;
1365 default:
1367 * How did we get here?
1369 XtWarning("XwStaticTextWidget: An Unknown Alignment has crept into the code\n");
1370 break;
1374 * We don't want to lose the highlight on redisplay
1375 * do we?
1377 if (stw->primitive.highlighted)
1379 _XwHighlightBorder(stw);
1380 stw->primitive.display_highlighted = TRUE;
1382 else
1383 if (stw->primitive.display_highlighted)
1385 _XwUnhighlightBorder(stw);
1386 stw->primitive.display_highlighted = FALSE;
1391 /*************************************<->*************************************
1393 * static void Resize(stw)
1394 * XwStaticTextWidget stw;
1396 * Description:
1397 * -----------
1398 * See XToolKit Documentation
1400 * Inputs:
1401 * ------
1403 * Outputs:
1404 * -------
1406 * Procedures Called
1407 * -----------------
1408 * SetSize
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.
1420 SetSize(stw);
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 /****************************************************************
1448 * Event Routines.
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;
1458 XEvent *event;
1460 XtCallCallbacks((Widget)w,XtNselect,event);
1463 static void Release(w,event)
1464 XwStaticTextWidget w;
1465 XEvent *event;
1467 XtCallCallbacks((Widget)w,XtNrelease,event);
1470 static void Toggle(w,event)
1471 XwStaticTextWidget w;
1472 XEvent *event;