dtcalc: change from obsoleted MAXFLOAT to FLT_MAX from std C
[oweals/cde.git] / cde / lib / DtWidget / DialogBox.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: DialogBox.c /main/9 1996/05/14 15:26:42 drk $
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:           DialogBox.c
37 ***
38 ***     project:        Motif Widgets
39 ***
40 ***     description:    Source code for DtDialogBox class.
41 ***
42 ***-------------------------------------------------------------------*/
43
44
45 /*-------------------------------------------------------------
46 **      Include Files
47 */
48
49 #include <stdio.h>
50 #include <Xm/DialogS.h>
51 #include <Xm/PushBG.h>
52 #include <Xm/SeparatoG.h>
53 #include <Dt/DialogBoxP.h>
54 #include <Dt/MacrosP.h>
55 #include <Dt/DtMsgsP.h>
56 #include "DtWidgetI.h"
57
58 /*
59  * Private functions borrowed from Motif.
60  */
61 extern void _XmSetThickness(Widget widget, int offset, XrmValue *value);
62
63 /*-------------------------------------------------------------
64 **      Public Interface
65 **-------------------------------------------------------------
66 */
67
68 extern Widget _DtCreateDialogBox( 
69                         Widget parent,
70                         char *name,
71                         ArgList arglist,
72                         Cardinal argcount) ;
73 extern Widget __DtCreateDialogBoxDialog( 
74                         Widget ds_p,
75                         String name,
76                         ArgList db_args,
77                         Cardinal db_n) ;
78 extern Widget _DtDialogBoxGetButton( 
79                         Widget w,
80                         Cardinal pos) ;
81 extern Widget _DtDialogBoxGetWorkArea( 
82                         Widget w) ;
83
84 #define Max(x, y)    (((x) > (y)) ? (x) : (y))
85
86 /********    Static Function Declarations    ********/
87
88 static void ClassInitialize( void ) ;
89 static void ClassPartInitialize( 
90                         WidgetClass wc) ;
91 static void Initialize( 
92                         Widget request_w,
93                         Widget new_w) ;
94 static void Destroy( 
95                         Widget w) ;
96 static Boolean SetValues( 
97                         Widget current_w,
98                         Widget request_w,
99                         Widget new_w) ;
100 static void ChangeManaged( 
101                         Widget manager) ;
102 static void InsertChild( 
103                         Widget child) ;
104 static void DeleteChild( 
105                         Widget child) ;
106 static void ConstraintInitialize( 
107                         Widget request,
108                         Widget new) ;
109 static void GetSize( 
110                         Widget manager,
111                         Dimension wa_w,
112                         Dimension wa_h,
113                         Dimension bp_w,
114                         Dimension bp_h,
115                         Dimension *w,
116                         Dimension *h) ;
117 static void CreateChildren( 
118                         DtDialogBoxWidget new,
119                         Widget top_widget,
120                         Widget bottom_widget) ;
121 static void ButtonCallback( 
122                         Widget g,
123                         XtPointer client_data,
124                         XtPointer call_data) ;
125
126 /********    End Static Function Declarations    ********/
127
128 \f
129 /*-------------------------------------------------------------
130 **      Forward Declarations
131 */
132
133 #define OFFSET          6
134 #define CENTER_POS      50
135 #define LEFT_POS        50
136
137 #define WARN_CHILD_TYPE         _DtMsgDialogBox_0000
138 #define WARN_BUTTON_CHILD       _DtMsgDialogBox_0001
139
140 extern void     _DtRegisterNewConverters ();
141
142
143 /*-------------------------------------------------------------
144 **      Translations and Actions
145 */
146
147
148 \f
149 /*-------------------------------------------------------------
150 **      Resource List
151 */
152
153 /*      Define offset macros.
154 */
155 #define DB_Offset(field) \
156         XtOffset (DtDialogBoxWidget, dialog_box.field)
157 #define DBC_Offset(field) \
158         XtOffset (DtDialogBoxConstraintPtr, dialog_box_constraint.field)
159
160 /*      Core Resources.
161 */
162 static XtResource resources[] = 
163 {
164         {
165                 XmNminimizeButtons,
166                 XmCMinimizeButtons, XmRBoolean, sizeof (Boolean),
167                 DB_Offset (minimize_buttons), XmRImmediate, (XtPointer) False
168         },
169         {
170                 XmNbuttonCount,
171                 XmCButtonCount, XmRCardinal, sizeof (Cardinal),
172                 DB_Offset (button_count), XmRImmediate, (XtPointer) 4
173         },
174         {
175                 XmNbuttonLabelStrings,
176                 XmCButtonLabelStrings, XmRXmStringTable, sizeof (XtPointer),
177                 DB_Offset (button_label_strings), XmRStringTable, NULL
178         },
179         {
180                 XmNcallback,
181                 XmCCallback, XmRCallback, sizeof (XtCallbackList),
182                 DB_Offset (callback), XmRImmediate, (XtPointer) NULL
183         },
184         {
185                 XmNshadowThickness,
186                 XmCShadowThickness, XmRHorizontalDimension, sizeof(Dimension),
187                 XtOffsetOf (struct _XmManagerRec, manager.shadow_thickness),
188                 XmRCallProc, (XtPointer) _XmSetThickness
189         }
190 };
191
192 /*      Constraint Resources
193 */
194 static XtResource constraints[] =
195 {
196         {
197                 XmNchildType,
198                 XmCChildType, XmRChildType, sizeof (unsigned char),
199                 DBC_Offset (child_type), XmRImmediate, (XtPointer) XmWORK_AREA
200         }
201 };
202
203 #undef  DB_Offset
204 #undef  DBC_Offset
205
206
207 \f
208 /*-------------------------------------------------------------
209 **      Class Record
210 */
211 DtDialogBoxClassRec dtDialogBoxClassRec =
212 {
213 /*      Core Part
214 */
215         {       
216                 (WidgetClass) &xmFormClassRec,  /* superclass   */
217                 "DtDialogBox",                  /* class_name           */
218                 sizeof (DtDialogBoxRec),        /* widget_size          */
219                 ClassInitialize,                /* class_initialize     */
220                 ClassPartInitialize,            /* class_part_initialize*/
221                 False,                          /* class_inited         */
222                 (XtInitProc) Initialize,        /* initialize           */
223                 NULL,                           /* initialize_hook      */
224                 XtInheritRealize,               /* realize              */
225                 NULL,                           /* actions              */
226                 0,                              /* num_actions          */
227                 resources,                      /* resources            */
228                 XtNumber (resources),           /* num_resources        */
229                 NULLQUARK,                      /* xrm_class            */
230                 True,                           /* compress_motion      */
231                 False,                          /* compress_exposure    */
232                 True,                           /* compress_enterleave  */
233                 False,                          /* visible_interest     */      
234                 Destroy,                        /* destroy              */      
235                 XtInheritResize,                /* resize               */
236                 XtInheritExpose,                /* expose               */      
237                 (XtSetValuesFunc) SetValues,    /* set_values           */      
238                 NULL,                           /* set_values_hook      */
239                 XtInheritSetValuesAlmost,       /* set_values_almost    */
240                 NULL,                           /* get_values_hook      */
241                 NULL,                           /* accept_focus         */      
242                 XtVersion,                      /* version              */
243                 NULL,                           /* callback private     */
244                 XtInheritTranslations,          /* tm_table             */
245                 XtInheritQueryGeometry,         /* query_geometry       */
246                 NULL,                           /* display_accelerator  */
247                 NULL,                           /* extension            */
248         },
249
250 /*      Composite Part
251 */
252         {
253                 XtInheritGeometryManager,       /* geometry_manager     */
254                 XtInheritChangeManaged,         /* change_managed       */
255                 InsertChild,                    /* insert_child         */
256                 DeleteChild,                    /* delete_child         */
257                 NULL,                           /* extension            */
258         },
259
260 /*      Constraint Part
261 */
262         {
263                 constraints,                    /* constraint_resources */
264                 XtNumber (constraints),         /* num_constraint_resources */
265                 sizeof (DtDialogBoxConstraintRec),/* constraint_record  */
266                 (XtInitProc) ConstraintInitialize,/* constraint_initialize */
267                 NULL,                           /* constraint_destroy   */
268                 NULL,                           /* constraint_set_values */
269                 NULL,                           /* extension            */
270         },
271
272 /*      XmManager Part
273 */
274         {
275                 XtInheritTranslations,          /* default_translations */
276                 NULL,                           /* get_resources        */
277                 0,                              /* num_get_resources    */
278                 NULL,                           /* get_cont_resources   */
279                 0,                              /* num_get_cont_resources */
280                 XmInheritParentProcess,         /* parent_process       */
281                 NULL,                           /* extension            */
282         },
283
284 /*      XmBulletinBoard Part
285 */
286         {
287                 True,                           /* always_install_accelerators*/
288                 NULL,                           /* geo_matrix_create    */
289                 XmInheritFocusMovedProc,        /* focus_moved_proc     */
290                 NULL,                           /* extension            */
291         },
292
293 /*      XmForm Part
294 */
295         {
296                 NULL,                           /* extension            */
297         },
298
299 /*      DtDialogBox Part
300 */
301         {
302 (XtWidgetProc)  CreateChildren,                 /* create_children      */
303                 NULL,                           /* configure_children   */
304                 GetSize,                        /* get_size             */
305                 NULL,                           /* button_callback      */
306                 NULL,                           /* extension            */
307         }
308
309 };
310
311 WidgetClass dtDialogBoxWidgetClass = (WidgetClass) &dtDialogBoxClassRec;
312
313
314 \f
315 /*-------------------------------------------------------------
316 **      Private Procs
317 **-------------------------------------------------------------
318 */
319
320
321 /*-------------------------------------------------------------
322 **      Action Procs
323 **-------------------------------------------------------------
324 */
325
326
327 /*-------------------------------------------------------------
328 **      Core Procs
329 **-------------------------------------------------------------
330 */
331
332 /*-------------------------------------------------------------
333 **      ClassInitialize
334 **              Initialize widget class.
335 */
336 static void 
337 ClassInitialize( void )
338 {
339         _DtRegisterNewConverters ();
340 }
341
342
343 \f
344 /*-------------------------------------------------------------
345 **      ClassPartInitialize
346 **              Initialize widget class part.
347 */
348 static void
349 ClassPartInitialize(
350         WidgetClass wc )
351 {
352         DtDialogBoxWidgetClass  mc =    (DtDialogBoxWidgetClass) wc;
353         DtDialogBoxWidgetClass  super = (DtDialogBoxWidgetClass)
354                                                 C_Superclass (wc);
355
356         mc->bulletin_board_class.always_install_accelerators = True;
357
358 /*      Propagate class procs for subclasses.
359 */
360         if (C_CreateChildren (mc) == (XtWidgetProc) _XtInherit) 
361                 C_CreateChildren (mc) = C_CreateChildren (super);
362
363         if (C_ConfigureChildren (mc) == (XtWidgetProc) _XtInherit)      
364                 C_ConfigureChildren (mc) = C_ConfigureChildren (super);
365
366         if (C_GetSize (mc) == (DlgGetSizeProc) _XtInherit)      
367                 C_GetSize (mc) = C_GetSize (super);
368
369         if (C_ButtonCallback (mc) == (XtCallbackProc) _XtInherit)       
370                 C_ButtonCallback (mc) = C_ButtonCallback (super);
371
372 }
373
374
375 \f
376 /*-------------------------------------------------------------
377 **      Initialize
378 **              Initialize a new widget instance.
379 */
380 static void 
381 Initialize(
382         Widget request_w,
383         Widget new_w )
384 {
385         DtDialogBoxWidget       new     = (DtDialogBoxWidget) new_w;
386         XtWidgetProc    create_children;
387
388         if (M_ButtonCount (new) > 0)
389                 M_Button (new) = (Widget *)
390                         XtMalloc (sizeof (Widget) * M_ButtonCount (new));
391         else
392                 M_Button (new) = NULL;
393
394         M_WorkArea (new) = NULL;
395         _DtProcessLock();
396         create_children = C_CreateChildren((DtDialogBoxWidgetClass) XtClass(new));
397         _DtProcessUnlock();
398         (*create_children) ((Widget)new); 
399
400         M_ButtonLabelStrings (new) = NULL;
401
402         M_MarginWidth (new) = M_ShadowThickness (new);
403         M_MarginHeight (new) = M_ShadowThickness (new);
404 }
405
406
407 /*-------------------------------------------------------------
408 **      Destroy
409 **              Release resources allocated for widget instance.
410 */
411 static void 
412 Destroy(
413         Widget w )
414 {
415         DtDialogBoxWidget       mgr = (DtDialogBoxWidget) w;
416
417 /*      Free button pointers.
418 */
419         if (M_Button (mgr) != NULL)
420                 XtFree ((char *)M_Button (mgr));
421 }
422
423
424 \f
425 /*-------------------------------------------------------------
426 **      SetValues
427 **              Handle changes in resource data.
428 */
429 static Boolean 
430 SetValues(
431         Widget current_w,
432         Widget request_w,
433         Widget new_w )
434 {
435         Boolean redraw_flag = False;
436
437 /*      Superclass does all the work so far; checks for redisplay, etc.
438 */
439
440         return (redraw_flag);
441 }
442
443
444 \f
445 /*-------------------------------------------------------------
446 **      Composite Procs
447 **-------------------------------------------------------------
448 */
449
450 /*-------------------------------------------------------------
451 **      ChangeManaged
452 **              Handle change in set of managed children.
453 */
454 static void 
455 ChangeManaged(
456         Widget manager )
457 {
458         DtDialogBoxWidget       mgr     = (DtDialogBoxWidget) manager;
459         Dimension               w       = M_Width (mgr),
460                                 h       = M_Height (mgr);
461         DlgGetSizeProc          get_size;
462         XtWidgetProc            resize;
463 /*      Compute desired size.
464 */
465         _DtProcessLock();
466         get_size = C_GetSize((DtDialogBoxWidgetClass) XtClass(mgr));
467         resize = XtCoreProc(manager, resize);
468         _DtProcessUnlock();
469         (*get_size) ((Widget)mgr, 0, 0, 0, 0, &w, &h);
470
471         /* check for resize policy if not first time ?? */
472
473 /*      Try to change size to fit children
474 */
475         if (w != M_Width (mgr) || h != M_Height (mgr))
476         {
477                 switch (XtMakeResizeRequest ((Widget) mgr, w, h, &w, &h))
478                 {
479                         case XtGeometryAlmost:
480                                 XtMakeResizeRequest ((Widget) mgr, w, h,
481                                         NULL, NULL);
482                         case XtGeometryYes:
483                         case XtGeometryNo:
484                         default:
485                                 break;
486                 }
487         }
488         
489 /*      Set positions and sizes of children.
490 */
491         (*resize) (manager);
492 }
493
494
495 \f
496 /*-------------------------------------------------------------
497 **      InsertChild
498 **              Add a child.
499 */
500 static void 
501 InsertChild(
502         Widget child )
503 {
504         DtDialogBoxConstraint   constraint = (DtDialogBoxConstraint)
505                                         M_DialogBoxConstraint (child);
506         DtDialogBoxWidget       w = (DtDialogBoxWidget) XtParent (child);
507         XmManagerWidgetClass    mc = (XmManagerWidgetClass)xmManagerWidgetClass;
508         Dimension               s_t = M_ShadowThickness (w);
509         Arg             al[20];         /*  arg list            */
510         register int    ac;             /*  arg count           */
511         XtWidgetProc    insert_child;
512
513         _DtProcessLock();
514         insert_child = mc->composite_class.insert_child;
515         _DtProcessUnlock();
516         (*insert_child) (child);
517
518         if (constraint->child_type == XmWORK_AREA)
519         {
520                 if (! M_WorkArea (w))
521                 {
522                         M_WorkArea (w) = child;
523                         ac = 0;
524                         XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM);  ac++;
525                         XtSetArg (al[ac], XmNtopOffset, s_t);  ac++;
526                         XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
527                         XtSetArg (al[ac], XmNleftOffset, s_t);  ac++;
528                         XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
529                         XtSetArg (al[ac], XmNrightOffset, s_t);  ac++;
530                         XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_WIDGET);  ac++;
531                         XtSetArg (al[ac], XmNbottomWidget, M_Separator (w));  ac++;
532                         XtSetArg (al[ac], XmNbottomOffset, 0);  ac++;
533                         XtSetValues (child, al, ac);
534                 }
535         }
536 }
537
538
539 \f
540 /*-------------------------------------------------------------
541 **      DeleteChild
542 **              Delete a child.
543 */
544 static void 
545 DeleteChild(
546         Widget child )
547 {
548         DtDialogBoxWidget       w = (DtDialogBoxWidget) XtParent (child);
549         XmManagerWidgetClass    mc = (XmManagerWidgetClass)xmManagerWidgetClass;
550         XtWidgetProc            delete_child;
551
552         _DtProcessLock();
553         delete_child = mc->composite_class.delete_child;
554         _DtProcessUnlock();
555         (*delete_child) (child);
556         
557         if (child == M_Separator (w))
558                 M_Separator (w) = NULL;
559         else if (child == M_WorkArea (w))
560                 M_WorkArea (w) = NULL;
561
562         /* button children ?? */
563 }
564
565
566 \f 
567 /*-------------------------------------------------------------
568 **      Constraint Procs
569 **-------------------------------------------------------------
570 */
571 /*-------------------------------------------------------------
572 **      ConstraintInitialize
573 **              Add a child.
574 */
575 static void 
576 ConstraintInitialize(
577         Widget request,
578         Widget new )
579 {
580         DtDialogBoxWidget       mgr      = (DtDialogBoxWidget) XtParent (new);
581         DtDialogBoxConstraint   constraint      = M_DialogBoxConstraint (new);
582
583 /*      Validate child type.
584 */
585         if (constraint->child_type != XmWORK_AREA &&
586             constraint->child_type != XmSEPARATOR &&
587             constraint->child_type != XmBUTTON)
588         {
589                 XmeWarning (new, WARN_CHILD_TYPE);
590                 if (! M_WorkArea (mgr))
591                 {
592                         constraint->child_type = XmWORK_AREA;
593                 }
594         }
595 }
596
597
598 /*-------------------------------------------------------------
599 **      XmManager Procs
600 **-------------------------------------------------------------
601 */
602
603 /*      All inherited from superclass.
604 */
605
606
607 \f
608 /*-------------------------------------------------------------
609 **      DtDialogBox Procs
610 **-------------------------------------------------------------
611 */ 
612
613 /*-------------------------------------------------------------------------
614 **      GetSize
615 **              Calculate desired size based on children.
616 */
617 static void 
618 GetSize(
619         Widget manager,
620         Dimension wa_w,
621         Dimension wa_h,
622         Dimension bp_w,
623         Dimension bp_h,
624         Dimension *w,
625         Dimension *h )
626 {
627         DtDialogBoxWidget       mgr =           (DtDialogBoxWidget) manager;
628         Widget                  work_area =     M_WorkArea (mgr),
629                                 separator =     M_Separator (mgr);
630         Widget *                button =        M_Button (mgr);
631         register int            button_count =  M_ButtonCount (mgr),
632                                 i;                    
633         Boolean                 min_btns =      M_MinimizeButtons (mgr);
634         Dimension               sep_h = 0,
635                                 offset = OFFSET, pad,
636                                 max_w = 0, max_h = 0,
637                                 s_t =           M_ShadowThickness (mgr);
638         XtWidgetGeometry        request, reply;
639
640
641 /*      Query work area.
642 */
643         if (work_area && !wa_w && !wa_h)
644         {
645                 request.request_mode = CWWidth | CWHeight;
646                 XtQueryGeometry (work_area, &request, &reply);
647                 wa_w = reply.width;
648                 wa_h = reply.height;
649         }
650
651         sep_h = (separator)     ? P_Height (separator)  : 0;
652
653 /*      Get button panel size.
654 */
655         s_t = Max (2, s_t);
656         if ((bp_w == 0) && (bp_h == 0) && !min_btns)
657         {
658                 request.request_mode = CWWidth | CWHeight;
659                 for (i = 0;  i < button_count;  i++)
660                 {
661                         pad = (i == 0) ? 0 : 4 * s_t;
662                         XtQueryGeometry (button[i], &request, &reply);
663                         max_w = Max ((unsigned)max_w, reply.width + pad);
664                         max_h = Max ((unsigned)max_h, reply.height + pad);
665                 }
666
667                 if (button_count)
668                 {
669                         max_w += 4;
670                         max_h += 1;
671                 }
672
673                 bp_w = (button_count * max_w) + ((button_count + 1) * offset);
674                 bp_h = sep_h + max_h + (2 * offset);
675         }
676
677         else if ((bp_w == 0) && (bp_h == 0) && min_btns)
678         {
679                 request.request_mode = CWWidth | CWHeight;
680                 for (i = 0;  i < button_count;  i++)
681                 {
682                         XtQueryGeometry (button[i], &request, &reply);
683                         bp_w += reply.width;
684                         max_h = Max (max_h, reply.height);
685                 }
686
687                 bp_w += (button_count + 1) * offset;
688                 bp_h = sep_h + max_h + (2 * offset);
689         }
690
691 /*      Set width and height.
692 */
693         *w = Max (wa_w, bp_w);
694         *h = wa_h + sep_h + bp_h;
695 }
696
697
698 \f
699 /*-------------------------------------------------------------
700 **      CreateChildren
701 **              Create resource and value labels and text.
702 */
703 static void 
704 CreateChildren(
705         DtDialogBoxWidget new,
706         Widget top_widget,
707         Widget bottom_widget )
708 {
709         Widget          ref_widget,
710                         sep, btn;
711         Widget *        button =        M_Button (new);
712         int             count =         M_ButtonCount (new),
713                         i, l_p, r_p, off_p, b_delta, offset = 0;
714         XmStringTable   string =        M_ButtonLabelStrings (new);
715         Boolean         min_btns =      M_MinimizeButtons (new);
716         Dimension       s_t =           M_ShadowThickness (new);
717         char            button_name[100];
718
719         Arg             al[20];         /*  arg list            */
720         register int    ac;             /*  arg count           */
721
722 /*      Compute position factors.
723 */
724         off_p = 2;
725         b_delta = (100 - off_p) / count;
726         l_p = (100 - (count * b_delta) + off_p) / 2;
727         r_p = l_p + b_delta - off_p;
728 /*      s_t = Max (2, s_t); */
729
730 /*      Create buttons.
731 */
732         for (i = 0; i < count; i++)
733         {
734                 ac = 0;
735                 XtSetArg (al[ac], XmNdefaultButtonShadowThickness,Max(2U,s_t)/2U);
736                 ac++;
737                 XtSetArg (al[ac], XmNshadowThickness, s_t);  ac++;
738                 XtSetArg (al[ac], XmNhighlightThickness, s_t);  ac++;
739                 if (!min_btns)
740                 {
741                         XtSetArg (al[ac], XmNleftAttachment,
742                                 XmATTACH_POSITION);  ac++;
743                         XtSetArg (al[ac], XmNleftPosition, l_p);  ac++;
744                         XtSetArg (al[ac], XmNleftOffset, offset);  ac++;
745                         XtSetArg (al[ac], XmNrightAttachment,
746                                 XmATTACH_POSITION);  ac++;
747                         XtSetArg (al[ac], XmNrightPosition, r_p);  ac++;
748                         XtSetArg (al[ac], XmNrightOffset, offset);  ac++;
749                 }
750                 else
751                 {
752                         if (i == 0)
753                         {
754                                 XtSetArg (al[ac], XmNleftAttachment,
755                                         XmATTACH_FORM);  ac++;
756                                 XtSetArg (al[ac], XmNleftOffset, OFFSET);  ac++;
757                         }
758                         else if (i == count -1)
759                         {
760                                 XtSetArg (al[ac], XmNrightAttachment,
761                                         XmATTACH_FORM);  ac++;
762                                 XtSetArg (al[ac], XmNrightOffset, OFFSET);  ac++;
763                         }
764                         else
765                         {
766                                 XtSetArg (al[ac], XmNleftAttachment,
767                                         XmATTACH_WIDGET);  ac++;
768                                 XtSetArg (al[ac], XmNleftWidget, button[i-1]);
769                                 ac++;
770                                 XtSetArg (al[ac], XmNleftOffset, OFFSET);
771                                 ac++;
772                         }
773                 }
774
775                 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM);  ac++;
776                 XtSetArg (al[ac], XmNbottomOffset, OFFSET + offset);  ac++;
777                 if (string)
778                 {
779                         XtSetArg (al[ac], XmNlabelString, string[i]);  ac++;
780                 }
781                 XtSetArg (al[ac], XmNchildType, XmBUTTON);  ac++;
782                 sprintf (button_name, "%s_%d", M_Name (new), i+1);
783                 btn = XmCreatePushButtonGadget ((Widget)new, button_name, al, ac);
784                 XtManageChild (btn);
785                 XtAddCallback (btn, XmNactivateCallback,
786                                 (XtCallbackProc)ButtonCallback,
787                                 (XtPointer)((long)(i+1)));
788
789                 button[i] = btn;
790                 l_p += b_delta;
791                 r_p += b_delta;
792
793         }
794         ref_widget = button[0];
795         new->bulletin_board.default_button = button[0];
796
797 /*      Create Separator
798 */
799         ac = 0;
800         XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM);  ac++;
801         XtSetArg (al[ac], XmNleftOffset, 0);  ac++;
802         XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM);  ac++;
803         XtSetArg (al[ac], XmNrightOffset, 0);  ac++;
804         XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_WIDGET);  ac++;
805         XtSetArg (al[ac], XmNbottomWidget, ref_widget);  ac++;
806         XtSetArg (al[ac], XmNbottomOffset, OFFSET);  ac++;
807         XtSetArg (al[ac], XmNhighlightThickness, 0);  ac++;
808         XtSetArg (al[ac], XmNchildType, XmSEPARATOR);  ac++;
809         sep = XmCreateSeparatorGadget ((Widget)new, "separator", al, ac);
810         XtManageChild (sep);
811         M_Separator (new) = sep;
812 }
813
814
815 /*-------------------------------------------------------------
816 **      ButtonCallback
817 */
818 static void 
819 ButtonCallback(
820         Widget g,
821         XtPointer client_data,
822         XtPointer call_data )
823 {
824         DtDialogBoxWidget       mgr =   (DtDialogBoxWidget) XtParent (g);
825         XtCallbackList          cb_list =       M_Callback (mgr);
826         XmAnyCallbackStruct *   b_cb_data =
827                                 (XmAnyCallbackStruct *) call_data;
828         DtDialogBoxCallbackStruct       cb_data;
829
830         if (cb_list != NULL)
831         {
832                 cb_data.reason = XmCR_DIALOG_BUTTON;
833                 cb_data.event = b_cb_data->event;
834                 cb_data.button_position = (int) client_data;
835                 cb_data.button = g;
836                 XtCallCallbackList ((Widget) mgr, cb_list, &cb_data);
837         }
838 }
839
840
841 \f
842 /*-------------------------------------------------------------
843 **      Public Entry Points
844 **-------------------------------------------------------------
845 */
846
847 /*-------------------------------------------------------------
848 **      _DtCreateDialogBox
849 **              Create a new DtDialogBox instance.
850 **-------------------------------------------------------------
851 */
852 Widget 
853 _DtCreateDialogBox(
854         Widget parent,
855         char *name,
856         ArgList arglist,
857         Cardinal argcount )
858 {
859         return (XtCreateWidget (name, dtDialogBoxWidgetClass, 
860                         parent, arglist, argcount));
861 }
862
863
864 /*-------------------------------------------------------------
865 **      __DtCreateDialogBoxDialog
866 **              Create a DialogShell and a new DialogBox instance;
867 **              return the DialogBox widget;
868 **-------------------------------------------------------------
869 */
870 Widget 
871 __DtCreateDialogBoxDialog(
872         Widget ds_p,
873         String name,
874         ArgList db_args,
875         Cardinal db_n )
876 {
877         Widget          ds;             /*  DialogShell         */
878         Arg             ds_args[10];    /*  arglist for shell   */
879         Cardinal        ds_n;           /*  argcount for shell  */
880         Widget          db;             /*  new sb widget       */
881
882
883         /*  create DialogShell parent
884         */
885         ds_n = 0;
886         XtSetArg (ds_args[ds_n], XmNallowShellResize, True);  ds_n++;
887         ds = XtCreatePopupShell (name, xmDialogShellWidgetClass, 
888                 ds_p, ds_args, ds_n);
889
890         /*  create DialogBox, free args, return 
891         */
892         db = XtCreateWidget (name, dtDialogBoxWidgetClass, 
893                 ds, db_args, db_n);
894
895         return (db);
896 }
897
898
899 /*-------------------------------------------------------------
900 **      _DtDialogBoxGetButton
901 **              Return DialogBox button.
902 **-------------------------------------------------------------
903 */
904 Widget 
905 _DtDialogBoxGetButton(
906         Widget w,
907         Cardinal pos )
908 {
909         DtDialogBoxWidget       mgr =   (DtDialogBoxWidget) w;
910         int                     index = pos - 1;
911         Widget *                button = M_Button (mgr);
912         Widget                  rtn_w = NULL;
913
914
915         if (index >= M_ButtonCount (mgr))
916                 XmeWarning ((Widget)mgr, WARN_BUTTON_CHILD);
917         else
918                 rtn_w = button[index];
919
920         return (rtn_w);
921 }
922
923
924 /*-------------------------------------------------------------
925 **      _DtDialogBoxGetWorkArea
926 **              Return DialogBox work area;
927 **-------------------------------------------------------------
928 */
929 Widget 
930 _DtDialogBoxGetWorkArea(
931         Widget w )
932 {
933         DtDialogBoxWidget       mgr =   (DtDialogBoxWidget) w;
934         Widget                  rtn_w = M_WorkArea (mgr);
935
936         return (rtn_w);
937 }
938
939