dtcalc: change from obsoleted MAXFLOAT to FLT_MAX from std C
[oweals/cde.git] / cde / lib / DtWidget / TitleBox.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: TitleBox.c /main/14 1996/10/14 10:48:11 pascale $
24  *
25  * (c) Copyright 1996 Digital Equipment Corporation.
26  * (c) Copyright 1990,1996 Hewlett-Packard Company.
27  * (c) Copyright 1996 International Business Machines Corp.
28  * (c) Copyright 1996 Sun Microsystems, Inc.
29  * (c) Copyright 1996 Novell, Inc. 
30  * (c) Copyright 1996 FUJITSU LIMITED.
31  * (c) Copyright 1996 Hitachi.
32  */
33
34 /**---------------------------------------------------------------------
35 ***     
36 ***     file:           TitleBox.c
37 ***
38 ***     project:        MotifPlus Widgets
39 ***
40 ***     description:    Source code for DtTitleBox class.
41 ***     
42 ***-------------------------------------------------------------------*/
43
44
45 /*-------------------------------------------------------------
46 **      Include Files
47 */
48
49 #include <Xm/LabelG.h>
50 #if RiversVersion == _31
51 #include <Xm/ManagerP.h>
52 #include <Xm/GadgetP.h>
53 #endif /* RiversVersion == _31 */
54 #include <Xm/DrawP.h>
55 #include <Xm/XmP.h>
56 #include <Dt/TitleBoxP.h>
57 #include <Dt/MacrosP.h>
58 #include <Dt/DtMsgsP.h>
59 #include "DtWidgetI.h"
60
61 #include <Xm/XmPrivate.h>         /* _XmClearShadowType */
62
63
64
65 /********    Public Function Declarations    ********/
66
67 extern Widget _DtCreateTitleBox( 
68                         Widget parent,
69                         char *name,
70                         ArgList arglist,
71                         Cardinal argcount) ;
72 extern Widget _DtTitleBoxGetTitleArea( 
73                         Widget w) ;
74 extern Widget _DtTitleBoxGetWorkArea( 
75                         Widget w) ;
76
77 #define Max(x, y)    (((x) > (y)) ? (x) : (y))
78 /********    End Public Function Declarations    ********/
79
80 /********    Static Function Declarations    ********/
81
82 static void ConfigureChildren( 
83                         DtTitleBoxWidget manager) ;
84 static void GetSize( 
85                         DtTitleBoxWidget manager,
86                         Dimension ta_w,
87                         Dimension ta_h,
88                         Dimension wa_w,
89                         Dimension wa_h,
90                         Dimension *w,
91                         Dimension *h) ;
92 static void GetTitleString( 
93                         DtTitleBoxWidget manager,
94                         XrmQuark resource,
95                         XtArgVal *value) ;
96 static void ClassInitialize( void ) ;
97 static void ClassPartInitialize( 
98                         WidgetClass wc) ;
99 static void Initialize( 
100                         DtTitleBoxWidget request,
101                         DtTitleBoxWidget new) ;
102 static void Destroy( 
103                         DtTitleBoxWidget manager) ;
104 static void Resize( 
105                         DtTitleBoxWidget manager) ;
106 static void Redisplay( 
107                         DtTitleBoxWidget manager,
108                         XEvent *event,
109                         Region region) ;
110 static Boolean SetValues( 
111                         DtTitleBoxWidget current,
112                         DtTitleBoxWidget request,
113                         DtTitleBoxWidget new) ;
114 static XtGeometryResult QueryGeometry( 
115                         DtTitleBoxWidget manager,
116                         XtWidgetGeometry *request,
117                         XtWidgetGeometry *reply) ;
118 static XtGeometryResult GeometryManager( 
119                         Widget kid,
120                         XtWidgetGeometry *request,
121                         XtWidgetGeometry *reply) ;
122 static void ChangeManaged( 
123                         DtTitleBoxWidget manager) ;
124 static void InsertChild( 
125                         Widget child) ;
126 static void ConstraintInitialize( 
127                         Widget request,
128                         Widget new) ;
129
130 /********    End Static Function Declarations    ********/
131
132 \f
133 /*-------------------------------------------------------------
134 **      Forward Declarations
135 */
136
137 #define UNSPECIFIED_CHAR        255
138 #define UNSPECIFIED_DIMENSION   9999
139 #define MARGIN_DEFAULT          10
140
141 #define WARN_CHILD_TYPE         _DtMsgDialogBox_0000
142 #define WARN_SHADOW_TYPE        _DtMsgIcon_0005
143 #define WARN_TITLE_POSITION     _DtMsgTitleBox_0000
144 #define WARN_TITLE_ALIGNMENT    _DtMsgTitleBox_0001
145
146 #define MESSAGE2                _DtMsgTitleBox_0002
147 #define MESSAGE3                _DtMsgTitleBox_0003
148 #define MESSAGE4                _DtMsgTitleBox_0004
149
150 extern void _DtRegisterNewConverters( void ) ;
151
152
153 /*-------------------------------------------------------------
154 **      Translations and Actions
155 */
156
157
158 \f
159 /*-------------------------------------------------------------
160 **      Resource List
161 */
162
163 /*      Define offset macros.
164 */
165 #define TB_Offset(field) \
166         XtOffset (DtTitleBoxWidget, title_box.field)
167 #define TBC_Offset(field) \
168         XtOffset (DtTitleBoxConstraintPtr, title_box_constraint.field)
169
170 static XtResource resources[] = 
171 {
172         {
173                 XmNshadowThickness,
174                 XmCShadowThickness, XmRShort, sizeof (short),
175                 XtOffset (DtTitleBoxWidget, manager.shadow_thickness),
176                 XmRImmediate, (XtPointer) UNSPECIFIED_DIMENSION
177         },
178         {
179                 XmNmarginWidth,
180                 XmCMarginWidth, XmRHorizontalDimension, sizeof (Dimension),
181                 TB_Offset (margin_width),
182                 XmRImmediate, (XtPointer) UNSPECIFIED_DIMENSION
183         },
184         {
185                 XmNmarginHeight,
186                 XmCMarginHeight, XmRVerticalDimension, sizeof (Dimension),
187                 TB_Offset (margin_height),
188                 XmRImmediate, (XtPointer) UNSPECIFIED_DIMENSION
189         },
190         {
191                 XmNshadowType,
192                 XmCShadowType, XmRShadowType, sizeof (unsigned char),
193                 TB_Offset (shadow_type),
194                 XmRImmediate, (XtPointer) UNSPECIFIED_CHAR
195         },
196         {
197                 XmNtitleSpacing,
198                 XmCTitleSpacing, XmRHorizontalDimension, sizeof (Dimension),
199                 TB_Offset (title_spacing),
200                 XmRImmediate, (XtPointer) UNSPECIFIED_DIMENSION
201         },
202         {
203                 XmNtitlePosition,
204                 XmCTitlePosition, XmRTitlePosition, sizeof (unsigned char),
205                 TB_Offset (title_position), XmRImmediate, (XtPointer) XmTITLE_TOP
206         },
207         {
208                 XmNtitleAlignment,
209                 XmCAlignment, XmRAlignment, sizeof (unsigned char),
210                 TB_Offset (title_alignment),
211                 XmRImmediate, (XtPointer) XmALIGNMENT_BEGINNING
212         },
213         {
214                 XmNtitleString,
215                 XmCXmString, XmRXmString, sizeof (XmString),
216                 TB_Offset (title_string),
217                 XmRImmediate, (XtPointer) XmUNSPECIFIED_STRING
218         },
219         {
220                 XmNfontList,
221                 XmCFontList, XmRFontList, sizeof (XmFontList),
222                 TB_Offset (font_list), XmRImmediate, (XtPointer) NULL
223         }
224 };
225
226 /*      Synthetic Resources
227 */
228 static XmSyntheticResource syn_resources[] = 
229 {
230         {
231                 XmNtitleString, sizeof (XmString),
232                 TB_Offset (title_string),
233                 (XmExportProc) GetTitleString,
234                 (XmImportProc) NULL
235         },
236         {
237                 XmNmarginWidth, sizeof (Dimension),
238                 TB_Offset (margin_width),
239                 (XmExportProc) XmeFromHorizontalPixels,
240                 (XmImportProc) XmeToHorizontalPixels
241         },
242         {
243                 XmNmarginHeight, sizeof (Dimension),
244                 TB_Offset (margin_height),
245                 (XmExportProc) XmeFromVerticalPixels,
246                 (XmImportProc) XmeToVerticalPixels, 
247         }
248 };
249
250 /*      Constraint Resources
251 */
252 static XtResource constraints[] =
253 {
254         {
255                 XmNchildType,
256                 XmCChildType, XmRChildType, sizeof (unsigned char),
257                 TBC_Offset (child_type), XmRImmediate, (XtPointer) XmWORK_AREA
258         }
259 };
260
261 \f
262 /*-------------------------------------------------------------
263 **      Class Record
264 */
265 DtTitleBoxClassRec dtTitleBoxClassRec =
266 {
267 /*      Core Part
268 */
269         {       
270                 (WidgetClass) &xmManagerClassRec, /* superclass         */
271                 "DtTitleBox",                   /* class_name           */
272                 sizeof (DtTitleBoxRec), /* widget_size          */
273                 ClassInitialize,                /* class_initialize     */
274                 ClassPartInitialize,            /* class_part_initialize*/
275                 False,                          /* class_inited         */
276                 (XtInitProc) Initialize,        /* initialize           */
277                 NULL,                           /* initialize_hook      */
278                 XtInheritRealize,               /* realize              */
279                 NULL,                           /* actions              */
280                 0,                              /* num_actions          */
281                 resources,                      /* resources            */
282                 XtNumber (resources),           /* num_resources        */
283                 NULLQUARK,                      /* xrm_class            */
284                 True,                           /* compress_motion      */
285                 True,                           /* compress_exposure    */
286                 True,                           /* compress_enterleave  */
287                 False,                          /* visible_interest     */      
288                 (XtWidgetProc) Destroy,         /* destroy              */      
289                 (XtWidgetProc) Resize,          /* resize               */
290                 (XtExposeProc) Redisplay,       /* expose               */      
291                 (XtSetValuesFunc) SetValues,    /* set_values           */      
292                 NULL,                           /* set_values_hook      */
293                 XtInheritSetValuesAlmost,       /* set_values_almost    */
294                 NULL,                           /* get_values_hook      */
295                 NULL,                           /* accept_focus         */      
296                 XtVersion,                      /* version              */
297                 NULL,                           /* callback private     */
298                 XtInheritTranslations,          /* tm_table             */
299                 XtInheritQueryGeometry,         /* query_geometry       */
300                 NULL,                           /* display_accelerator  */
301                 NULL,                           /* extension            */
302         },
303
304 /*      Composite Part
305 */
306         {
307                 (XtGeometryHandler) GeometryManager,/* geometry_manager */
308                 (XtWidgetProc) ChangeManaged,   /* change_managed       */
309                 (XtWidgetProc) InsertChild,     /* insert_child         */
310                 XtInheritDeleteChild,           /* delete_child         */
311                 NULL,                           /* extension            */
312         },
313
314 /*      Composite Part
315 */
316         {
317                 constraints,                    /* constraint_resources */
318                 XtNumber (constraints),         /* num_constraint_resources */
319                 sizeof (DtTitleBoxConstraintRec), /* constraint_record  */
320                 (XtInitProc) ConstraintInitialize, /* constraint_initialize */
321                 NULL,                           /* constraint_destroy   */
322                 NULL,                           /* constraint_set_values */
323                 NULL,                           /* extension            */
324         },
325
326 /*      XmManager Part
327 */
328         {
329                 XtInheritTranslations,          /* default_translations */
330                 syn_resources,                  /* syn_resources        */
331                 XtNumber (syn_resources),       /* num_syn_resources    */
332                 NULL,                           /* syn_cont_resources   */
333                 0,                              /* num_syn_cont_resources */
334                 XmInheritParentProcess,         /* parent_process       */
335                 NULL,                           /* extension            */
336         },
337
338 /*      DtTitleBox Part
339 */
340         {
341                 NULL,                           /* extension            */
342         }
343 };
344
345 WidgetClass dtTitleBoxWidgetClass = (WidgetClass) &dtTitleBoxClassRec;
346
347
348 \f
349 /*-------------------------------------------------------------
350 **      Private Procs
351 **-------------------------------------------------------------
352 */
353
354 /*-------------------------------------------------------------------------
355 **      ConfigureChildren
356 **              Set positions and sizes of title and work area.
357 */
358 static void 
359 ConfigureChildren(
360         DtTitleBoxWidget manager )
361 {
362         Widget                  title_area = M_TitleArea (manager),
363                                 work_area = M_WorkArea (manager);
364         Position                ta_x = 0, ta_y = 0, wa_x = 0, wa_y = 0;
365         Dimension               ta_w = 0, ta_h = 0, ta_bw = 0,
366                                 wa_w = 0, wa_h = 0, wa_bw = 0,
367                                 w = M_Width (manager),
368                                 h = M_Height (manager),
369                                 s_t = M_ShadowThickness (manager),
370                                 m_w = M_MarginWidth (manager),
371                                 m_h = M_MarginHeight (manager),
372                                 ta_sp = M_TitleSpacing (manager);
373         Boolean                 title_top;
374         unsigned char           align = M_TitleAlignment (manager);
375         XtWidgetGeometry        ta_reply;
376
377         title_top = (M_TitlePosition (manager) == XmTITLE_TOP) ? True : False;
378
379 /*      Set position and size of title area.
380 */
381         if (title_area)
382         {
383                 XtQueryGeometry (title_area, NULL, &ta_reply);
384                 ta_w = ta_reply.width;
385                 ta_h = ta_reply.height;
386
387                 if (ta_w + 2U * ta_sp > (M_Width (manager) - 2U * ta_sp))
388                         ta_w = M_Width (manager) - 2 * ta_sp;
389                 if (ta_w == 0)
390                         ta_w = 10;
391                 if (ta_h == 0)
392                         ta_h = 10;
393
394                 if (align == XmALIGNMENT_BEGINNING)
395                         ta_x = ta_sp;
396                 else if (align == XmALIGNMENT_END)
397                         ta_x = w - ta_sp - ta_w;
398                 else
399                         ta_x = (w - ta_w) / 2U;
400
401                 ta_y = (title_top) ? 0 : h - ta_h;
402
403                 ta_bw = P_BorderWidth (title_area);
404                 XmeConfigureObject (title_area, ta_x, ta_y, ta_w, ta_h, ta_bw);
405         }
406
407 /*      Set position and size of work area.
408 */
409         if (work_area)
410         {
411                 wa_x = m_w + s_t;
412                 wa_y = (title_top) ? Max (s_t, ta_h) + m_h : s_t + m_h;
413                 wa_w = w - 2 * (m_w + s_t);
414                 if (wa_w == 0)
415                         wa_w = 10;
416                 wa_h = h - Max (s_t, ta_h) - s_t - 2 * m_h;
417                 if (wa_h == 0)
418                         wa_h = 10;
419                 wa_bw = P_BorderWidth (work_area);
420                 XmeConfigureObject (work_area,
421                                         wa_x, wa_y, wa_w, wa_h, wa_bw);
422         }
423 }
424
425
426 \f
427 /*-------------------------------------------------------------------------
428 **      GetSize
429 **              Calculate desired size based on children.
430 */
431 static void 
432 GetSize(
433         DtTitleBoxWidget manager,
434         Dimension ta_w,
435         Dimension ta_h,
436         Dimension wa_w,
437         Dimension wa_h,
438         Dimension *w,
439         Dimension *h )
440 {
441         Widget                  title_area = M_TitleArea (manager),
442                                 work_area = M_WorkArea (manager);
443         XtWidgetGeometry        ta_reply, wa_reply;
444         Dimension               s_t = M_ShadowThickness (manager),
445                                 m_w = M_MarginWidth (manager),
446                                 m_h = M_MarginHeight (manager),
447                                 ta_sp = M_TitleSpacing (manager);
448
449
450 /*      Optimize title area change if possible.
451 */
452         if (work_area && (wa_w == 0) && (wa_h == 0))
453         {
454                 if ((ta_w != 0) && (ta_h == 0))
455                 {
456                         if ((M_Width (manager) >=
457                                 M_Width (work_area) + (2U * ta_sp)) &&
458                             (M_Height (manager) >= Max (ta_h, s_t) +
459                                 M_Height (work_area) + s_t + (2U * m_h)))
460                         {
461                                 wa_w = M_Width (work_area);
462                                 wa_h = M_Height (work_area);
463                         }
464                 }
465
466                 if ((wa_w == 0) && (wa_h == 0))
467                 {       
468                         XtQueryGeometry (work_area, NULL, &wa_reply);
469                         wa_w = wa_reply.width;
470                         wa_h = wa_reply.height;
471                 }
472         }
473         if (title_area && (ta_w == 0) && (ta_h == 0))
474         {
475                 XtQueryGeometry (title_area, NULL, &ta_reply);
476                 ta_w = ta_reply.width;
477                 ta_h = ta_reply.height;
478         }
479
480         *w = Max (wa_w + (2U * (m_w + s_t)), ta_w + (2U * ta_sp));
481         if (*w == 0)
482                 *w = 10;
483         *h = Max (s_t, ta_h) + wa_h + (2 * m_h) + s_t;
484         if (*h == 0)
485                 *h = 10;
486 }
487
488
489 \f
490 /*-------------------------------------------------------------
491 **      GetTitleString
492 **              Get string from title label.
493 */
494 static void 
495 GetTitleString(
496         DtTitleBoxWidget manager,
497         XrmQuark resource,
498         XtArgVal *value )
499 {
500         Arg             al[10];         /*  arg list            */
501         register int    ac;             /*  arg count           */
502         Widget          title_area = M_TitleArea (manager);
503         XmString        string = NULL;
504
505         if (title_area)
506         {
507                 ac = 0;
508                 XtSetArg (al[ac], XmNlabelString, &string);  ac++;
509                 XtGetValues (title_area, al, ac);
510         }
511
512         *value = (XtArgVal) string;
513 }
514
515
516 \f
517 /*-------------------------------------------------------------
518 **      Action Procs
519 **-------------------------------------------------------------
520 */
521
522
523 /*-------------------------------------------------------------
524 **      Core Procs
525 **-------------------------------------------------------------
526 */
527
528 /*-------------------------------------------------------------------------
529 **      ClassInitialize
530 **              Initialize widget class.
531 */
532 static void 
533 ClassInitialize( void )
534 {
535         _DtRegisterNewConverters ();
536 }
537
538
539 /*-------------------------------------------------------------------------
540 **      ClassPartInitialize
541 **              Initialize widget class data.
542 */
543 static void 
544 ClassPartInitialize(
545         WidgetClass wc )
546 {
547 }
548
549
550 \f
551 /*-------------------------------------------------------------
552 **      Initialize
553 **              Initialize a new widget instance.
554 */
555 static void 
556 Initialize(
557         DtTitleBoxWidget request,
558         DtTitleBoxWidget new )
559 {
560         Arg             al[10];         /*  arg list            */
561         register int    ac;             /*  arg count           */
562         Widget          title = NULL;
563         XmString        title_string = NULL;
564
565 /*      Check for unspecified dimensions.
566 */
567         if (M_MarginWidth (request) == UNSPECIFIED_DIMENSION)
568                 M_MarginWidth (new) = MARGIN_DEFAULT;
569         if (M_MarginHeight (request) == UNSPECIFIED_DIMENSION)
570                 M_MarginHeight (new) = MARGIN_DEFAULT;
571         if (M_TitleSpacing (request) == UNSPECIFIED_DIMENSION)
572                 M_TitleSpacing (new) = UNSPECIFIED_DIMENSION;
573         if (M_ShadowThickness (new) == UNSPECIFIED_DIMENSION)
574         {
575                 if (XtIsShell (XtParent (new)))
576                         M_ShadowThickness (new) = 1;
577                 else
578                         M_ShadowThickness (new) = 2;
579         }
580
581 /*      Validate shadow type.
582 */
583         if (M_ShadowType (new) == UNSPECIFIED_CHAR)
584         {
585                 if (XtIsShell (XtParent (new)))
586                         M_ShadowType (new) = XmSHADOW_OUT;
587                 else
588                         M_ShadowType (new) = XmSHADOW_ETCHED_IN;
589         }
590         else if (M_ShadowType (new) != XmSHADOW_IN &&
591                  M_ShadowType (new) != XmSHADOW_OUT &&
592                  M_ShadowType (new) != XmSHADOW_ETCHED_IN &&
593                  M_ShadowType (new) != XmSHADOW_ETCHED_OUT)
594         {
595               XmeWarning ((Widget)new, WARN_SHADOW_TYPE);
596         }
597
598 /*      Validate title position.
599 */
600         if (M_TitlePosition (new) != XmTITLE_TOP &&
601             M_TitlePosition (new) != XmTITLE_BOTTOM)
602         {
603                 XmeWarning ((Widget)new, WARN_TITLE_POSITION);
604         }
605
606 /*      Validate title alignment.
607 */
608         if (M_TitleAlignment (new) != XmALIGNMENT_BEGINNING &&
609             M_TitleAlignment (new) != XmALIGNMENT_CENTER &&
610             M_TitleAlignment (new) != XmALIGNMENT_END)
611         {
612                 XmeWarning ((Widget)new, WARN_TITLE_ALIGNMENT);
613         }
614
615 /*      Check width and height.
616 */
617         if (M_Width (new) == 0)
618         {
619                 M_Width (new) = 2 * (M_ShadowThickness (new) +
620                                         M_MarginWidth (new));
621                 if (M_Width (new) == 0)
622                         M_Width (new) = 10;
623         }
624         if (M_Height (new) == 0)
625         {
626                 M_Height (new) = 2 * (M_ShadowThickness (new) +
627                                         M_MarginHeight (new));
628                 if (M_Height (new) == 0)
629                         M_Height (new) = 10;
630         }
631
632         M_OldWidth (new) = M_Width (new);
633         M_OldHeight (new) = M_Height (new);
634         M_OldShadowThickness (new) = M_ShadowThickness (new);
635
636
637         M_WorkArea (new) = NULL;
638
639 /*      Create title_area unless title explicitly set to null;
640 *       use name if unspecified.
641 */
642         if (! M_TitleString (new))
643         {
644                 M_TitleArea (new) = NULL;
645                 return;
646         }
647
648         if (M_TitleString (new) == XmUNSPECIFIED_STRING && M_Name (new))
649         {
650                 M_TitleString (new) = XmStringCreateLocalized(M_Name (new));
651                 title_string = M_TitleString (new);
652         }
653         ac = 0;
654         XtSetArg (al[ac], XmNchildType, XmTITLE_AREA);  ac++;
655         XtSetArg (al[ac], XmNmarginWidth, 2);  ac++;
656         XtSetArg (al[ac], XmNmarginHeight, 0);  ac++;
657         XtSetArg (al[ac], XmNshadowThickness, 0);  ac++;
658         XtSetArg (al[ac], XmNhighlightThickness, 0);  ac++;
659         XtSetArg (al[ac], XmNlabelString, M_TitleString (new));  ac++;
660         if (M_FontList (new))
661         {
662                 XtSetArg (al[ac], XmNfontList, M_FontList (new));
663                 ac++;
664         }
665         title = XmCreateLabelGadget ((Widget)new, "title", al, ac);
666         M_TitleArea (new) = title;
667         XtManageChild (title);
668
669         if (M_TitleSpacing (new) == UNSPECIFIED_DIMENSION)
670                 M_TitleSpacing (new) =
671                         Max (P_Height (title)/2U, M_ShadowThickness (new));
672
673         M_TitleString (new) = XmUNSPECIFIED_STRING;
674         M_FontList (new) = NULL;
675         if (title_string != NULL)
676                 XmStringFree (title_string);
677 }
678
679
680 /*-------------------------------------------------------------
681 **      Destroy
682 **              Release resources allocated for widget instance.
683 */
684 static void 
685 Destroy(
686         DtTitleBoxWidget manager )
687 {
688         /*      Superclass does all the work so far.
689         */
690 }
691
692
693 \f
694 /*-------------------------------------------------------------
695 **      Resize
696 **              Update size of children.
697 */
698 static void 
699 Resize(
700         DtTitleBoxWidget manager )
701 {
702         Widget          title_area = M_TitleArea (manager);
703         Dimension       s_t = M_OldShadowThickness (manager),
704                         w = M_OldWidth (manager),
705                         h = M_OldHeight (manager);
706         Position        y;
707
708 /*      Clear shadow and save shadow data.
709 */
710         if (XtIsRealized ((Widget)manager))
711         {
712                 _XmClearShadowType ((Widget)manager, w, h, s_t, 0);
713
714                 if ((M_TitlePosition (manager) == XmTITLE_BOTTOM) &&
715                     (M_Height (manager) > h))
716                 {
717                         y = h - P_Height (title_area);
718                         XClearArea (XtDisplay (manager), XtWindow (manager),
719                                         0, y, M_Width (manager),
720                                         M_Height (manager) - y, False);
721                 }                       
722         }
723                                 
724         M_OldWidth (manager) = M_Width (manager);
725         M_OldHeight (manager) = M_Height (manager);
726         M_OldShadowThickness (manager) = M_ShadowThickness (manager);
727
728         ConfigureChildren (manager);
729
730 /*      Draw shadow and title.
731 */
732         if (XtIsRealized ((Widget)manager))
733                 Redisplay (manager, NULL, NULL);
734 }
735
736
737 \f
738 /*-------------------------------------------------------------
739 **      Redisplay
740 **              Redisplay widget.
741 */
742 static void 
743 Redisplay(
744         DtTitleBoxWidget manager,
745         XEvent *event,
746         Region region )
747 {
748         Widget          title_area = M_TitleArea (manager),
749                         work_area = M_WorkArea (manager);
750         Position        title_x = M_X (title_area),
751                         title_y = M_Y (title_area);
752         Dimension       title_width = M_Width (title_area),
753                         title_height = M_Height (title_area);
754
755         Display *       d =             XtDisplay (manager);
756         Dimension       w =             M_Width (manager),
757                         h =             M_Height (manager),
758                         s_t =           M_ShadowThickness (manager);
759
760         Position        x = 0,
761                         y = title_height / 2 - s_t / 2;
762
763 /*      Redisplay work area.
764 */
765         if (work_area && XmIsGadget (work_area) && XtIsManaged (work_area))
766         {
767                 XtExposeProc expose;
768                 _DtProcessLock();
769                 expose = XtCoreProc(work_area, expose);
770                 _DtProcessUnlock();
771
772                 (*expose) (work_area, event, region);
773         }
774
775 /*      Draw shadow.
776 */
777         if (M_ShadowThickness (manager) > 0)
778         {
779                 h -= y;
780                 if (M_TitlePosition (manager) == XmTITLE_BOTTOM)
781                         y = 0;
782                 XmeDrawShadows(d, XtWindow(manager),
783                                M_TopShadowGC(manager),
784                                M_BottomShadowGC(manager),
785                                x, y, w, h, s_t, M_ShadowType(manager));
786         }
787
788 /*      Redisplay title area.
789 */      
790         if (title_area && XtIsManaged (title_area))
791         {               
792                 XClearArea (d, XtWindow (manager), title_x, title_y,
793                                 title_width, title_height, False);
794                 if (XmIsGadget (title_area))
795                 {
796                         XtExposeProc expose;
797                         _DtProcessLock();
798                         expose = XtCoreProc(title_area, expose);
799                         _DtProcessUnlock();
800
801                         (*expose) (title_area, event, region);
802                 }
803         }
804
805 }
806
807
808 \f
809 /*-------------------------------------------------------------
810 **      SetValues
811 **              Handle changes in resource data.
812 */
813
814
815 static Boolean 
816 SetValues(
817         DtTitleBoxWidget current,
818         DtTitleBoxWidget request,
819         DtTitleBoxWidget new )
820 {
821         Widget          title = M_TitleArea (new);
822         Boolean         redisplay_flag = False,
823                         new_title = False,
824                         new_font = False;
825         Arg             al[10];         /*  arg list            */
826         register int    ac;             /*  arg count           */
827
828 /*      Validate title position.
829 */
830         if (M_TitlePosition (new) != M_TitlePosition (current) &&
831             M_TitlePosition (new) != XmTITLE_TOP &&
832             M_TitlePosition (new) != XmTITLE_BOTTOM)
833         {
834                 XmeWarning ((Widget)new, WARN_TITLE_POSITION);
835                 M_TitlePosition (new) = M_TitlePosition (current);
836         }
837
838 /*      Validate title alignment.
839 */
840         if (M_TitleAlignment (new) != M_TitleAlignment (current) &&
841             M_TitleAlignment (new) != XmALIGNMENT_BEGINNING &&
842             M_TitleAlignment (new) != XmALIGNMENT_CENTER &&
843             M_TitleAlignment (new) != XmALIGNMENT_END)
844         {
845                 XmeWarning ((Widget)new, WARN_TITLE_ALIGNMENT);
846                 M_TitleAlignment (new) = M_TitleAlignment (current);
847         }
848
849 /*      Validate shadow type.
850 */
851         if (M_ShadowType (new) != M_ShadowThickness (current) &&
852             M_ShadowType (new) != XmSHADOW_IN &&
853             M_ShadowType (new) != XmSHADOW_OUT &&
854             M_ShadowType (new) != XmSHADOW_ETCHED_IN &&
855             M_ShadowType (new) != XmSHADOW_ETCHED_OUT)
856         {
857                 XmeWarning ((Widget)new, WARN_SHADOW_TYPE);
858                 M_ShadowType (new) = M_ShadowThickness (current);
859         }
860
861 /*      Check for redisplay; query and update kids if no resize.
862 */
863         if (M_MarginWidth (new) != M_MarginWidth (current) ||
864             M_MarginHeight (new) != M_MarginHeight (current) ||
865             M_ShadowThickness (new) != M_ShadowThickness (current))
866         {
867                 redisplay_flag = True;
868                 if (M_Width (new) == M_Width (current) &&
869                     M_Height (new) == M_Height (current))
870                 {
871                         GetSize (new, 0, 0, 0, 0,
872                                 &(M_Width (new)), &(M_Height (new)));
873                         ConfigureChildren (new);
874                 }
875         }
876
877         else if (M_TitleSpacing (new) != M_TitleSpacing (current) ||
878                  M_TitlePosition (new) != M_TitlePosition (current) ||
879                  M_TitleAlignment (new) != M_TitleAlignment (current))
880         {
881                 redisplay_flag = True;
882                 ConfigureChildren (new);
883         }
884         else if (M_ShadowType (new) != M_ShadowThickness (current))
885         {
886                 redisplay_flag = True;
887         }
888
889 /*      Update title if string or font changed.
890 */
891         ac = 0;
892         if (M_TitleString (current) != M_TitleString (new))
893         {
894                 new_title = True;
895                 XtSetArg (al[ac], XmNlabelString, M_TitleString (new));  ac++;
896         }
897         if (M_FontList (current) != M_FontList (new))
898         {
899                 new_font = True;
900                 XtSetArg (al[ac], XmNfontList, M_FontList (new));
901                 ac++;
902         }
903         if (ac && title)
904         {
905                 XtSetValues (title, al, ac);
906                 if (new_title)
907                         M_TitleString (new) = XmUNSPECIFIED_STRING;
908                 if (new_font)
909                         M_FontList (new) = NULL;
910                 redisplay_flag = True;
911         }
912
913         return (redisplay_flag);
914 }
915
916
917 \f
918 /*-------------------------------------------------------------
919 **      QueryGeometry
920 **              Handle query geometry request.
921 */
922 static XtGeometryResult 
923 QueryGeometry(
924         DtTitleBoxWidget manager,
925         XtWidgetGeometry *request,
926         XtWidgetGeometry *reply )
927 {
928         Dimension       w = M_Width (manager),
929                         h = M_Height (manager),
930                         new_w = 0,
931                         new_h = 0;
932         Boolean         width_req = request->request_mode & CWWidth,
933                         height_req = request->request_mode & CWHeight;
934
935 /*      Compute preferred size if preferred width or height requested.
936 */
937         if (width_req || height_req)
938                 GetSize (manager, 0, 0, 0, 0, &new_w, &new_h);
939
940 /*      Load reply.
941 */
942         reply->request_mode = request->request_mode;
943         reply->x = request->x;
944         reply->y = request->y;
945         reply->width = (width_req) ? new_w : request->width;
946         reply->height = (height_req) ? new_h : request->height;
947         reply->border_width = request->border_width;
948
949 /*      If no change return no; otherwise yes.
950 */
951         if ((!width_req || (width_req && w == new_w)) &&
952             (!height_req || (height_req && h == new_h)))
953                 return (XtGeometryNo);
954         else
955                 return (XtGeometryYes);         
956 }
957
958
959 \f
960 /*-------------------------------------------------------------
961 **      Composite Procs
962 **-------------------------------------------------------------
963 */
964
965 /*-------------------------------------------------------------
966 **      GeometryManager
967 **              Handle geometry request from title area or work area.
968 */
969 static XtGeometryResult 
970 GeometryManager(
971         Widget kid,
972         XtWidgetGeometry *request,
973         XtWidgetGeometry *reply )
974 {
975         DtTitleBoxWidget        manager = (DtTitleBoxWidget) XtParent (kid);
976         Widget          title_area = M_TitleArea (manager);
977         Dimension       ta_w = 0, ta_h = 0, ta_bw = 0,
978                         wa_w = 0, wa_h = 0,
979                         w = M_Width (manager),
980                         h = M_Height (manager);
981         Boolean         query_only = request->request_mode & XtCWQueryOnly,
982                         x_req = request->request_mode & CWX,
983                         y_req = request->request_mode & CWY,
984                         width_req = request->request_mode & CWWidth,
985                         height_req = request->request_mode & CWHeight,
986                         bw_req = request->request_mode & CWBorderWidth,
987                         almost = False;
988         XtGeometryResult        result, parent_result;
989         XtWidgetGeometry        parent_req, parent_reply;
990         
991
992 /*      Check for width, height, and borderwidth requests.
993 */
994         if (!width_req && !height_req)
995         {
996                 if (x_req || y_req)
997                         return (XtGeometryNo);
998                 else
999                         return (XtGeometryYes);
1000         }
1001         else
1002         {
1003                 if (x_req || y_req)
1004                         almost = True;
1005         }
1006
1007 /*      Compute desired size.
1008 */
1009         if (kid == title_area)
1010         {
1011                 ta_w = (width_req) ? request->width : P_Width (kid);
1012                 ta_h = (height_req) ? request->height : P_Height (kid);
1013                 ta_bw = (bw_req) ? request->border_width : P_BorderWidth (kid);
1014         }
1015         else
1016         {
1017                 wa_w = (width_req) ? request->width : P_Width (kid);
1018                 wa_h = (height_req) ? request->height : P_Height (kid);
1019         }
1020
1021         GetSize (manager, ta_w, ta_h, wa_w, wa_h, &w, &h);
1022
1023 /*      Request change from parent if necessary.
1024 */
1025         if (w != M_Width (manager) || h != M_Height (manager))
1026         {
1027                 parent_req.request_mode = CWWidth | CWHeight;
1028                 parent_req.width = w;
1029                 parent_req.height = h;
1030                 if (almost || query_only)
1031                         parent_req.request_mode |= XtCWQueryOnly;
1032                 parent_result =
1033                         XtMakeGeometryRequest ((Widget)manager, &parent_req,
1034                                         &parent_reply);
1035                 if (kid == (Widget) title_area)
1036                         parent_result = XtGeometryYes;
1037         }
1038         else
1039                 parent_result = XtGeometryYes;
1040
1041 /*      Reply to kid based on reply from parent.
1042 */
1043         switch ((int) parent_result)
1044         {
1045                 case XtGeometryYes:
1046                         if (query_only)
1047                                 result = XtGeometryYes;
1048                         else if (!almost)
1049                         {
1050                                 XtWidgetProc resize;
1051                                 if (kid == title_area)
1052                                       XmeConfigureObject (title_area,
1053                                              title_area->core.x,
1054                                              title_area->core.y,
1055                                              ta_w, ta_h, ta_bw);
1056                                 _DtProcessLock();
1057                                 resize = XtCoreProc(XtParent(kid), resize);
1058                                 _DtProcessUnlock();
1059                                 (*resize) (XtParent (kid));
1060                                 result = XtGeometryDone;
1061                         }
1062                         else
1063                         {
1064                                 result = XtGeometryNo;
1065                         }
1066                         break;
1067                 case XtGeometryAlmost:
1068                 case XtGeometryNo:
1069                         result = XtGeometryNo;
1070                         break;
1071         }
1072
1073         return (result);
1074 }
1075
1076
1077 /*-------------------------------------------------------------
1078 **      ChangeManaged
1079 **              Handle change in set of managed children.
1080 */
1081 static void 
1082 ChangeManaged(
1083         DtTitleBoxWidget manager )
1084 {
1085         Dimension       w = M_Width (manager),
1086                         h = M_Height (manager);
1087
1088 /*      Compute desired size.
1089 */
1090         GetSize (manager, 0, 0, 0, 0, &w, &h);
1091
1092 /*      Try to change size to fit children
1093 */
1094         if (w != M_Width (manager) || h != M_Height (manager))
1095         {
1096                 switch (XtMakeResizeRequest ((Widget) manager, w, h, &w, &h))
1097                 {
1098                         case XtGeometryAlmost:
1099                                 XtMakeResizeRequest ((Widget) manager, w, h,
1100                                         NULL, NULL);
1101                         case XtGeometryYes:
1102                         case XtGeometryNo:
1103                         default:
1104                                 break;
1105                 }
1106         }
1107         
1108 /*      Set positions and sizes of children.
1109 */
1110         ConfigureChildren (manager);
1111         XmeNavigChangeManaged ((Widget)manager);
1112 }
1113
1114
1115 \f
1116 /*-------------------------------------------------------------
1117 **      InsertChild
1118 **              Add a child.
1119 */
1120 static void 
1121 InsertChild(
1122         Widget child )
1123 {
1124         DtTitleBoxConstraint    constraint = (DtTitleBoxConstraint)
1125                                         M_TitleBoxConstraint (child);
1126         DtTitleBoxWidget        w;
1127         XmManagerWidgetClass    mc = (XmManagerWidgetClass)
1128                                                 xmManagerWidgetClass;
1129         XtWidgetProc            insert_child;
1130
1131         _DtProcessLock();
1132         insert_child = mc->composite_class.insert_child;
1133         _DtProcessUnlock();
1134         (* insert_child) (child);
1135
1136         w = (DtTitleBoxWidget) XtParent (child);
1137         
1138         if (constraint->child_type == XmWORK_AREA)
1139         {
1140                 if (! M_WorkArea (w))
1141                 {
1142                         M_WorkArea (w) = child;
1143                 }
1144         }
1145         else if (constraint->child_type == XmTITLE_AREA)
1146         {
1147                 if (! M_TitleArea (w))
1148                 {
1149                         M_TitleArea (w) = child;
1150                 }
1151         }
1152 }
1153
1154
1155 \f 
1156 /*-------------------------------------------------------------
1157 **      Constraint Procs
1158 **-------------------------------------------------------------
1159 */
1160 /*-------------------------------------------------------------
1161 **      ConstraintInitialize
1162 **              Add a child.
1163 */
1164 static void 
1165 ConstraintInitialize(
1166         Widget request,
1167         Widget new )
1168 {
1169         DtTitleBoxWidget        manager = (DtTitleBoxWidget) XtParent (new);
1170         DtTitleBoxConstraint    constraint = M_TitleBoxConstraint (new);
1171
1172 /*      Validate child type.
1173 */
1174         if (constraint->child_type != XmWORK_AREA &&
1175             constraint->child_type != XmTITLE_AREA)
1176         {
1177                 XmeWarning (new, WARN_CHILD_TYPE);
1178                 if (! M_WorkArea (manager))
1179                 {
1180                         constraint->child_type = XmWORK_AREA;
1181                 }
1182                 else if (! M_TitleArea (manager))
1183                 {
1184                         constraint->child_type = XmTITLE_AREA;
1185                 }
1186         }
1187 }
1188
1189
1190 /*-------------------------------------------------------------
1191 **      Manager Procs
1192 **-------------------------------------------------------------
1193 */
1194 /*      All inherited from superclass.
1195 */
1196
1197
1198 \f
1199 /*-------------------------------------------------------------
1200 **      Public Entry Points
1201 **-------------------------------------------------------------
1202 */
1203
1204 /*-------------------------------------------------------------
1205 **      _DtCreateTitleBox
1206 **              Create a new DtTitleBox instance.
1207 **-------------------------------------------------------------
1208 */
1209 Widget 
1210 _DtCreateTitleBox(
1211         Widget parent,
1212         char *name,
1213         ArgList arglist,
1214         Cardinal argcount )
1215 {
1216         return (XtCreateWidget (name, dtTitleBoxWidgetClass, 
1217                         parent, arglist, argcount));
1218 }
1219
1220
1221 /*-------------------------------------------------------------
1222 **      _DtTitleBoxGetTitleArea
1223 **              Return TitleBox title area;
1224 **-------------------------------------------------------------
1225 */
1226 Widget 
1227 _DtTitleBoxGetTitleArea(
1228         Widget w )
1229 {
1230         DtTitleBoxWidget        mgr =   (DtTitleBoxWidget) w;
1231         Widget                  rtn_w = M_TitleArea (mgr);
1232
1233         return (rtn_w);
1234 }
1235
1236
1237 /*-------------------------------------------------------------
1238 **      _DtTitleBoxGetWorkArea
1239 **              Return TitleBox work area;
1240 **-------------------------------------------------------------
1241 */
1242 Widget 
1243 _DtTitleBoxGetWorkArea(
1244         Widget w )
1245 {
1246         DtTitleBoxWidget        mgr =   (DtTitleBoxWidget) w;
1247         Widget                  rtn_w = M_WorkArea (mgr);
1248
1249         return (rtn_w);
1250 }