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
);
66 xm_update_menu (widget_instance
* instance
, Widget widget
, widget_value
* val
,
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 (char* name
, char* type
, Widget widget
, Widget parent
,
87 destroyed_instance
* instance
=
88 (destroyed_instance
*)malloc (sizeof (destroyed_instance
));
89 instance
->name
= safe_strdup (name
);
90 instance
->type
= safe_strdup (type
);
91 instance
->widget
= widget
;
92 instance
->parent
= parent
;
93 instance
->pop_up_p
= pop_up_p
;
94 instance
->next
= NULL
;
99 free_destroyed_instance (destroyed_instance
* instance
)
101 free (instance
->name
);
102 free (instance
->type
);
106 \f/* motif utility functions */
108 first_child (Widget widget
)
110 return ((CompositeWidget
)widget
)->composite
.children
[0];
114 lw_motif_widget_p (Widget widget
)
117 XtClass (widget
) == xmDialogShellWidgetClass
118 || XmIsPrimitive (widget
) || XmIsManager (widget
) || XmIsGadget (widget
);
122 resource_motif_string (Widget widget
, char* name
)
127 resource
.resource_name
= name
;
128 resource
.resource_class
= XmCXmString
;
129 resource
.resource_type
= XmRXmString
;
130 resource
.resource_size
= sizeof (XmString
);
131 resource
.resource_offset
= 0;
132 resource
.default_type
= XtRImmediate
;
133 resource
.default_addr
= 0;
135 XtGetSubresources (widget
, (XtPointer
)&result
, "dialogString",
136 "DialogString", &resource
, 1, NULL
, 0);
141 destroy_all_children (Widget widget
)
147 children
= XtCompositeChildren (widget
, &number
);
150 /* Unmanage all children and destroy them. They will only be
151 * really destroyed when we get out of DispatchEvent. */
152 for (i
= 0; i
< number
; i
++)
154 Widget child
= children
[i
];
155 if (!child
->core
.being_destroyed
)
157 XtUnmanageChild (child
);
158 XtDestroyWidget (child
);
161 XtFree ((char *) children
);
165 \f/* update the label of anything subclass of a label */
167 xm_update_label (widget_instance
* instance
, Widget widget
, widget_value
* val
)
169 XmString res_string
= 0;
170 XmString built_string
= 0;
171 XmString key_string
= 0;
179 res_string
= resource_motif_string (widget
, val
->value
);
183 XtSetArg (al
[ac
], XmNlabelString
, res_string
); ac
++;
188 XmStringCreateLtoR (val
->value
, XmSTRING_DEFAULT_CHARSET
);
189 XtSetArg (al
[ac
], XmNlabelString
, built_string
); ac
++;
191 XtSetArg (al
[ac
], XmNlabelType
, XmSTRING
); ac
++;
196 key_string
= XmStringCreateLtoR (val
->key
, XmSTRING_DEFAULT_CHARSET
);
197 XtSetArg (al
[ac
], XmNacceleratorText
, key_string
); ac
++;
201 XtSetValues (widget
, al
, ac
);
204 XmStringFree (built_string
);
207 XmStringFree (key_string
);
210 \f/* update of list */
212 xm_update_list (widget_instance
* instance
, Widget widget
, widget_value
* val
)
216 XtRemoveAllCallbacks (widget
, XmNsingleSelectionCallback
);
217 XtAddCallback (widget
, XmNsingleSelectionCallback
, xm_generic_callback
,
219 for (cur
= val
->contents
, i
= 0; cur
; cur
= cur
->next
)
222 XmString xmstr
= XmStringCreate (cur
->value
, XmSTRING_DEFAULT_CHARSET
);
224 XmListAddItem (widget
, xmstr
, 0);
226 XmListSelectPos (widget
, i
, False
);
227 XmStringFree (xmstr
);
231 \f/* update of buttons */
233 xm_update_pushbutton (widget_instance
* instance
, Widget widget
,
236 XtVaSetValues (widget
, XmNalignment
, XmALIGNMENT_CENTER
, 0);
237 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
238 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
242 xm_update_cascadebutton (widget_instance
* instance
, Widget widget
,
245 /* Should also rebuild the menu by calling ...update_menu... */
246 XtRemoveAllCallbacks (widget
, XmNcascadingCallback
);
247 XtAddCallback (widget
, XmNcascadingCallback
, xm_pull_down_callback
,
251 \f/* update toggle and radiobox */
253 xm_update_toggle (widget_instance
* instance
, Widget widget
, widget_value
* val
)
255 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
256 XtAddCallback (widget
, XmNvalueChangedCallback
,
257 xm_internal_update_other_instances
, instance
);
258 XtVaSetValues (widget
, XmNset
, val
->selected
,
259 XmNalignment
, XmALIGNMENT_BEGINNING
, 0);
263 xm_update_radiobox (widget_instance
* instance
, Widget widget
,
269 /* update the callback */
270 XtRemoveAllCallbacks (widget
, XmNentryCallback
);
271 XtAddCallback (widget
, XmNentryCallback
, xm_generic_callback
, instance
);
273 /* first update all the toggles */
274 /* Energize kernel interface is currently bad. It sets the selected widget
275 with the selected flag but returns it by its name. So we currently
276 have to support both setting the selection with the selected slot
277 of val contents and setting it with the "value" slot of val. The latter
278 has a higher priority. This to be removed when the kernel is fixed. */
279 for (cur
= val
->contents
; cur
; cur
= cur
->next
)
281 toggle
= XtNameToWidget (widget
, cur
->value
);
284 XtVaSetValues (toggle
, XmNsensitive
, cur
->enabled
, 0);
285 if (!val
->value
&& cur
->selected
)
286 XtVaSetValues (toggle
, XmNset
, cur
->selected
, 0);
287 if (val
->value
&& strcmp (val
->value
, cur
->value
))
288 XtVaSetValues (toggle
, XmNset
, False
, 0);
292 /* The selected was specified by the value slot */
295 toggle
= XtNameToWidget (widget
, val
->value
);
297 XtVaSetValues (toggle
, XmNset
, True
, 0);
301 \f/* update a popup menu, pulldown menu or a menubar */
303 all_dashes_p (char* s
)
313 make_menu_in_widget (widget_instance
* instance
, Widget widget
,
316 Widget
* children
= 0;
326 /* Allocate the children array */
327 for (num_children
= 0, cur
= val
; cur
; num_children
++, cur
= cur
->next
);
328 children
= (Widget
*)XtMalloc (num_children
* sizeof (Widget
));
330 /* tricky way to know if this RowColumn is a menubar or a pulldown... */
332 XtSetArg (al
[0], XmNisHomogeneous
, &menubar_p
);
333 XtGetValues (widget
, al
, 1);
335 /* add the unmap callback for popups and pulldowns */
336 /*** this sounds bogus ***/
338 XtAddCallback (XtParent (widget
), XmNpopdownCallback
,
339 xm_pop_down_callback
, (XtPointer
)instance
);
341 for (child_index
= 0, cur
= val
; cur
; child_index
++, cur
= cur
->next
)
344 XtSetArg (al
[ac
], XmNsensitive
, cur
->enabled
); ac
++;
345 XtSetArg (al
[ac
], XmNalignment
, XmALIGNMENT_BEGINNING
); ac
++;
346 XtSetArg (al
[ac
], XmNuserData
, cur
->call_data
); ac
++;
348 if (instance
->pop_up_p
&& !cur
->contents
&& !cur
->call_data
349 && !all_dashes_p (cur
->name
))
352 XtSetArg (al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
353 button
= XmCreateLabel (widget
, cur
->name
, al
, ac
);
355 else if (all_dashes_p (cur
->name
))
357 button
= XmCreateSeparator (widget
, cur
->name
, NULL
, 0);
359 else if (!cur
->contents
)
362 button
= XmCreateCascadeButton (widget
, cur
->name
, al
, ac
);
363 else if (!cur
->call_data
)
364 button
= XmCreateLabel (widget
, cur
->name
, al
, ac
);
366 button
= XmCreatePushButtonGadget (widget
, cur
->name
, al
, ac
);
368 xm_update_label (instance
, button
, cur
);
370 /* don't add a callback to a simple label */
372 XtAddCallback (button
, XmNactivateCallback
, xm_generic_callback
,
373 (XtPointer
)instance
);
377 menu
= XmCreatePulldownMenu (widget
, "pulldown", NULL
, 0);
378 make_menu_in_widget (instance
, menu
, cur
->contents
);
379 XtSetArg (al
[ac
], XmNsubMenuId
, menu
); ac
++;
380 button
= XmCreateCascadeButton (widget
, cur
->name
, al
, ac
);
382 xm_update_label (instance
, button
, cur
);
384 XtAddCallback (button
, XmNcascadingCallback
, xm_pull_down_callback
,
385 (XtPointer
)instance
);
388 children
[child_index
] = button
;
391 XtManageChildren (children
, num_children
);
393 /* Last entry is the help button. Has to be done after managing
394 * the buttons otherwise the menubar is only 4 pixels high... */
398 XtSetArg (al
[ac
], XmNmenuHelpWidget
, button
); ac
++;
399 XtSetValues (widget
, al
, ac
);
402 XtFree ((char *) children
);
406 update_one_menu_entry (widget_instance
* instance
, Widget widget
,
407 widget_value
* val
, Boolean deep_p
)
412 widget_value
* contents
;
414 if (val
->change
== NO_CHANGE
)
417 /* update the sensitivity and userdata */
418 /* Common to all widget types */
419 XtVaSetValues (widget
,
420 XmNsensitive
, val
->enabled
,
421 XmNuserData
, val
->call_data
,
424 /* update the menu button as a label. */
425 if (val
->change
>= VISIBLE_CHANGE
)
426 xm_update_label (instance
, widget
, val
);
428 /* update the pulldown/pullaside as needed */
431 XtSetArg (al
[ac
], XmNsubMenuId
, &menu
); ac
++;
432 XtGetValues (widget
, al
, ac
);
434 contents
= val
->contents
;
440 menu
= XmCreatePulldownMenu (XtParent (widget
), "pulldown", NULL
, 0);
441 make_menu_in_widget (instance
, menu
, contents
);
443 XtSetArg (al
[ac
], XmNsubMenuId
, menu
); ac
++;
444 XtSetValues (widget
, al
, ac
);
450 XtSetArg (al
[ac
], XmNsubMenuId
, NULL
); ac
++;
451 XtSetValues (widget
, al
, ac
);
452 XtDestroyWidget (menu
);
454 else if (deep_p
&& contents
->change
!= NO_CHANGE
)
455 xm_update_menu (instance
, menu
, val
, 1);
459 xm_update_menu (widget_instance
* instance
, Widget widget
, widget_value
* val
,
462 /* Widget is a RowColumn widget whose contents have to be updated
463 * to reflect the list of items in val->contents */
464 if (val
->contents
->change
== STRUCTURAL_CHANGE
)
466 destroy_all_children (widget
);
467 make_menu_in_widget (instance
, widget
, val
->contents
);
471 /* Update all the buttons of the RowColumn in order. */
473 unsigned int num_children
;
477 children
= XtCompositeChildren (widget
, &num_children
);
480 for (i
= 0, cur
= val
->contents
; i
< num_children
; i
++)
484 if (children
[i
]->core
.being_destroyed
485 || strcmp (XtName (children
[i
]), cur
->name
))
487 update_one_menu_entry (instance
, children
[i
], cur
, deep_p
);
490 XtFree ((char *) children
);
498 /* update text widgets */
501 xm_update_text (widget_instance
* instance
, Widget widget
, widget_value
* val
)
503 XmTextSetString (widget
, val
->value
? val
->value
: "");
504 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
505 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
506 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
507 XtAddCallback (widget
, XmNvalueChangedCallback
,
508 xm_internal_update_other_instances
, instance
);
512 xm_update_text_field (widget_instance
* instance
, Widget widget
,
515 XmTextFieldSetString (widget
, val
->value
? val
->value
: "");
516 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
517 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
518 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
519 XtAddCallback (widget
, XmNvalueChangedCallback
,
520 xm_internal_update_other_instances
, instance
);
524 /* update a motif widget */
527 xm_update_one_widget (widget_instance
* instance
, Widget widget
,
528 widget_value
* val
, Boolean deep_p
)
532 /* Mark as not edited */
535 /* Common to all widget types */
536 XtVaSetValues (widget
,
537 XmNsensitive
, val
->enabled
,
538 XmNuserData
, val
->call_data
,
541 /* Common to all label like widgets */
542 if (XtIsSubclass (widget
, xmLabelWidgetClass
))
543 xm_update_label (instance
, widget
, val
);
545 class = XtClass (widget
);
546 /* Class specific things */
547 if (class == xmPushButtonWidgetClass
||
548 class == xmArrowButtonWidgetClass
)
550 xm_update_pushbutton (instance
, widget
, val
);
552 else if (class == xmCascadeButtonWidgetClass
)
554 xm_update_cascadebutton (instance
, widget
, val
);
556 else if (class == xmToggleButtonWidgetClass
557 || class == xmToggleButtonGadgetClass
)
559 xm_update_toggle (instance
, widget
, val
);
561 else if (class == xmRowColumnWidgetClass
)
563 Boolean radiobox
= 0;
567 XtSetArg (al
[ac
], XmNradioBehavior
, &radiobox
); ac
++;
568 XtGetValues (widget
, al
, ac
);
571 xm_update_radiobox (instance
, widget
, val
);
573 xm_update_menu (instance
, widget
, val
, deep_p
);
575 else if (class == xmTextWidgetClass
)
577 xm_update_text (instance
, widget
, val
);
579 else if (class == xmTextFieldWidgetClass
)
581 xm_update_text_field (instance
, widget
, val
);
583 else if (class == xmListWidgetClass
)
585 xm_update_list (instance
, widget
, val
);
589 \f/* getting the value back */
591 xm_update_one_value (widget_instance
* instance
, Widget widget
,
594 WidgetClass
class = XtClass (widget
);
595 widget_value
*old_wv
;
597 /* copy the call_data slot into the "return" widget_value */
598 for (old_wv
= instance
->info
->val
->contents
; old_wv
; old_wv
= old_wv
->next
)
599 if (!strcmp (val
->name
, old_wv
->name
))
601 val
->call_data
= old_wv
->call_data
;
605 if (class == xmToggleButtonWidgetClass
|| class == xmToggleButtonGadgetClass
)
607 XtVaGetValues (widget
, XmNset
, &val
->selected
, 0);
610 else if (class == xmTextWidgetClass
)
614 val
->value
= XmTextGetString (widget
);
617 else if (class == xmTextFieldWidgetClass
)
621 val
->value
= XmTextFieldGetString (widget
);
624 else if (class == xmRowColumnWidgetClass
)
626 Boolean radiobox
= 0;
630 XtSetArg (al
[ac
], XmNradioBehavior
, &radiobox
); ac
++;
631 XtGetValues (widget
, al
, ac
);
635 CompositeWidget radio
= (CompositeWidget
)widget
;
637 for (i
= 0; i
< radio
->composite
.num_children
; i
++)
640 Widget toggle
= radio
->composite
.children
[i
];
642 XtVaGetValues (toggle
, XmNset
, &set
, 0);
647 val
->value
= safe_strdup (XtName (toggle
));
653 else if (class == xmListWidgetClass
)
657 if (XmListGetSelectedPos (widget
, &pos_list
, &pos_cnt
))
661 for (cur
= val
->contents
, i
= 0; cur
; cur
= cur
->next
)
665 cur
->selected
= False
;
667 for (j
= 0; j
< pos_cnt
; j
++)
668 if (pos_list
[j
] == i
)
670 cur
->selected
= True
;
671 val
->value
= safe_strdup (cur
->name
);
675 XtFree ((char *) pos_list
);
681 /* This function is for activating a button from a program. It's wrong because
682 we pass a NULL argument in the call_data which is not Motif compatible.
683 This is used from the XmNdefaultAction callback of the List widgets to
684 have a dble-click put down a dialog box like the button woudl do.
685 I could not find a way to do that with accelerators.
688 activate_button (Widget widget
, XtPointer closure
, XtPointer call_data
)
690 Widget button
= (Widget
)closure
;
691 XtCallCallbacks (button
, XmNactivateCallback
, NULL
);
694 /* creation functions */
698 make_dialog (char* name
, Widget parent
, Boolean pop_up_p
,
699 char* shell_title
, char* icon_name
, Boolean text_input_slot
,
700 Boolean radio_box
, Boolean list
,
701 int left_buttons
, int right_buttons
)
707 Widget icon_separator
;
712 Widget children
[16]; /* for the final XtManageChildren */
714 Arg al
[64]; /* Arg List */
715 int ac
; /* Arg Count */
721 XtSetArg(al
[ac
], XmNtitle
, shell_title
); ac
++;
722 XtSetArg(al
[ac
], XtNallowShellResize
, True
); ac
++;
723 XtSetArg(al
[ac
], XmNdeleteResponse
, XmUNMAP
); ac
++;
724 result
= XmCreateDialogShell (parent
, "dialog", al
, ac
);
726 XtSetArg(al
[ac
], XmNautoUnmanage
, FALSE
); ac
++;
727 /* XtSetArg(al[ac], XmNautoUnmanage, TRUE); ac++; */ /* ####is this ok? */
728 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
729 form
= XmCreateForm (result
, shell_title
, al
, ac
);
734 XtSetArg(al
[ac
], XmNautoUnmanage
, FALSE
); ac
++;
735 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
736 form
= XmCreateForm (parent
, shell_title
, al
, ac
);
740 n_children
= left_buttons
+ right_buttons
+ 1;
742 XtSetArg(al
[ac
], XmNpacking
, n_children
== 3?
743 XmPACK_COLUMN
: XmPACK_TIGHT
); ac
++;
744 XtSetArg(al
[ac
], XmNorientation
, n_children
== 3?
745 XmVERTICAL
: XmHORIZONTAL
); ac
++;
746 XtSetArg(al
[ac
], XmNnumColumns
, left_buttons
+ right_buttons
+ 1); ac
++;
747 XtSetArg(al
[ac
], XmNmarginWidth
, 0); ac
++;
748 XtSetArg(al
[ac
], XmNmarginHeight
, 0); ac
++;
749 XtSetArg(al
[ac
], XmNspacing
, 13); ac
++;
750 XtSetArg(al
[ac
], XmNadjustLast
, False
); ac
++;
751 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
752 XtSetArg(al
[ac
], XmNisAligned
, True
); ac
++;
753 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
754 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_FORM
); ac
++;
755 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
756 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
757 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
758 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
759 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
760 row
= XmCreateRowColumn (form
, "row", al
, ac
);
763 for (i
= 0; i
< left_buttons
; i
++)
765 char button_name
[16];
766 sprintf (button_name
, "button%d", i
+ 1);
770 XtSetArg(al
[ac
], XmNhighlightThickness
, 1); ac
++;
771 XtSetArg(al
[ac
], XmNshowAsDefault
, TRUE
); ac
++;
773 XtSetArg(al
[ac
], XmNmarginWidth
, 10); ac
++;
774 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
775 children
[n_children
] = XmCreatePushButton (row
, button_name
, al
, ac
);
779 button
= children
[n_children
];
781 XtSetArg(al
[ac
], XmNdefaultButton
, button
); ac
++;
782 XtSetValues (row
, al
, ac
);
788 /* invisible seperator button */
790 XtSetArg (al
[ac
], XmNmappedWhenManaged
, FALSE
); ac
++;
791 children
[n_children
] = XmCreateLabel (row
, "separator_button", al
, ac
);
794 for (i
= 0; i
< right_buttons
; i
++)
796 char button_name
[16];
797 sprintf (button_name
, "button%d", left_buttons
+ i
+ 1);
799 XtSetArg(al
[ac
], XmNmarginWidth
, 10); ac
++;
800 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
801 children
[n_children
] = XmCreatePushButton (row
, button_name
, al
, ac
);
802 if (! button
) button
= children
[n_children
];
806 XtManageChildren (children
, n_children
);
809 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
810 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
811 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
812 XtSetArg(al
[ac
], XmNbottomWidget
, row
); ac
++;
813 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
814 XtSetArg(al
[ac
], XmNleftOffset
, 0); ac
++;
815 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
816 XtSetArg(al
[ac
], XmNrightOffset
, 0); ac
++;
817 separator
= XmCreateSeparator (form
, "", al
, ac
);
820 XtSetArg(al
[ac
], XmNlabelType
, XmPIXMAP
); ac
++;
821 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_FORM
); ac
++;
822 XtSetArg(al
[ac
], XmNtopOffset
, 13); ac
++;
823 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_NONE
); ac
++;
824 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
825 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
826 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_NONE
); ac
++;
827 icon
= XmCreateLabel (form
, icon_name
, al
, ac
);
830 XtSetArg(al
[ac
], XmNmappedWhenManaged
, FALSE
); ac
++;
831 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_WIDGET
); ac
++;
832 XtSetArg(al
[ac
], XmNtopOffset
, 6); ac
++;
833 XtSetArg(al
[ac
], XmNtopWidget
, icon
); ac
++;
834 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
835 XtSetArg(al
[ac
], XmNbottomOffset
, 6); ac
++;
836 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
837 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_NONE
); ac
++;
838 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_NONE
); ac
++;
839 icon_separator
= XmCreateLabel (form
, "", al
, ac
);
844 XtSetArg(al
[ac
], XmNcolumns
, 50); ac
++;
845 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
846 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
847 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
848 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
849 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
850 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
851 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
852 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
853 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
854 value
= XmCreateTextField (form
, "value", al
, ac
);
860 XtSetArg(al
[ac
], XmNmarginWidth
, 0); ac
++;
861 XtSetArg(al
[ac
], XmNmarginHeight
, 0); ac
++;
862 XtSetArg(al
[ac
], XmNspacing
, 13); ac
++;
863 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
864 XtSetArg(al
[ac
], XmNorientation
, XmHORIZONTAL
); ac
++;
865 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
866 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
867 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
868 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
869 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
870 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
871 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
872 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
873 value
= XmCreateRadioBox (form
, "radiobutton1", al
, ac
);
876 radio_butt
= XmCreateToggleButtonGadget (value
, "radio1", al
, ac
);
877 children
[i
++] = radio_butt
;
878 radio_butt
= XmCreateToggleButtonGadget (value
, "radio2", al
, ac
);
879 children
[i
++] = radio_butt
;
880 radio_butt
= XmCreateToggleButtonGadget (value
, "radio3", al
, ac
);
881 children
[i
++] = radio_butt
;
882 XtManageChildren (children
, i
);
887 XtSetArg(al
[ac
], XmNvisibleItemCount
, 5); ac
++;
888 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
889 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
890 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
891 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
892 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
893 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
894 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
895 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
896 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
897 value
= XmCreateScrolledList (form
, "list", al
, ac
);
899 /* this is the easiest way I found to have the dble click in the
900 list activate the default button */
901 XtAddCallback (value
, XmNdefaultActionCallback
, activate_button
, button
);
905 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_BEGINNING
); ac
++;
906 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_FORM
); ac
++;
907 XtSetArg(al
[ac
], XmNtopOffset
, 13); ac
++;
908 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
909 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
910 XtSetArg(al
[ac
], XmNbottomWidget
,
911 text_input_slot
|| radio_box
|| list
? value
: separator
); ac
++;
912 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
913 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
914 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
915 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
916 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
917 message
= XmCreateLabel (form
, "message", al
, ac
);
920 XtManageChild (value
);
923 children
[i
] = row
; i
++;
924 children
[i
] = separator
; i
++;
925 if (text_input_slot
|| radio_box
)
927 children
[i
] = value
; i
++;
929 children
[i
] = message
; i
++;
930 children
[i
] = icon
; i
++;
931 children
[i
] = icon_separator
; i
++;
932 XtManageChildren (children
, i
);
934 if (text_input_slot
|| list
)
936 XtInstallAccelerators (value
, button
);
937 XtSetKeyboardFocus (result
, value
);
941 XtInstallAccelerators (form
, button
);
942 XtSetKeyboardFocus (result
, button
);
948 static destroyed_instance
*
949 find_matching_instance (widget_instance
* instance
)
951 destroyed_instance
* cur
;
952 destroyed_instance
* prev
;
953 char* type
= instance
->info
->type
;
954 char* name
= instance
->info
->name
;
956 for (prev
= NULL
, cur
= all_destroyed_instances
;
958 prev
= cur
, cur
= cur
->next
)
960 if (!strcmp (cur
->name
, name
)
961 && !strcmp (cur
->type
, type
)
962 && cur
->parent
== instance
->parent
963 && cur
->pop_up_p
== instance
->pop_up_p
)
966 prev
->next
= cur
->next
;
968 all_destroyed_instances
= cur
->next
;
971 /* do some cleanup */
972 else if (!cur
->widget
)
975 prev
->next
= cur
->next
;
977 all_destroyed_instances
= cur
->next
;
978 free_destroyed_instance (cur
);
979 cur
= prev
? prev
: all_destroyed_instances
;
986 mark_dead_instance_destroyed (Widget widget
, XtPointer closure
,
989 destroyed_instance
* instance
= (destroyed_instance
*)closure
;
990 instance
->widget
= NULL
;
994 recenter_widget (Widget widget
)
996 Widget parent
= XtParent (widget
);
997 Screen
* screen
= XtScreen (widget
);
998 Dimension screen_width
= WidthOfScreen (screen
);
999 Dimension screen_height
= HeightOfScreen (screen
);
1000 Dimension parent_width
= 0;
1001 Dimension parent_height
= 0;
1002 Dimension child_width
= 0;
1003 Dimension child_height
= 0;
1007 XtVaGetValues (widget
, XtNwidth
, &child_width
, XtNheight
, &child_height
, 0);
1008 XtVaGetValues (parent
, XtNwidth
, &parent_width
, XtNheight
, &parent_height
,
1011 x
= (((Position
)parent_width
) - ((Position
)child_width
)) / 2;
1012 y
= (((Position
)parent_height
) - ((Position
)child_height
)) / 2;
1014 XtTranslateCoords (parent
, x
, y
, &x
, &y
);
1016 if (x
+ child_width
> screen_width
)
1017 x
= screen_width
- child_width
;
1021 if (y
+ child_height
> screen_height
)
1022 y
= screen_height
- child_height
;
1026 XtVaSetValues (widget
, XtNx
, x
, XtNy
, y
, 0);
1030 recycle_instance (destroyed_instance
* instance
)
1032 Widget widget
= instance
->widget
;
1034 /* widget is NULL if the parent was destroyed. */
1040 /* Remove the destroy callback as the instance is not in the list
1042 XtRemoveCallback (instance
->parent
, XtNdestroyCallback
,
1043 mark_dead_instance_destroyed
,
1044 (XtPointer
)instance
);
1046 /* Give the focus to the initial item */
1047 focus
= XtNameToWidget (widget
, "*value");
1049 focus
= XtNameToWidget (widget
, "*button1");
1051 XtSetKeyboardFocus (widget
, focus
);
1053 /* shrink the separator label back to their original size */
1054 separator
= XtNameToWidget (widget
, "*separator_button");
1056 XtVaSetValues (separator
, XtNwidth
, 5, XtNheight
, 5, 0);
1058 /* Center the dialog in its parent */
1059 recenter_widget (widget
);
1061 free_destroyed_instance (instance
);
1066 xm_create_dialog (widget_instance
* instance
)
1068 char* name
= instance
->info
->type
;
1069 Widget parent
= instance
->parent
;
1071 Boolean pop_up_p
= instance
->pop_up_p
;
1072 char* shell_name
= 0;
1074 Boolean text_input_slot
= False
;
1075 Boolean radio_box
= False
;
1076 Boolean list
= False
;
1078 int left_buttons
= 0;
1079 int right_buttons
= 1;
1080 destroyed_instance
* dead_one
;
1082 /* try to find a widget to recycle */
1083 dead_one
= find_matching_instance (instance
);
1086 Widget recycled_widget
= recycle_instance (dead_one
);
1087 if (recycled_widget
)
1088 return recycled_widget
;
1093 icon_name
= "dbox-error";
1094 shell_name
= "Error";
1098 icon_name
= "dbox-info";
1099 shell_name
= "Information";
1104 icon_name
= "dbox-question";
1105 shell_name
= "Prompt";
1109 text_input_slot
= True
;
1110 icon_name
= "dbox-question";
1111 shell_name
= "Prompt";
1115 icon_name
= "dbox-question";
1116 shell_name
= "Question";
1120 total_buttons
= name
[1] - '0';
1122 if (name
[3] == 'T' || name
[3] == 't')
1124 text_input_slot
= False
;
1128 right_buttons
= name
[4] - '0';
1130 left_buttons
= total_buttons
- right_buttons
;
1132 widget
= make_dialog (name
, parent
, pop_up_p
,
1133 shell_name
, icon_name
, text_input_slot
, radio_box
,
1134 list
, left_buttons
, right_buttons
);
1136 XtAddCallback (widget
, XmNpopdownCallback
, xm_nosel_callback
,
1137 (XtPointer
) instance
);
1142 make_menubar (widget_instance
* instance
)
1144 return XmCreateMenuBar (instance
->parent
, instance
->info
->name
, NULL
, 0);
1148 remove_grabs (Widget shell
, XtPointer closure
, XtPointer call_data
)
1150 XmRowColumnWidget menu
= (XmRowColumnWidget
) closure
;
1151 XmRemoveFromPostFromList (menu
, XtParent (XtParent ((Widget
) menu
)));
1155 make_popup_menu (widget_instance
* instance
)
1157 Widget parent
= instance
->parent
;
1158 Window parent_window
= parent
->core
.window
;
1161 /* sets the parent window to 0 to fool Motif into not generating a grab */
1162 parent
->core
.window
= 0;
1163 result
= XmCreatePopupMenu (parent
, instance
->info
->name
, NULL
, 0);
1164 XtAddCallback (XtParent (result
), XmNpopdownCallback
, remove_grabs
,
1166 parent
->core
.window
= parent_window
;
1170 make_main (widget_instance
* instance
)
1172 Widget parent
= instance
->parent
;
1178 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
1179 XtSetArg (al
[ac
], XmNspacing
, 0); ac
++;
1180 result
= XmCreateMainWindow (parent
, instance
->info
->name
, al
, ac
);
1184 \f/* Table of functions to create widgets */
1188 /* interface with the XDesigner generated functions */
1189 typedef Widget (*widget_maker
) (Widget
);
1190 extern Widget
create_project_p_sheet (Widget parent
);
1191 extern Widget
create_debugger_p_sheet (Widget parent
);
1192 extern Widget
create_breaklist_p_sheet (Widget parent
);
1193 extern Widget
create_le_browser_p_sheet (Widget parent
);
1194 extern Widget
create_class_browser_p_sheet (Widget parent
);
1195 extern Widget
create_call_browser_p_sheet (Widget parent
);
1196 extern Widget
create_build_dialog (Widget parent
);
1197 extern Widget
create_editmode_dialog (Widget parent
);
1198 extern Widget
create_search_dialog (Widget parent
);
1199 extern Widget
create_project_display_dialog (Widget parent
);
1202 make_one (widget_instance
* instance
, widget_maker fn
)
1208 if (instance
->pop_up_p
)
1210 XtSetArg (al
[ac
], XmNallowShellResize
, TRUE
); ac
++;
1211 result
= XmCreateDialogShell (instance
->parent
, "dialog", NULL
, 0);
1212 XtAddCallback (result
, XmNpopdownCallback
, &xm_nosel_callback
,
1213 (XtPointer
) instance
);
1218 result
= (*fn
) (instance
->parent
);
1219 XtRealizeWidget (result
);
1225 make_project_p_sheet (widget_instance
* instance
)
1227 return make_one (instance
, create_project_p_sheet
);
1231 make_debugger_p_sheet (widget_instance
* instance
)
1233 return make_one (instance
, create_debugger_p_sheet
);
1237 make_breaklist_p_sheet (widget_instance
* instance
)
1239 return make_one (instance
, create_breaklist_p_sheet
);
1243 make_le_browser_p_sheet (widget_instance
* instance
)
1245 return make_one (instance
, create_le_browser_p_sheet
);
1249 make_class_browser_p_sheet (widget_instance
* instance
)
1251 return make_one (instance
, create_class_browser_p_sheet
);
1255 make_call_browser_p_sheet (widget_instance
* instance
)
1257 return make_one (instance
, create_call_browser_p_sheet
);
1261 make_build_dialog (widget_instance
* instance
)
1263 return make_one (instance
, create_build_dialog
);
1267 make_editmode_dialog (widget_instance
* instance
)
1269 return make_one (instance
, create_editmode_dialog
);
1273 make_search_dialog (widget_instance
* instance
)
1275 return make_one (instance
, create_search_dialog
);
1279 make_project_display_dialog (widget_instance
* instance
)
1281 return make_one (instance
, create_project_display_dialog
);
1284 #endif /* ENERGIZE */
1286 widget_creation_entry
1287 xm_creation_table
[] =
1289 {"menubar", make_menubar
},
1290 {"popup", make_popup_menu
},
1291 {"main", make_main
},
1293 {"project_p_sheet", make_project_p_sheet
},
1294 {"debugger_p_sheet", make_debugger_p_sheet
},
1295 {"breaklist_psheet", make_breaklist_p_sheet
},
1296 {"leb_psheet", make_le_browser_p_sheet
},
1297 {"class_browser_psheet", make_class_browser_p_sheet
},
1298 {"ctree_browser_psheet", make_call_browser_p_sheet
},
1299 {"build", make_build_dialog
},
1300 {"editmode", make_editmode_dialog
},
1301 {"search", make_search_dialog
},
1302 {"project_display", make_project_display_dialog
},
1303 #endif /* ENERGIZE */
1307 \f/* Destruction of instances */
1309 xm_destroy_instance (widget_instance
* instance
)
1311 Widget widget
= instance
->widget
;
1312 /* recycle the dialog boxes */
1313 /* Disable the recycling until we can find a way to have the dialog box
1314 get reasonable layout after we modify its contents. */
1316 && XtClass (widget
) == xmDialogShellWidgetClass
)
1318 destroyed_instance
* dead_instance
=
1319 make_destroyed_instance (instance
->info
->name
,
1320 instance
->info
->type
,
1323 instance
->pop_up_p
);
1324 dead_instance
->next
= all_destroyed_instances
;
1325 all_destroyed_instances
= dead_instance
;
1326 XtUnmanageChild (first_child (instance
->widget
));
1327 XFlush (XtDisplay (instance
->widget
));
1328 XtAddCallback (instance
->parent
, XtNdestroyCallback
,
1329 mark_dead_instance_destroyed
, (XtPointer
)dead_instance
);
1333 /* This might not be necessary now that the nosel is attached to
1334 popdown instead of destroy, but it can't hurt. */
1335 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
1336 xm_nosel_callback
, (XtPointer
)instance
);
1337 XtDestroyWidget (instance
->widget
);
1341 \f/* popup utility */
1343 xm_popup_menu (Widget widget
)
1345 XButtonPressedEvent dummy
;
1348 dummy
.type
= ButtonPress
;
1350 dummy
.send_event
= 0;
1351 dummy
.display
= XtDisplay (widget
);
1352 dummy
.window
= XtWindow (XtParent (widget
));
1355 XQueryPointer (dummy
.display
, dummy
.window
, &dummy
.root
,
1356 &dummy
.subwindow
, &dummy
.x_root
, &dummy
.y_root
,
1357 &dummy
.x
, &dummy
.y
, &dummy
.state
);
1358 event
= (XEvent
*) &dummy
;
1360 if (event
->type
== ButtonPress
|| event
->type
== ButtonRelease
)
1362 /* This is so totally ridiculous: there's NO WAY to tell Motif
1363 that *any* button can select a menu item. Only one button
1364 can have that honor.
1367 if (event
->xbutton
.state
& Button5Mask
) trans
= "<Btn5Down>";
1368 else if (event
->xbutton
.state
& Button4Mask
) trans
= "<Btn4Down>";
1369 else if (event
->xbutton
.state
& Button3Mask
) trans
= "<Btn3Down>";
1370 else if (event
->xbutton
.state
& Button2Mask
) trans
= "<Btn2Down>";
1371 else if (event
->xbutton
.state
& Button1Mask
) trans
= "<Btn1Down>";
1372 if (trans
) XtVaSetValues (widget
, XmNmenuPost
, trans
, 0);
1373 XmMenuPosition (widget
, (XButtonPressedEvent
*) event
);
1375 XtManageChild (widget
);
1379 set_min_dialog_size (Widget w
)
1383 XtVaGetValues (w
, XmNwidth
, &width
, XmNheight
, &height
, 0);
1384 XtVaSetValues (w
, XmNminWidth
, width
, XmNminHeight
, height
, 0);
1388 xm_pop_instance (widget_instance
* instance
, Boolean up
)
1390 Widget widget
= instance
->widget
;
1392 if (XtClass (widget
) == xmDialogShellWidgetClass
)
1394 Widget widget_to_manage
= first_child (widget
);
1397 XtManageChild (widget_to_manage
);
1398 set_min_dialog_size (widget
);
1399 XtSetKeyboardFocus (instance
->parent
, widget
);
1402 XtUnmanageChild (widget_to_manage
);
1407 XtManageChild (widget
);
1409 XtUnmanageChild (widget
);
1414 /* motif callback */
1416 enum do_call_type
{ pre_activate
, selection
, no_selection
, post_activate
};
1419 do_call (Widget widget
, XtPointer closure
, enum do_call_type type
)
1423 XtPointer user_data
;
1424 widget_instance
* instance
= (widget_instance
*)closure
;
1425 Widget instance_widget
;
1430 if (widget
->core
.being_destroyed
)
1433 instance_widget
= instance
->widget
;
1434 if (!instance_widget
)
1437 id
= instance
->info
->id
;
1440 XtSetArg (al
[ac
], XmNuserData
, &user_data
); ac
++;
1441 XtGetValues (widget
, al
, ac
);
1445 if (instance
->info
->pre_activate_cb
)
1446 instance
->info
->pre_activate_cb (widget
, id
, user_data
);
1449 if (instance
->info
->selection_cb
)
1450 instance
->info
->selection_cb (widget
, id
, user_data
);
1453 if (instance
->info
->selection_cb
)
1454 instance
->info
->selection_cb (widget
, id
, (XtPointer
) -1);
1457 if (instance
->info
->post_activate_cb
)
1458 instance
->info
->post_activate_cb (widget
, id
, user_data
);
1465 /* Like lw_internal_update_other_instances except that it does not do
1466 anything if its shell parent is not managed. This is to protect
1467 lw_internal_update_other_instances to dereference freed memory
1468 if the widget was ``destroyed'' by caching it in the all_destroyed_instances
1471 xm_internal_update_other_instances (Widget widget
, XtPointer closure
,
1472 XtPointer call_data
)
1475 for (parent
= widget
; parent
; parent
= XtParent (parent
))
1476 if (XtIsShell (parent
))
1478 else if (!XtIsManaged (parent
))
1480 lw_internal_update_other_instances (widget
, closure
, call_data
);
1484 xm_generic_callback (Widget widget
, XtPointer closure
, XtPointer call_data
)
1486 lw_internal_update_other_instances (widget
, closure
, call_data
);
1487 do_call (widget
, closure
, selection
);
1491 xm_nosel_callback (Widget widget
, XtPointer closure
, XtPointer call_data
)
1493 /* This callback is only called when a dialog box is dismissed with the wm's
1494 destroy button (WM_DELETE_WINDOW.) We want the dialog box to be destroyed
1495 in that case, not just unmapped, so that it releases its keyboard grabs.
1496 But there are problems with running our callbacks while the widget is in
1497 the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
1498 instead of XmDESTROY and then destroy it ourself after having run the
1501 do_call (widget
, closure
, no_selection
);
1502 XtDestroyWidget (widget
);
1506 xm_pull_down_callback (Widget widget
, XtPointer closure
, XtPointer call_data
)
1508 do_call (widget
, closure
, pre_activate
);
1512 xm_pop_down_callback (Widget widget
, XtPointer closure
, XtPointer call_data
)
1514 widget_instance
*instance
= (widget_instance
*) closure
;
1516 if (!instance
->pop_up_p
|| (XtParent (widget
) == instance
->parent
))
1517 do_call (widget
, closure
, post_activate
);
1521 /* set the keyboard focus */
1523 xm_set_keyboard_focus (Widget parent
, Widget w
)
1525 XmProcessTraversal (w
, 0);
1526 XtSetKeyboardFocus (parent
, w
);
1529 /* Motif hack to set the main window areas. */
1531 xm_set_main_areas (parent
, menubar
, work_area
)
1536 XmMainWindowSetAreas (parent
,
1537 menubar
, /* menubar (maybe 0) */
1538 0, /* command area (psheets) */
1539 0, /* horizontal scroll */
1540 0, /* vertical scroll */
1541 work_area
); /* work area */
1544 /* Motif hack to control resizing on the menubar. */
1546 xm_manage_resizing (w
, flag
)
1552 /* Enable the edit widget for resizing. */
1555 XtSetArg (al
[0], XtNallowShellResize
, 0);
1556 XtSetValues (w
, al
, 1);
1560 /* Disable the edit widget from resizing. */
1563 XtSetArg (al
[0], XtNallowShellResize
, 0);
1564 XtSetValues (w
, al
, 1);