1 /* The lwlib interface to Motif widgets.
2 Copyright (C) 1992 Lucid, Inc.
4 This file is part of the Lucid Widget Library.
6 The Lucid Widget Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 The Lucid Widget Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include <X11/StringDefs.h>
26 #include <X11/IntrinsicP.h>
27 #include <X11/ObjectP.h>
28 #include <X11/CoreP.h>
29 #include <X11/CompositeP.h>
32 #include "lwlib-utils.h"
34 #include <Xm/BulletinB.h>
35 #include <Xm/CascadeB.h>
36 #include <Xm/DrawingA.h>
37 #include <Xm/FileSB.h>
41 #include <Xm/MenuShell.h>
42 #include <Xm/MessageB.h>
43 #include <Xm/PanedW.h>
45 #include <Xm/PushBG.h>
46 #include <Xm/ArrowB.h>
47 #include <Xm/SelectioB.h>
50 #include <Xm/ToggleB.h>
51 #include <Xm/ToggleBG.h>
52 #include <Xm/RowColumn.h>
53 #include <Xm/ScrolledW.h>
54 #include <Xm/Separator.h>
55 #include <Xm/DialogS.h>
58 static void xm_pull_down_callback (/* Widget, XtPointer, XtPointer */);
59 static void xm_internal_update_other_instances (/* Widget, XtPointer,
61 static void xm_generic_callback (/* Widget, XtPointer, XtPointer */);
62 static void xm_nosel_callback (/* Widget, XtPointer, XtPointer */);
63 static void xm_pop_down_callback (/* Widget, XtPointer, XtPointer */);
65 static void xm_update_menu (/* widget_instance*, Widget, widget_value*,
69 \f/* Structures to keep destroyed instances */
70 typedef struct _destroyed_instance
77 struct _destroyed_instance
* next
;
80 static destroyed_instance
*
81 all_destroyed_instances
= NULL
;
83 static destroyed_instance
*
84 make_destroyed_instance (name
, type
, widget
, parent
, pop_up_p
)
91 destroyed_instance
* instance
=
92 (destroyed_instance
*)malloc (sizeof (destroyed_instance
));
93 instance
->name
= safe_strdup (name
);
94 instance
->type
= safe_strdup (type
);
95 instance
->widget
= widget
;
96 instance
->parent
= parent
;
97 instance
->pop_up_p
= pop_up_p
;
98 instance
->next
= NULL
;
103 free_destroyed_instance (instance
)
104 destroyed_instance
* instance
;
106 free (instance
->name
);
107 free (instance
->type
);
111 \f/* motif utility functions */
116 return ((CompositeWidget
)widget
)->composite
.children
[0];
120 lw_motif_widget_p (widget
)
124 XtClass (widget
) == xmDialogShellWidgetClass
125 || XmIsPrimitive (widget
) || XmIsManager (widget
) || XmIsGadget (widget
);
129 resource_motif_string (widget
, name
)
136 resource
.resource_name
= name
;
137 resource
.resource_class
= XmCXmString
;
138 resource
.resource_type
= XmRXmString
;
139 resource
.resource_size
= sizeof (XmString
);
140 resource
.resource_offset
= 0;
141 resource
.default_type
= XtRImmediate
;
142 resource
.default_addr
= 0;
144 XtGetSubresources (widget
, (XtPointer
)&result
, "dialogString",
145 "DialogString", &resource
, 1, NULL
, 0);
150 destroy_all_children (widget
)
157 children
= XtCompositeChildren (widget
, &number
);
160 /* Unmanage all children and destroy them. They will only be
161 * really destroyed when we get out of DispatchEvent. */
162 for (i
= 0; i
< number
; i
++)
164 Widget child
= children
[i
];
165 if (!child
->core
.being_destroyed
)
167 XtUnmanageChild (child
);
168 XtDestroyWidget (child
);
171 XtFree ((char *) children
);
175 \f/* update the label of anything subclass of a label */
177 xm_update_label (instance
, widget
, val
)
178 widget_instance
* instance
;
182 XmString res_string
= 0;
183 XmString built_string
= 0;
184 XmString key_string
= 0;
192 res_string
= resource_motif_string (widget
, val
->value
);
196 XtSetArg (al
[ac
], XmNlabelString
, res_string
); ac
++;
201 XmStringCreateLtoR (val
->value
, XmSTRING_DEFAULT_CHARSET
);
202 XtSetArg (al
[ac
], XmNlabelString
, built_string
); ac
++;
204 XtSetArg (al
[ac
], XmNlabelType
, XmSTRING
); ac
++;
209 key_string
= XmStringCreateLtoR (val
->key
, XmSTRING_DEFAULT_CHARSET
);
210 XtSetArg (al
[ac
], XmNacceleratorText
, key_string
); ac
++;
214 XtSetValues (widget
, al
, ac
);
217 XmStringFree (built_string
);
220 XmStringFree (key_string
);
223 \f/* update of list */
225 xm_update_list (instance
, widget
, val
)
226 widget_instance
* instance
;
232 XtRemoveAllCallbacks (widget
, XmNsingleSelectionCallback
);
233 XtAddCallback (widget
, XmNsingleSelectionCallback
, xm_generic_callback
,
235 for (cur
= val
->contents
, i
= 0; cur
; cur
= cur
->next
)
238 XmString xmstr
= XmStringCreate (cur
->value
, XmSTRING_DEFAULT_CHARSET
);
240 XmListAddItem (widget
, xmstr
, 0);
242 XmListSelectPos (widget
, i
, False
);
243 XmStringFree (xmstr
);
247 \f/* update of buttons */
249 xm_update_pushbutton (instance
, widget
, val
)
250 widget_instance
* instance
;
254 XtVaSetValues (widget
, XmNalignment
, XmALIGNMENT_CENTER
, 0);
255 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
256 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
260 xm_update_cascadebutton (instance
, widget
, val
)
261 widget_instance
* instance
;
265 /* Should also rebuild the menu by calling ...update_menu... */
266 XtRemoveAllCallbacks (widget
, XmNcascadingCallback
);
267 XtAddCallback (widget
, XmNcascadingCallback
, xm_pull_down_callback
,
271 \f/* update toggle and radiobox */
273 xm_update_toggle (instance
, widget
, val
)
274 widget_instance
* instance
;
278 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
279 XtAddCallback (widget
, XmNvalueChangedCallback
,
280 xm_internal_update_other_instances
, instance
);
281 XtVaSetValues (widget
, XmNset
, val
->selected
,
282 XmNalignment
, XmALIGNMENT_BEGINNING
, 0);
286 xm_update_radiobox (instance
, widget
, val
)
287 widget_instance
* instance
;
295 /* update the callback */
296 XtRemoveAllCallbacks (widget
, XmNentryCallback
);
297 XtAddCallback (widget
, XmNentryCallback
, xm_generic_callback
, instance
);
299 /* first update all the toggles */
300 /* Energize kernel interface is currently bad. It sets the selected widget
301 with the selected flag but returns it by its name. So we currently
302 have to support both setting the selection with the selected slot
303 of val contents and setting it with the "value" slot of val. The latter
304 has a higher priority. This to be removed when the kernel is fixed. */
305 for (cur
= val
->contents
; cur
; cur
= cur
->next
)
307 toggle
= XtNameToWidget (widget
, cur
->value
);
310 XtVaSetValues (toggle
, XmNsensitive
, cur
->enabled
, 0);
311 if (!val
->value
&& cur
->selected
)
312 XtVaSetValues (toggle
, XmNset
, cur
->selected
, 0);
313 if (val
->value
&& strcmp (val
->value
, cur
->value
))
314 XtVaSetValues (toggle
, XmNset
, False
, 0);
318 /* The selected was specified by the value slot */
321 toggle
= XtNameToWidget (widget
, val
->value
);
323 XtVaSetValues (toggle
, XmNset
, True
, 0);
327 \f/* update a popup menu, pulldown menu or a menubar */
340 make_menu_in_widget (instance
, widget
, val
)
341 widget_instance
* instance
;
345 Widget
* children
= 0;
355 /* Allocate the children array */
356 for (num_children
= 0, cur
= val
; cur
; num_children
++, cur
= cur
->next
);
357 children
= (Widget
*)XtMalloc (num_children
* sizeof (Widget
));
359 /* tricky way to know if this RowColumn is a menubar or a pulldown... */
361 XtSetArg (al
[0], XmNisHomogeneous
, &menubar_p
);
362 XtGetValues (widget
, al
, 1);
364 /* add the unmap callback for popups and pulldowns */
365 /*** this sounds bogus ***/
367 XtAddCallback (XtParent (widget
), XmNpopdownCallback
,
368 xm_pop_down_callback
, (XtPointer
)instance
);
370 for (child_index
= 0, cur
= val
; cur
; child_index
++, cur
= cur
->next
)
373 XtSetArg (al
[ac
], XmNsensitive
, cur
->enabled
); ac
++;
374 XtSetArg (al
[ac
], XmNalignment
, XmALIGNMENT_BEGINNING
); ac
++;
375 XtSetArg (al
[ac
], XmNuserData
, cur
->call_data
); ac
++;
377 if (instance
->pop_up_p
&& !cur
->contents
&& !cur
->call_data
378 && !all_dashes_p (cur
->name
))
381 XtSetArg (al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
382 button
= XmCreateLabel (widget
, cur
->name
, al
, ac
);
384 else if (all_dashes_p (cur
->name
))
386 button
= XmCreateSeparator (widget
, cur
->name
, NULL
, 0);
388 else if (!cur
->contents
)
391 button
= XmCreateCascadeButton (widget
, cur
->name
, al
, ac
);
392 else if (!cur
->call_data
)
393 button
= XmCreateLabel (widget
, cur
->name
, al
, ac
);
395 button
= XmCreatePushButtonGadget (widget
, cur
->name
, al
, ac
);
397 xm_update_label (instance
, button
, cur
);
399 /* don't add a callback to a simple label */
401 XtAddCallback (button
, XmNactivateCallback
, xm_generic_callback
,
402 (XtPointer
)instance
);
406 menu
= XmCreatePulldownMenu (widget
, cur
->name
, NULL
, 0);
407 make_menu_in_widget (instance
, menu
, cur
->contents
);
408 XtSetArg (al
[ac
], XmNsubMenuId
, menu
); ac
++;
409 button
= XmCreateCascadeButton (widget
, cur
->name
, al
, ac
);
411 xm_update_label (instance
, button
, cur
);
413 XtAddCallback (button
, XmNcascadingCallback
, xm_pull_down_callback
,
414 (XtPointer
)instance
);
417 children
[child_index
] = button
;
420 XtManageChildren (children
, num_children
);
422 /* Last entry is the help button. Has to be done after managing
423 * the buttons otherwise the menubar is only 4 pixels high... */
427 XtSetArg (al
[ac
], XmNmenuHelpWidget
, button
); ac
++;
428 XtSetValues (widget
, al
, ac
);
431 XtFree ((char *) children
);
435 update_one_menu_entry (instance
, widget
, val
, deep_p
)
436 widget_instance
* instance
;
444 widget_value
* contents
;
446 if (val
->change
== NO_CHANGE
)
449 /* update the sensitivity and userdata */
450 /* Common to all widget types */
451 XtVaSetValues (widget
,
452 XmNsensitive
, val
->enabled
,
453 XmNuserData
, val
->call_data
,
456 /* update the menu button as a label. */
457 if (val
->change
>= VISIBLE_CHANGE
)
458 xm_update_label (instance
, widget
, val
);
460 /* update the pulldown/pullaside as needed */
463 XtSetArg (al
[ac
], XmNsubMenuId
, &menu
); ac
++;
464 XtGetValues (widget
, al
, ac
);
466 contents
= val
->contents
;
472 menu
= XmCreatePulldownMenu (XtParent (widget
), XtName (widget
), NULL
, 0);
473 make_menu_in_widget (instance
, menu
, contents
);
475 XtSetArg (al
[ac
], XmNsubMenuId
, menu
); ac
++;
476 XtSetValues (widget
, al
, ac
);
482 XtSetArg (al
[ac
], XmNsubMenuId
, NULL
); ac
++;
483 XtSetValues (widget
, al
, ac
);
484 XtDestroyWidget (menu
);
486 else if (deep_p
&& contents
->change
!= NO_CHANGE
)
487 xm_update_menu (instance
, menu
, val
, 1);
491 xm_update_menu (instance
, widget
, val
, deep_p
)
492 widget_instance
* instance
;
497 /* Widget is a RowColumn widget whose contents have to be updated
498 * to reflect the list of items in val->contents */
499 if (val
->contents
->change
== STRUCTURAL_CHANGE
)
501 destroy_all_children (widget
);
502 make_menu_in_widget (instance
, widget
, val
->contents
);
506 /* Update all the buttons of the RowColumn in order. */
508 unsigned int num_children
;
512 children
= XtCompositeChildren (widget
, &num_children
);
515 for (i
= 0, cur
= val
->contents
; i
< num_children
; i
++)
519 if (children
[i
]->core
.being_destroyed
520 || strcmp (XtName (children
[i
]), cur
->name
))
522 update_one_menu_entry (instance
, children
[i
], cur
, deep_p
);
525 XtFree ((char *) children
);
533 /* update text widgets */
536 xm_update_text (instance
, widget
, val
)
537 widget_instance
* instance
;
541 XmTextSetString (widget
, val
->value
? val
->value
: "");
542 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
543 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
544 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
545 XtAddCallback (widget
, XmNvalueChangedCallback
,
546 xm_internal_update_other_instances
, instance
);
550 xm_update_text_field (instance
, widget
, val
)
551 widget_instance
* instance
;
555 XmTextFieldSetString (widget
, val
->value
? val
->value
: "");
556 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
557 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
558 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
559 XtAddCallback (widget
, XmNvalueChangedCallback
,
560 xm_internal_update_other_instances
, instance
);
564 /* update a motif widget */
567 xm_update_one_widget (instance
, widget
, val
, deep_p
)
568 widget_instance
* instance
;
575 /* Mark as not edited */
578 /* Common to all widget types */
579 XtVaSetValues (widget
,
580 XmNsensitive
, val
->enabled
,
581 XmNuserData
, val
->call_data
,
584 /* Common to all label like widgets */
585 if (XtIsSubclass (widget
, xmLabelWidgetClass
))
586 xm_update_label (instance
, widget
, val
);
588 class = XtClass (widget
);
589 /* Class specific things */
590 if (class == xmPushButtonWidgetClass
||
591 class == xmArrowButtonWidgetClass
)
593 xm_update_pushbutton (instance
, widget
, val
);
595 else if (class == xmCascadeButtonWidgetClass
)
597 xm_update_cascadebutton (instance
, widget
, val
);
599 else if (class == xmToggleButtonWidgetClass
600 || class == xmToggleButtonGadgetClass
)
602 xm_update_toggle (instance
, widget
, val
);
604 else if (class == xmRowColumnWidgetClass
)
606 Boolean radiobox
= 0;
610 XtSetArg (al
[ac
], XmNradioBehavior
, &radiobox
); ac
++;
611 XtGetValues (widget
, al
, ac
);
614 xm_update_radiobox (instance
, widget
, val
);
616 xm_update_menu (instance
, widget
, val
, deep_p
);
618 else if (class == xmTextWidgetClass
)
620 xm_update_text (instance
, widget
, val
);
622 else if (class == xmTextFieldWidgetClass
)
624 xm_update_text_field (instance
, widget
, val
);
626 else if (class == xmListWidgetClass
)
628 xm_update_list (instance
, widget
, val
);
632 \f/* getting the value back */
634 xm_update_one_value (instance
, widget
, val
)
635 widget_instance
* instance
;
639 WidgetClass
class = XtClass (widget
);
640 widget_value
*old_wv
;
642 /* copy the call_data slot into the "return" widget_value */
643 for (old_wv
= instance
->info
->val
->contents
; old_wv
; old_wv
= old_wv
->next
)
644 if (!strcmp (val
->name
, old_wv
->name
))
646 val
->call_data
= old_wv
->call_data
;
650 if (class == xmToggleButtonWidgetClass
|| class == xmToggleButtonGadgetClass
)
652 XtVaGetValues (widget
, XmNset
, &val
->selected
, 0);
655 else if (class == xmTextWidgetClass
)
659 val
->value
= XmTextGetString (widget
);
662 else if (class == xmTextFieldWidgetClass
)
666 val
->value
= XmTextFieldGetString (widget
);
669 else if (class == xmRowColumnWidgetClass
)
671 Boolean radiobox
= 0;
675 XtSetArg (al
[ac
], XmNradioBehavior
, &radiobox
); ac
++;
676 XtGetValues (widget
, al
, ac
);
680 CompositeWidget radio
= (CompositeWidget
)widget
;
682 for (i
= 0; i
< radio
->composite
.num_children
; i
++)
685 Widget toggle
= radio
->composite
.children
[i
];
687 XtVaGetValues (toggle
, XmNset
, &set
, 0);
692 val
->value
= safe_strdup (XtName (toggle
));
698 else if (class == xmListWidgetClass
)
702 if (XmListGetSelectedPos (widget
, &pos_list
, &pos_cnt
))
706 for (cur
= val
->contents
, i
= 0; cur
; cur
= cur
->next
)
710 cur
->selected
= False
;
712 for (j
= 0; j
< pos_cnt
; j
++)
713 if (pos_list
[j
] == i
)
715 cur
->selected
= True
;
716 val
->value
= safe_strdup (cur
->name
);
720 XtFree ((char *) pos_list
);
726 /* This function is for activating a button from a program. It's wrong because
727 we pass a NULL argument in the call_data which is not Motif compatible.
728 This is used from the XmNdefaultAction callback of the List widgets to
729 have a dble-click put down a dialog box like the button woudl do.
730 I could not find a way to do that with accelerators.
733 activate_button (widget
, closure
, call_data
)
738 Widget button
= (Widget
)closure
;
739 XtCallCallbacks (button
, XmNactivateCallback
, NULL
);
742 /* creation functions */
746 make_dialog (name
, parent
, pop_up_p
, shell_title
, icon_name
, text_input_slot
,
747 radio_box
, list
, left_buttons
, right_buttons
)
753 Boolean text_input_slot
;
763 Widget icon_separator
;
768 Widget children
[16]; /* for the final XtManageChildren */
770 Arg al
[64]; /* Arg List */
771 int ac
; /* Arg Count */
777 XtSetArg(al
[ac
], XmNtitle
, shell_title
); ac
++;
778 XtSetArg(al
[ac
], XtNallowShellResize
, True
); ac
++;
779 XtSetArg(al
[ac
], XmNdeleteResponse
, XmUNMAP
); ac
++;
780 result
= XmCreateDialogShell (parent
, "dialog", al
, ac
);
782 XtSetArg(al
[ac
], XmNautoUnmanage
, FALSE
); ac
++;
783 /* XtSetArg(al[ac], XmNautoUnmanage, TRUE); ac++; */ /* ####is this ok? */
784 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
785 form
= XmCreateForm (result
, shell_title
, al
, ac
);
790 XtSetArg(al
[ac
], XmNautoUnmanage
, FALSE
); ac
++;
791 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
792 form
= XmCreateForm (parent
, shell_title
, al
, ac
);
796 n_children
= left_buttons
+ right_buttons
+ 1;
798 XtSetArg(al
[ac
], XmNpacking
, n_children
== 3?
799 XmPACK_COLUMN
: XmPACK_TIGHT
); ac
++;
800 XtSetArg(al
[ac
], XmNorientation
, n_children
== 3?
801 XmVERTICAL
: XmHORIZONTAL
); ac
++;
802 XtSetArg(al
[ac
], XmNnumColumns
, left_buttons
+ right_buttons
+ 1); ac
++;
803 XtSetArg(al
[ac
], XmNmarginWidth
, 0); ac
++;
804 XtSetArg(al
[ac
], XmNmarginHeight
, 0); ac
++;
805 XtSetArg(al
[ac
], XmNspacing
, 13); ac
++;
806 XtSetArg(al
[ac
], XmNadjustLast
, False
); ac
++;
807 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
808 XtSetArg(al
[ac
], XmNisAligned
, True
); ac
++;
809 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
810 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_FORM
); ac
++;
811 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
812 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
813 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
814 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
815 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
816 row
= XmCreateRowColumn (form
, "row", al
, ac
);
819 for (i
= 0; i
< left_buttons
; i
++)
821 char button_name
[16];
822 sprintf (button_name
, "button%d", i
+ 1);
826 XtSetArg(al
[ac
], XmNhighlightThickness
, 1); ac
++;
827 XtSetArg(al
[ac
], XmNshowAsDefault
, TRUE
); ac
++;
829 XtSetArg(al
[ac
], XmNmarginWidth
, 10); ac
++;
830 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
831 children
[n_children
] = XmCreatePushButton (row
, button_name
, al
, ac
);
835 button
= children
[n_children
];
837 XtSetArg(al
[ac
], XmNdefaultButton
, button
); ac
++;
838 XtSetValues (row
, al
, ac
);
844 /* invisible seperator button */
846 XtSetArg (al
[ac
], XmNmappedWhenManaged
, FALSE
); ac
++;
847 children
[n_children
] = XmCreateLabel (row
, "separator_button", al
, ac
);
850 for (i
= 0; i
< right_buttons
; i
++)
852 char button_name
[16];
853 sprintf (button_name
, "button%d", left_buttons
+ i
+ 1);
855 XtSetArg(al
[ac
], XmNmarginWidth
, 10); ac
++;
856 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
857 children
[n_children
] = XmCreatePushButton (row
, button_name
, al
, ac
);
858 if (! button
) button
= children
[n_children
];
862 XtManageChildren (children
, n_children
);
865 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
866 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
867 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
868 XtSetArg(al
[ac
], XmNbottomWidget
, row
); ac
++;
869 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
870 XtSetArg(al
[ac
], XmNleftOffset
, 0); ac
++;
871 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
872 XtSetArg(al
[ac
], XmNrightOffset
, 0); ac
++;
873 separator
= XmCreateSeparator (form
, "", al
, ac
);
876 XtSetArg(al
[ac
], XmNlabelType
, XmPIXMAP
); ac
++;
877 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_FORM
); ac
++;
878 XtSetArg(al
[ac
], XmNtopOffset
, 13); ac
++;
879 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_NONE
); ac
++;
880 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
881 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
882 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_NONE
); ac
++;
883 icon
= XmCreateLabel (form
, icon_name
, al
, ac
);
886 XtSetArg(al
[ac
], XmNmappedWhenManaged
, FALSE
); ac
++;
887 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_WIDGET
); ac
++;
888 XtSetArg(al
[ac
], XmNtopOffset
, 6); ac
++;
889 XtSetArg(al
[ac
], XmNtopWidget
, icon
); ac
++;
890 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
891 XtSetArg(al
[ac
], XmNbottomOffset
, 6); ac
++;
892 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
893 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_NONE
); ac
++;
894 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_NONE
); ac
++;
895 icon_separator
= XmCreateLabel (form
, "", al
, ac
);
900 XtSetArg(al
[ac
], XmNcolumns
, 50); ac
++;
901 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
902 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
903 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
904 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
905 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
906 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
907 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
908 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
909 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
910 value
= XmCreateTextField (form
, "value", al
, ac
);
916 XtSetArg(al
[ac
], XmNmarginWidth
, 0); ac
++;
917 XtSetArg(al
[ac
], XmNmarginHeight
, 0); ac
++;
918 XtSetArg(al
[ac
], XmNspacing
, 13); ac
++;
919 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
920 XtSetArg(al
[ac
], XmNorientation
, XmHORIZONTAL
); ac
++;
921 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
922 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
923 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
924 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
925 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
926 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
927 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
928 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
929 value
= XmCreateRadioBox (form
, "radiobutton1", al
, ac
);
932 radio_butt
= XmCreateToggleButtonGadget (value
, "radio1", al
, ac
);
933 children
[i
++] = radio_butt
;
934 radio_butt
= XmCreateToggleButtonGadget (value
, "radio2", al
, ac
);
935 children
[i
++] = radio_butt
;
936 radio_butt
= XmCreateToggleButtonGadget (value
, "radio3", al
, ac
);
937 children
[i
++] = radio_butt
;
938 XtManageChildren (children
, i
);
943 XtSetArg(al
[ac
], XmNvisibleItemCount
, 5); ac
++;
944 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
945 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
946 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
947 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
948 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
949 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
950 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
951 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
952 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
953 value
= XmCreateScrolledList (form
, "list", al
, ac
);
955 /* this is the easiest way I found to have the dble click in the
956 list activate the default button */
957 XtAddCallback (value
, XmNdefaultActionCallback
, activate_button
, button
);
961 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_BEGINNING
); ac
++;
962 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_FORM
); ac
++;
963 XtSetArg(al
[ac
], XmNtopOffset
, 13); ac
++;
964 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
965 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
966 XtSetArg(al
[ac
], XmNbottomWidget
,
967 text_input_slot
|| radio_box
|| list
? value
: separator
); ac
++;
968 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
969 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
970 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
971 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
972 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
973 message
= XmCreateLabel (form
, "message", al
, ac
);
976 XtManageChild (value
);
979 children
[i
] = row
; i
++;
980 children
[i
] = separator
; i
++;
981 if (text_input_slot
|| radio_box
)
983 children
[i
] = value
; i
++;
985 children
[i
] = message
; i
++;
986 children
[i
] = icon
; i
++;
987 children
[i
] = icon_separator
; i
++;
988 XtManageChildren (children
, i
);
990 if (text_input_slot
|| list
)
992 XtInstallAccelerators (value
, button
);
993 XtSetKeyboardFocus (result
, value
);
997 XtInstallAccelerators (form
, button
);
998 XtSetKeyboardFocus (result
, button
);
1004 static destroyed_instance
*
1005 find_matching_instance (instance
)
1006 widget_instance
* instance
;
1008 destroyed_instance
* cur
;
1009 destroyed_instance
* prev
;
1010 char* type
= instance
->info
->type
;
1011 char* name
= instance
->info
->name
;
1013 for (prev
= NULL
, cur
= all_destroyed_instances
;
1015 prev
= cur
, cur
= cur
->next
)
1017 if (!strcmp (cur
->name
, name
)
1018 && !strcmp (cur
->type
, type
)
1019 && cur
->parent
== instance
->parent
1020 && cur
->pop_up_p
== instance
->pop_up_p
)
1023 prev
->next
= cur
->next
;
1025 all_destroyed_instances
= cur
->next
;
1028 /* do some cleanup */
1029 else if (!cur
->widget
)
1032 prev
->next
= cur
->next
;
1034 all_destroyed_instances
= cur
->next
;
1035 free_destroyed_instance (cur
);
1036 cur
= prev
? prev
: all_destroyed_instances
;
1043 mark_dead_instance_destroyed (widget
, closure
, call_data
)
1046 XtPointer call_data
;
1048 destroyed_instance
* instance
= (destroyed_instance
*)closure
;
1049 instance
->widget
= NULL
;
1053 recenter_widget (widget
)
1056 Widget parent
= XtParent (widget
);
1057 Screen
* screen
= XtScreen (widget
);
1058 Dimension screen_width
= WidthOfScreen (screen
);
1059 Dimension screen_height
= HeightOfScreen (screen
);
1060 Dimension parent_width
= 0;
1061 Dimension parent_height
= 0;
1062 Dimension child_width
= 0;
1063 Dimension child_height
= 0;
1067 XtVaGetValues (widget
, XtNwidth
, &child_width
, XtNheight
, &child_height
, 0);
1068 XtVaGetValues (parent
, XtNwidth
, &parent_width
, XtNheight
, &parent_height
,
1071 x
= (((Position
)parent_width
) - ((Position
)child_width
)) / 2;
1072 y
= (((Position
)parent_height
) - ((Position
)child_height
)) / 2;
1074 XtTranslateCoords (parent
, x
, y
, &x
, &y
);
1076 if (x
+ child_width
> screen_width
)
1077 x
= screen_width
- child_width
;
1081 if (y
+ child_height
> screen_height
)
1082 y
= screen_height
- child_height
;
1086 XtVaSetValues (widget
, XtNx
, x
, XtNy
, y
, 0);
1090 recycle_instance (instance
)
1091 destroyed_instance
* instance
;
1093 Widget widget
= instance
->widget
;
1095 /* widget is NULL if the parent was destroyed. */
1101 /* Remove the destroy callback as the instance is not in the list
1103 XtRemoveCallback (instance
->parent
, XtNdestroyCallback
,
1104 mark_dead_instance_destroyed
,
1105 (XtPointer
)instance
);
1107 /* Give the focus to the initial item */
1108 focus
= XtNameToWidget (widget
, "*value");
1110 focus
= XtNameToWidget (widget
, "*button1");
1112 XtSetKeyboardFocus (widget
, focus
);
1114 /* shrink the separator label back to their original size */
1115 separator
= XtNameToWidget (widget
, "*separator_button");
1117 XtVaSetValues (separator
, XtNwidth
, 5, XtNheight
, 5, 0);
1119 /* Center the dialog in its parent */
1120 recenter_widget (widget
);
1122 free_destroyed_instance (instance
);
1127 xm_create_dialog (instance
)
1128 widget_instance
* instance
;
1130 char* name
= instance
->info
->type
;
1131 Widget parent
= instance
->parent
;
1133 Boolean pop_up_p
= instance
->pop_up_p
;
1134 char* shell_name
= 0;
1136 Boolean text_input_slot
= False
;
1137 Boolean radio_box
= False
;
1138 Boolean list
= False
;
1140 int left_buttons
= 0;
1141 int right_buttons
= 1;
1142 destroyed_instance
* dead_one
;
1144 /* try to find a widget to recycle */
1145 dead_one
= find_matching_instance (instance
);
1148 Widget recycled_widget
= recycle_instance (dead_one
);
1149 if (recycled_widget
)
1150 return recycled_widget
;
1155 icon_name
= "dbox-error";
1156 shell_name
= "Error";
1160 icon_name
= "dbox-info";
1161 shell_name
= "Information";
1166 icon_name
= "dbox-question";
1167 shell_name
= "Prompt";
1171 text_input_slot
= True
;
1172 icon_name
= "dbox-question";
1173 shell_name
= "Prompt";
1177 icon_name
= "dbox-question";
1178 shell_name
= "Question";
1182 total_buttons
= name
[1] - '0';
1184 if (name
[3] == 'T' || name
[3] == 't')
1186 text_input_slot
= False
;
1190 right_buttons
= name
[4] - '0';
1192 left_buttons
= total_buttons
- right_buttons
;
1194 widget
= make_dialog (name
, parent
, pop_up_p
,
1195 shell_name
, icon_name
, text_input_slot
, radio_box
,
1196 list
, left_buttons
, right_buttons
);
1198 XtAddCallback (widget
, XmNpopdownCallback
, xm_nosel_callback
,
1199 (XtPointer
) instance
);
1204 make_menubar (instance
)
1205 widget_instance
* instance
;
1207 return XmCreateMenuBar (instance
->parent
, instance
->info
->name
, NULL
, 0);
1211 remove_grabs (shell
, closure
, call_data
)
1214 XtPointer call_data
;
1216 Widget menu
= (Widget
) closure
;
1217 XmRemoveFromPostFromList (menu
, XtParent (XtParent (menu
)));
1221 make_popup_menu (instance
)
1222 widget_instance
* instance
;
1224 Widget parent
= instance
->parent
;
1225 Window parent_window
= parent
->core
.window
;
1228 /* sets the parent window to 0 to fool Motif into not generating a grab */
1229 parent
->core
.window
= 0;
1230 result
= XmCreatePopupMenu (parent
, instance
->info
->name
, NULL
, 0);
1231 XtAddCallback (XtParent (result
), XmNpopdownCallback
, remove_grabs
,
1233 parent
->core
.window
= parent_window
;
1237 make_main (instance
)
1238 widget_instance
* instance
;
1240 Widget parent
= instance
->parent
;
1246 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
1247 XtSetArg (al
[ac
], XmNspacing
, 0); ac
++;
1248 result
= XmCreateMainWindow (parent
, instance
->info
->name
, al
, ac
);
1252 \f/* Table of functions to create widgets */
1256 /* interface with the XDesigner generated functions */
1257 typedef Widget (*widget_maker
) (Widget
);
1258 extern Widget
create_project_p_sheet (Widget parent
);
1259 extern Widget
create_debugger_p_sheet (Widget parent
);
1260 extern Widget
create_breaklist_p_sheet (Widget parent
);
1261 extern Widget
create_le_browser_p_sheet (Widget parent
);
1262 extern Widget
create_class_browser_p_sheet (Widget parent
);
1263 extern Widget
create_call_browser_p_sheet (Widget parent
);
1264 extern Widget
create_build_dialog (Widget parent
);
1265 extern Widget
create_editmode_dialog (Widget parent
);
1266 extern Widget
create_search_dialog (Widget parent
);
1267 extern Widget
create_project_display_dialog (Widget parent
);
1270 make_one (widget_instance
* instance
, widget_maker fn
)
1276 if (instance
->pop_up_p
)
1278 XtSetArg (al
[ac
], XmNallowShellResize
, TRUE
); ac
++;
1279 result
= XmCreateDialogShell (instance
->parent
, "dialog", NULL
, 0);
1280 XtAddCallback (result
, XmNpopdownCallback
, &xm_nosel_callback
,
1281 (XtPointer
) instance
);
1286 result
= (*fn
) (instance
->parent
);
1287 XtRealizeWidget (result
);
1293 make_project_p_sheet (widget_instance
* instance
)
1295 return make_one (instance
, create_project_p_sheet
);
1299 make_debugger_p_sheet (widget_instance
* instance
)
1301 return make_one (instance
, create_debugger_p_sheet
);
1305 make_breaklist_p_sheet (widget_instance
* instance
)
1307 return make_one (instance
, create_breaklist_p_sheet
);
1311 make_le_browser_p_sheet (widget_instance
* instance
)
1313 return make_one (instance
, create_le_browser_p_sheet
);
1317 make_class_browser_p_sheet (widget_instance
* instance
)
1319 return make_one (instance
, create_class_browser_p_sheet
);
1323 make_call_browser_p_sheet (widget_instance
* instance
)
1325 return make_one (instance
, create_call_browser_p_sheet
);
1329 make_build_dialog (widget_instance
* instance
)
1331 return make_one (instance
, create_build_dialog
);
1335 make_editmode_dialog (widget_instance
* instance
)
1337 return make_one (instance
, create_editmode_dialog
);
1341 make_search_dialog (widget_instance
* instance
)
1343 return make_one (instance
, create_search_dialog
);
1347 make_project_display_dialog (widget_instance
* instance
)
1349 return make_one (instance
, create_project_display_dialog
);
1352 #endif /* ENERGIZE */
1354 widget_creation_entry
1355 xm_creation_table
[] =
1357 {"menubar", make_menubar
},
1358 {"popup", make_popup_menu
},
1359 {"main", make_main
},
1361 {"project_p_sheet", make_project_p_sheet
},
1362 {"debugger_p_sheet", make_debugger_p_sheet
},
1363 {"breaklist_psheet", make_breaklist_p_sheet
},
1364 {"leb_psheet", make_le_browser_p_sheet
},
1365 {"class_browser_psheet", make_class_browser_p_sheet
},
1366 {"ctree_browser_psheet", make_call_browser_p_sheet
},
1367 {"build", make_build_dialog
},
1368 {"editmode", make_editmode_dialog
},
1369 {"search", make_search_dialog
},
1370 {"project_display", make_project_display_dialog
},
1371 #endif /* ENERGIZE */
1375 \f/* Destruction of instances */
1377 xm_destroy_instance (instance
)
1378 widget_instance
* instance
;
1380 Widget widget
= instance
->widget
;
1381 /* recycle the dialog boxes */
1382 /* Disable the recycling until we can find a way to have the dialog box
1383 get reasonable layout after we modify its contents. */
1385 && XtClass (widget
) == xmDialogShellWidgetClass
)
1387 destroyed_instance
* dead_instance
=
1388 make_destroyed_instance (instance
->info
->name
,
1389 instance
->info
->type
,
1392 instance
->pop_up_p
);
1393 dead_instance
->next
= all_destroyed_instances
;
1394 all_destroyed_instances
= dead_instance
;
1395 XtUnmanageChild (first_child (instance
->widget
));
1396 XFlush (XtDisplay (instance
->widget
));
1397 XtAddCallback (instance
->parent
, XtNdestroyCallback
,
1398 mark_dead_instance_destroyed
, (XtPointer
)dead_instance
);
1402 /* This might not be necessary now that the nosel is attached to
1403 popdown instead of destroy, but it can't hurt. */
1404 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
1405 xm_nosel_callback
, (XtPointer
)instance
);
1406 XtDestroyWidget (instance
->widget
);
1410 \f/* popup utility */
1412 xm_popup_menu (widget
, event
)
1416 XButtonPressedEvent dummy
;
1420 dummy
.type
= ButtonPress
;
1422 dummy
.send_event
= 0;
1423 dummy
.display
= XtDisplay (widget
);
1424 dummy
.window
= XtWindow (XtParent (widget
));
1427 XQueryPointer (dummy
.display
, dummy
.window
, &dummy
.root
,
1428 &dummy
.subwindow
, &dummy
.x_root
, &dummy
.y_root
,
1429 &dummy
.x
, &dummy
.y
, &dummy
.state
);
1430 event
= (XEvent
*) &dummy
;
1433 if (event
->type
== ButtonPress
|| event
->type
== ButtonRelease
)
1435 /* This is so totally ridiculous: there's NO WAY to tell Motif
1436 that *any* button can select a menu item. Only one button
1437 can have that honor.
1440 if (event
->xbutton
.state
& Button5Mask
) trans
= "<Btn5Down>";
1441 else if (event
->xbutton
.state
& Button4Mask
) trans
= "<Btn4Down>";
1442 else if (event
->xbutton
.state
& Button3Mask
) trans
= "<Btn3Down>";
1443 else if (event
->xbutton
.state
& Button2Mask
) trans
= "<Btn2Down>";
1444 else if (event
->xbutton
.state
& Button1Mask
) trans
= "<Btn1Down>";
1445 if (trans
) XtVaSetValues (widget
, XmNmenuPost
, trans
, 0);
1446 XmMenuPosition (widget
, (XButtonPressedEvent
*) event
);
1448 XtManageChild (widget
);
1452 set_min_dialog_size (w
)
1457 XtVaGetValues (w
, XmNwidth
, &width
, XmNheight
, &height
, 0);
1458 XtVaSetValues (w
, XmNminWidth
, width
, XmNminHeight
, height
, 0);
1462 xm_pop_instance (instance
, up
)
1463 widget_instance
* instance
;
1466 Widget widget
= instance
->widget
;
1468 if (XtClass (widget
) == xmDialogShellWidgetClass
)
1470 Widget widget_to_manage
= first_child (widget
);
1473 XtManageChild (widget_to_manage
);
1474 set_min_dialog_size (widget
);
1475 XtSetKeyboardFocus (instance
->parent
, widget
);
1478 XtUnmanageChild (widget_to_manage
);
1483 XtManageChild (widget
);
1485 XtUnmanageChild (widget
);
1490 /* motif callback */
1492 enum do_call_type
{ pre_activate
, selection
, no_selection
, post_activate
};
1495 do_call (widget
, closure
, type
)
1498 enum do_call_type type
;
1502 XtPointer user_data
;
1503 widget_instance
* instance
= (widget_instance
*)closure
;
1504 Widget instance_widget
;
1509 if (widget
->core
.being_destroyed
)
1512 instance_widget
= instance
->widget
;
1513 if (!instance_widget
)
1516 id
= instance
->info
->id
;
1519 XtSetArg (al
[ac
], XmNuserData
, &user_data
); ac
++;
1520 XtGetValues (widget
, al
, ac
);
1524 if (instance
->info
->pre_activate_cb
)
1525 instance
->info
->pre_activate_cb (widget
, id
, user_data
);
1528 if (instance
->info
->selection_cb
)
1529 instance
->info
->selection_cb (widget
, id
, user_data
);
1532 if (instance
->info
->selection_cb
)
1533 instance
->info
->selection_cb (widget
, id
, (XtPointer
) -1);
1536 if (instance
->info
->post_activate_cb
)
1537 instance
->info
->post_activate_cb (widget
, id
, user_data
);
1544 /* Like lw_internal_update_other_instances except that it does not do
1545 anything if its shell parent is not managed. This is to protect
1546 lw_internal_update_other_instances to dereference freed memory
1547 if the widget was ``destroyed'' by caching it in the all_destroyed_instances
1550 xm_internal_update_other_instances (widget
, closure
, call_data
)
1553 XtPointer call_data
;
1556 for (parent
= widget
; parent
; parent
= XtParent (parent
))
1557 if (XtIsShell (parent
))
1559 else if (!XtIsManaged (parent
))
1561 lw_internal_update_other_instances (widget
, closure
, call_data
);
1565 xm_generic_callback (widget
, closure
, call_data
)
1568 XtPointer call_data
;
1570 lw_internal_update_other_instances (widget
, closure
, call_data
);
1571 do_call (widget
, closure
, selection
);
1575 xm_nosel_callback (widget
, closure
, call_data
)
1578 XtPointer call_data
;
1580 /* This callback is only called when a dialog box is dismissed with the wm's
1581 destroy button (WM_DELETE_WINDOW.) We want the dialog box to be destroyed
1582 in that case, not just unmapped, so that it releases its keyboard grabs.
1583 But there are problems with running our callbacks while the widget is in
1584 the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
1585 instead of XmDESTROY and then destroy it ourself after having run the
1588 do_call (widget
, closure
, no_selection
);
1589 XtDestroyWidget (widget
);
1593 xm_pull_down_callback (widget
, closure
, call_data
)
1596 XtPointer call_data
;
1598 do_call (widget
, closure
, pre_activate
);
1602 xm_pop_down_callback (widget
, closure
, call_data
)
1605 XtPointer call_data
;
1607 widget_instance
*instance
= (widget_instance
*) closure
;
1609 if ((!instance
->pop_up_p
&& (XtParent (widget
) == instance
->widget
))
1610 || (XtParent (widget
) == instance
->parent
))
1611 do_call (widget
, closure
, post_activate
);
1615 /* set the keyboard focus */
1617 xm_set_keyboard_focus (parent
, w
)
1621 XmProcessTraversal (w
, 0);
1622 XtSetKeyboardFocus (parent
, w
);
1625 /* Motif hack to set the main window areas. */
1627 xm_set_main_areas (parent
, menubar
, work_area
)
1632 XmMainWindowSetAreas (parent
,
1633 menubar
, /* menubar (maybe 0) */
1634 0, /* command area (psheets) */
1635 0, /* horizontal scroll */
1636 0, /* vertical scroll */
1637 work_area
); /* work area */
1640 /* Motif hack to control resizing on the menubar. */
1642 xm_manage_resizing (w
, flag
)
1648 /* Enable the edit widget for resizing. */
1651 XtSetArg (al
[0], XtNallowShellResize
, 0);
1652 XtSetValues (w
, al
, 1);
1656 /* Disable the edit widget from resizing. */
1659 XtSetArg (al
[0], XtNallowShellResize
, 0);
1660 XtSetValues (w
, al
, 1);