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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
26 #include <X11/StringDefs.h>
27 #include <X11/IntrinsicP.h>
28 #include <X11/ObjectP.h>
29 #include <X11/CoreP.h>
30 #include <X11/CompositeP.h>
33 #include "lwlib-utils.h"
35 #include <Xm/BulletinB.h>
36 #include <Xm/CascadeB.h>
37 #include <Xm/DrawingA.h>
38 #include <Xm/FileSB.h>
42 #include <Xm/MenuShell.h>
43 #include <Xm/MessageB.h>
44 #include <Xm/PanedW.h>
46 #include <Xm/PushBG.h>
47 #include <Xm/ArrowB.h>
48 #include <Xm/SelectioB.h>
51 #include <Xm/ToggleB.h>
52 #include <Xm/ToggleBG.h>
53 #include <Xm/RowColumn.h>
54 #include <Xm/ScrolledW.h>
55 #include <Xm/Separator.h>
56 #include <Xm/DialogS.h>
59 static void xm_pull_down_callback (/* Widget, XtPointer, XtPointer */);
60 static void xm_internal_update_other_instances (/* Widget, XtPointer,
62 static void xm_generic_callback (/* Widget, XtPointer, XtPointer */);
63 static void xm_nosel_callback (/* Widget, XtPointer, XtPointer */);
64 static void xm_pop_down_callback (/* Widget, XtPointer, XtPointer */);
66 static void xm_update_menu (/* widget_instance*, Widget, widget_value*,
70 \f/* Structures to keep destroyed instances */
71 typedef struct _destroyed_instance
78 struct _destroyed_instance
* next
;
81 static destroyed_instance
*
82 all_destroyed_instances
= NULL
;
84 static destroyed_instance
*
85 make_destroyed_instance (name
, type
, widget
, parent
, pop_up_p
)
92 destroyed_instance
* instance
=
93 (destroyed_instance
*)malloc (sizeof (destroyed_instance
));
94 instance
->name
= safe_strdup (name
);
95 instance
->type
= safe_strdup (type
);
96 instance
->widget
= widget
;
97 instance
->parent
= parent
;
98 instance
->pop_up_p
= pop_up_p
;
99 instance
->next
= NULL
;
104 free_destroyed_instance (instance
)
105 destroyed_instance
* instance
;
107 free (instance
->name
);
108 free (instance
->type
);
112 \f/* motif utility functions */
117 return ((CompositeWidget
)widget
)->composite
.children
[0];
121 lw_motif_widget_p (widget
)
125 XtClass (widget
) == xmDialogShellWidgetClass
126 || XmIsPrimitive (widget
) || XmIsManager (widget
) || XmIsGadget (widget
);
130 resource_motif_string (widget
, name
)
137 resource
.resource_name
= name
;
138 resource
.resource_class
= XmCXmString
;
139 resource
.resource_type
= XmRXmString
;
140 resource
.resource_size
= sizeof (XmString
);
141 resource
.resource_offset
= 0;
142 resource
.default_type
= XtRImmediate
;
143 resource
.default_addr
= 0;
145 XtGetSubresources (widget
, (XtPointer
)&result
, "dialogString",
146 "DialogString", &resource
, 1, NULL
, 0);
151 destroy_all_children (widget
)
158 children
= XtCompositeChildren (widget
, &number
);
161 /* Unmanage all children and destroy them. They will only be
162 * really destroyed when we get out of DispatchEvent. */
163 for (i
= 0; i
< number
; i
++)
165 Widget child
= children
[i
];
166 if (!child
->core
.being_destroyed
)
168 XtUnmanageChild (child
);
169 XtDestroyWidget (child
);
172 XtFree ((char *) children
);
176 \f/* update the label of anything subclass of a label */
178 xm_update_label (instance
, widget
, val
)
179 widget_instance
* instance
;
183 XmString res_string
= 0;
184 XmString built_string
= 0;
185 XmString key_string
= 0;
193 res_string
= resource_motif_string (widget
, val
->value
);
197 XtSetArg (al
[ac
], XmNlabelString
, res_string
); ac
++;
202 XmStringCreateLtoR (val
->value
, XmSTRING_DEFAULT_CHARSET
);
203 XtSetArg (al
[ac
], XmNlabelString
, built_string
); ac
++;
205 XtSetArg (al
[ac
], XmNlabelType
, XmSTRING
); ac
++;
210 key_string
= XmStringCreateLtoR (val
->key
, XmSTRING_DEFAULT_CHARSET
);
211 XtSetArg (al
[ac
], XmNacceleratorText
, key_string
); ac
++;
215 XtSetValues (widget
, al
, ac
);
218 XmStringFree (built_string
);
221 XmStringFree (key_string
);
224 \f/* update of list */
226 xm_update_list (instance
, widget
, val
)
227 widget_instance
* instance
;
233 XtRemoveAllCallbacks (widget
, XmNsingleSelectionCallback
);
234 XtAddCallback (widget
, XmNsingleSelectionCallback
, xm_generic_callback
,
236 for (cur
= val
->contents
, i
= 0; cur
; cur
= cur
->next
)
239 XmString xmstr
= XmStringCreate (cur
->value
, XmSTRING_DEFAULT_CHARSET
);
241 XmListAddItem (widget
, xmstr
, 0);
243 XmListSelectPos (widget
, i
, False
);
244 XmStringFree (xmstr
);
248 \f/* update of buttons */
250 xm_update_pushbutton (instance
, widget
, val
)
251 widget_instance
* instance
;
255 XtVaSetValues (widget
, XmNalignment
, XmALIGNMENT_CENTER
, 0);
256 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
257 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
261 xm_update_cascadebutton (instance
, widget
, val
)
262 widget_instance
* instance
;
266 /* Should also rebuild the menu by calling ...update_menu... */
267 XtRemoveAllCallbacks (widget
, XmNcascadingCallback
);
268 XtAddCallback (widget
, XmNcascadingCallback
, xm_pull_down_callback
,
272 \f/* update toggle and radiobox */
274 xm_update_toggle (instance
, widget
, val
)
275 widget_instance
* instance
;
279 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
280 XtAddCallback (widget
, XmNvalueChangedCallback
,
281 xm_internal_update_other_instances
, instance
);
282 XtVaSetValues (widget
, XmNset
, val
->selected
,
283 XmNalignment
, XmALIGNMENT_BEGINNING
, 0);
287 xm_update_radiobox (instance
, widget
, val
)
288 widget_instance
* instance
;
296 /* update the callback */
297 XtRemoveAllCallbacks (widget
, XmNentryCallback
);
298 XtAddCallback (widget
, XmNentryCallback
, xm_generic_callback
, instance
);
300 /* first update all the toggles */
301 /* Energize kernel interface is currently bad. It sets the selected widget
302 with the selected flag but returns it by its name. So we currently
303 have to support both setting the selection with the selected slot
304 of val contents and setting it with the "value" slot of val. The latter
305 has a higher priority. This to be removed when the kernel is fixed. */
306 for (cur
= val
->contents
; cur
; cur
= cur
->next
)
308 toggle
= XtNameToWidget (widget
, cur
->value
);
311 XtVaSetValues (toggle
, XmNsensitive
, cur
->enabled
, 0);
312 if (!val
->value
&& cur
->selected
)
313 XtVaSetValues (toggle
, XmNset
, cur
->selected
, 0);
314 if (val
->value
&& strcmp (val
->value
, cur
->value
))
315 XtVaSetValues (toggle
, XmNset
, False
, 0);
319 /* The selected was specified by the value slot */
322 toggle
= XtNameToWidget (widget
, val
->value
);
324 XtVaSetValues (toggle
, XmNset
, True
, 0);
328 \f/* update a popup menu, pulldown menu or a menubar */
341 make_menu_in_widget (instance
, widget
, val
)
342 widget_instance
* instance
;
346 Widget
* children
= 0;
356 /* Allocate the children array */
357 for (num_children
= 0, cur
= val
; cur
; num_children
++, cur
= cur
->next
);
358 children
= (Widget
*)XtMalloc (num_children
* sizeof (Widget
));
360 /* tricky way to know if this RowColumn is a menubar or a pulldown... */
362 XtSetArg (al
[0], XmNisHomogeneous
, &menubar_p
);
363 XtGetValues (widget
, al
, 1);
365 /* add the unmap callback for popups and pulldowns */
366 /*** this sounds bogus ***/
368 XtAddCallback (XtParent (widget
), XmNpopdownCallback
,
369 xm_pop_down_callback
, (XtPointer
)instance
);
371 for (child_index
= 0, cur
= val
; cur
; child_index
++, cur
= cur
->next
)
374 XtSetArg (al
[ac
], XmNsensitive
, cur
->enabled
); ac
++;
375 XtSetArg (al
[ac
], XmNalignment
, XmALIGNMENT_BEGINNING
); ac
++;
376 XtSetArg (al
[ac
], XmNuserData
, cur
->call_data
); ac
++;
378 if (instance
->pop_up_p
&& !cur
->contents
&& !cur
->call_data
379 && !all_dashes_p (cur
->name
))
382 XtSetArg (al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
383 button
= XmCreateLabel (widget
, cur
->name
, al
, ac
);
385 else if (all_dashes_p (cur
->name
))
387 button
= XmCreateSeparator (widget
, cur
->name
, NULL
, 0);
389 else if (!cur
->contents
)
392 button
= XmCreateCascadeButton (widget
, cur
->name
, al
, ac
);
393 else if (!cur
->call_data
)
394 button
= XmCreateLabel (widget
, cur
->name
, al
, ac
);
396 button
= XmCreatePushButtonGadget (widget
, cur
->name
, al
, ac
);
398 xm_update_label (instance
, button
, cur
);
400 /* don't add a callback to a simple label */
402 XtAddCallback (button
, XmNactivateCallback
, xm_generic_callback
,
403 (XtPointer
)instance
);
407 menu
= XmCreatePulldownMenu (widget
, cur
->name
, NULL
, 0);
408 make_menu_in_widget (instance
, menu
, cur
->contents
);
409 XtSetArg (al
[ac
], XmNsubMenuId
, menu
); ac
++;
410 button
= XmCreateCascadeButton (widget
, cur
->name
, al
, ac
);
412 xm_update_label (instance
, button
, cur
);
414 XtAddCallback (button
, XmNcascadingCallback
, xm_pull_down_callback
,
415 (XtPointer
)instance
);
418 children
[child_index
] = button
;
421 XtManageChildren (children
, num_children
);
423 /* Last entry is the help button. Has to be done after managing
424 * the buttons otherwise the menubar is only 4 pixels high... */
428 XtSetArg (al
[ac
], XmNmenuHelpWidget
, button
); ac
++;
429 XtSetValues (widget
, al
, ac
);
432 XtFree ((char *) children
);
436 update_one_menu_entry (instance
, widget
, val
, deep_p
)
437 widget_instance
* instance
;
445 widget_value
* contents
;
447 if (val
->change
== NO_CHANGE
)
450 /* update the sensitivity and userdata */
451 /* Common to all widget types */
452 XtVaSetValues (widget
,
453 XmNsensitive
, val
->enabled
,
454 XmNuserData
, val
->call_data
,
457 /* update the menu button as a label. */
458 if (val
->change
>= VISIBLE_CHANGE
)
459 xm_update_label (instance
, widget
, val
);
461 /* update the pulldown/pullaside as needed */
464 XtSetArg (al
[ac
], XmNsubMenuId
, &menu
); ac
++;
465 XtGetValues (widget
, al
, ac
);
467 contents
= val
->contents
;
473 menu
= XmCreatePulldownMenu (XtParent (widget
), XtName (widget
), NULL
, 0);
474 make_menu_in_widget (instance
, menu
, contents
);
476 XtSetArg (al
[ac
], XmNsubMenuId
, menu
); ac
++;
477 XtSetValues (widget
, al
, ac
);
483 XtSetArg (al
[ac
], XmNsubMenuId
, NULL
); ac
++;
484 XtSetValues (widget
, al
, ac
);
485 XtDestroyWidget (menu
);
487 else if (deep_p
&& contents
->change
!= NO_CHANGE
)
488 xm_update_menu (instance
, menu
, val
, 1);
492 xm_update_menu (instance
, widget
, val
, deep_p
)
493 widget_instance
* instance
;
498 /* Widget is a RowColumn widget whose contents have to be updated
499 * to reflect the list of items in val->contents */
500 if (val
->contents
->change
== STRUCTURAL_CHANGE
)
502 destroy_all_children (widget
);
503 make_menu_in_widget (instance
, widget
, val
->contents
);
507 /* Update all the buttons of the RowColumn in order. */
509 unsigned int num_children
;
513 children
= XtCompositeChildren (widget
, &num_children
);
516 for (i
= 0, cur
= val
->contents
; i
< num_children
; i
++)
520 if (children
[i
]->core
.being_destroyed
521 || strcmp (XtName (children
[i
]), cur
->name
))
523 update_one_menu_entry (instance
, children
[i
], cur
, deep_p
);
526 XtFree ((char *) children
);
534 /* update text widgets */
537 xm_update_text (instance
, widget
, val
)
538 widget_instance
* instance
;
542 XmTextSetString (widget
, val
->value
? val
->value
: "");
543 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
544 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
545 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
546 XtAddCallback (widget
, XmNvalueChangedCallback
,
547 xm_internal_update_other_instances
, instance
);
551 xm_update_text_field (instance
, widget
, val
)
552 widget_instance
* instance
;
556 XmTextFieldSetString (widget
, val
->value
? val
->value
: "");
557 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
558 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
559 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
560 XtAddCallback (widget
, XmNvalueChangedCallback
,
561 xm_internal_update_other_instances
, instance
);
565 /* update a motif widget */
568 xm_update_one_widget (instance
, widget
, val
, deep_p
)
569 widget_instance
* instance
;
576 /* Mark as not edited */
579 /* Common to all widget types */
580 XtVaSetValues (widget
,
581 XmNsensitive
, val
->enabled
,
582 XmNuserData
, val
->call_data
,
585 /* Common to all label like widgets */
586 if (XtIsSubclass (widget
, xmLabelWidgetClass
))
587 xm_update_label (instance
, widget
, val
);
589 class = XtClass (widget
);
590 /* Class specific things */
591 if (class == xmPushButtonWidgetClass
||
592 class == xmArrowButtonWidgetClass
)
594 xm_update_pushbutton (instance
, widget
, val
);
596 else if (class == xmCascadeButtonWidgetClass
)
598 xm_update_cascadebutton (instance
, widget
, val
);
600 else if (class == xmToggleButtonWidgetClass
601 || class == xmToggleButtonGadgetClass
)
603 xm_update_toggle (instance
, widget
, val
);
605 else if (class == xmRowColumnWidgetClass
)
607 Boolean radiobox
= 0;
611 XtSetArg (al
[ac
], XmNradioBehavior
, &radiobox
); ac
++;
612 XtGetValues (widget
, al
, ac
);
615 xm_update_radiobox (instance
, widget
, val
);
617 xm_update_menu (instance
, widget
, val
, deep_p
);
619 else if (class == xmTextWidgetClass
)
621 xm_update_text (instance
, widget
, val
);
623 else if (class == xmTextFieldWidgetClass
)
625 xm_update_text_field (instance
, widget
, val
);
627 else if (class == xmListWidgetClass
)
629 xm_update_list (instance
, widget
, val
);
633 \f/* getting the value back */
635 xm_update_one_value (instance
, widget
, val
)
636 widget_instance
* instance
;
640 WidgetClass
class = XtClass (widget
);
641 widget_value
*old_wv
;
643 /* copy the call_data slot into the "return" widget_value */
644 for (old_wv
= instance
->info
->val
->contents
; old_wv
; old_wv
= old_wv
->next
)
645 if (!strcmp (val
->name
, old_wv
->name
))
647 val
->call_data
= old_wv
->call_data
;
651 if (class == xmToggleButtonWidgetClass
|| class == xmToggleButtonGadgetClass
)
653 XtVaGetValues (widget
, XmNset
, &val
->selected
, 0);
656 else if (class == xmTextWidgetClass
)
660 val
->value
= XmTextGetString (widget
);
663 else if (class == xmTextFieldWidgetClass
)
667 val
->value
= XmTextFieldGetString (widget
);
670 else if (class == xmRowColumnWidgetClass
)
672 Boolean radiobox
= 0;
676 XtSetArg (al
[ac
], XmNradioBehavior
, &radiobox
); ac
++;
677 XtGetValues (widget
, al
, ac
);
681 CompositeWidget radio
= (CompositeWidget
)widget
;
683 for (i
= 0; i
< radio
->composite
.num_children
; i
++)
686 Widget toggle
= radio
->composite
.children
[i
];
688 XtVaGetValues (toggle
, XmNset
, &set
, 0);
693 val
->value
= safe_strdup (XtName (toggle
));
699 else if (class == xmListWidgetClass
)
703 if (XmListGetSelectedPos (widget
, &pos_list
, &pos_cnt
))
707 for (cur
= val
->contents
, i
= 0; cur
; cur
= cur
->next
)
711 cur
->selected
= False
;
713 for (j
= 0; j
< pos_cnt
; j
++)
714 if (pos_list
[j
] == i
)
716 cur
->selected
= True
;
717 val
->value
= safe_strdup (cur
->name
);
721 XtFree ((char *) pos_list
);
727 /* This function is for activating a button from a program. It's wrong because
728 we pass a NULL argument in the call_data which is not Motif compatible.
729 This is used from the XmNdefaultAction callback of the List widgets to
730 have a double-click put down a dialog box like the button would do.
731 I could not find a way to do that with accelerators.
734 activate_button (widget
, closure
, call_data
)
739 Widget button
= (Widget
)closure
;
740 XtCallCallbacks (button
, XmNactivateCallback
, NULL
);
743 /* creation functions */
747 make_dialog (name
, parent
, pop_up_p
, shell_title
, icon_name
, text_input_slot
,
748 radio_box
, list
, left_buttons
, right_buttons
)
754 Boolean text_input_slot
;
764 Widget icon_separator
;
769 Widget children
[16]; /* for the final XtManageChildren */
771 Arg al
[64]; /* Arg List */
772 int ac
; /* Arg Count */
778 XtSetArg(al
[ac
], XmNtitle
, shell_title
); ac
++;
779 XtSetArg(al
[ac
], XtNallowShellResize
, True
); ac
++;
780 XtSetArg(al
[ac
], XmNdeleteResponse
, XmUNMAP
); ac
++;
781 result
= XmCreateDialogShell (parent
, "dialog", al
, ac
);
783 XtSetArg(al
[ac
], XmNautoUnmanage
, FALSE
); ac
++;
784 /* XtSetArg(al[ac], XmNautoUnmanage, TRUE); ac++; */ /* ####is this ok? */
785 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
786 form
= XmCreateForm (result
, shell_title
, al
, ac
);
791 XtSetArg(al
[ac
], XmNautoUnmanage
, FALSE
); ac
++;
792 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
793 form
= XmCreateForm (parent
, shell_title
, al
, ac
);
797 n_children
= left_buttons
+ right_buttons
+ 1;
799 XtSetArg(al
[ac
], XmNpacking
, n_children
== 3?
800 XmPACK_COLUMN
: XmPACK_TIGHT
); ac
++;
801 XtSetArg(al
[ac
], XmNorientation
, n_children
== 3?
802 XmVERTICAL
: XmHORIZONTAL
); ac
++;
803 XtSetArg(al
[ac
], XmNnumColumns
, left_buttons
+ right_buttons
+ 1); ac
++;
804 XtSetArg(al
[ac
], XmNmarginWidth
, 0); ac
++;
805 XtSetArg(al
[ac
], XmNmarginHeight
, 0); ac
++;
806 XtSetArg(al
[ac
], XmNspacing
, 13); ac
++;
807 XtSetArg(al
[ac
], XmNadjustLast
, False
); ac
++;
808 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
809 XtSetArg(al
[ac
], XmNisAligned
, True
); ac
++;
810 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
811 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_FORM
); ac
++;
812 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
813 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
814 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
815 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
816 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
817 row
= XmCreateRowColumn (form
, "row", al
, ac
);
820 for (i
= 0; i
< left_buttons
; i
++)
822 char button_name
[16];
823 sprintf (button_name
, "button%d", i
+ 1);
827 XtSetArg(al
[ac
], XmNhighlightThickness
, 1); ac
++;
828 XtSetArg(al
[ac
], XmNshowAsDefault
, TRUE
); ac
++;
830 XtSetArg(al
[ac
], XmNmarginWidth
, 10); ac
++;
831 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
832 children
[n_children
] = XmCreatePushButton (row
, button_name
, al
, ac
);
836 button
= children
[n_children
];
838 XtSetArg(al
[ac
], XmNdefaultButton
, button
); ac
++;
839 XtSetValues (row
, al
, ac
);
845 /* invisible separator button */
847 XtSetArg (al
[ac
], XmNmappedWhenManaged
, FALSE
); ac
++;
848 children
[n_children
] = XmCreateLabel (row
, "separator_button", al
, ac
);
851 for (i
= 0; i
< right_buttons
; i
++)
853 char button_name
[16];
854 sprintf (button_name
, "button%d", left_buttons
+ i
+ 1);
856 XtSetArg(al
[ac
], XmNmarginWidth
, 10); ac
++;
857 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
858 children
[n_children
] = XmCreatePushButton (row
, button_name
, al
, ac
);
859 if (! button
) button
= children
[n_children
];
863 XtManageChildren (children
, n_children
);
866 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
867 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
868 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
869 XtSetArg(al
[ac
], XmNbottomWidget
, row
); ac
++;
870 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
871 XtSetArg(al
[ac
], XmNleftOffset
, 0); ac
++;
872 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
873 XtSetArg(al
[ac
], XmNrightOffset
, 0); ac
++;
874 separator
= XmCreateSeparator (form
, "", al
, ac
);
877 XtSetArg(al
[ac
], XmNlabelType
, XmPIXMAP
); ac
++;
878 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_FORM
); ac
++;
879 XtSetArg(al
[ac
], XmNtopOffset
, 13); ac
++;
880 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_NONE
); ac
++;
881 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
882 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
883 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_NONE
); ac
++;
884 icon
= XmCreateLabel (form
, icon_name
, al
, ac
);
887 XtSetArg(al
[ac
], XmNmappedWhenManaged
, FALSE
); ac
++;
888 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_WIDGET
); ac
++;
889 XtSetArg(al
[ac
], XmNtopOffset
, 6); ac
++;
890 XtSetArg(al
[ac
], XmNtopWidget
, icon
); ac
++;
891 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
892 XtSetArg(al
[ac
], XmNbottomOffset
, 6); ac
++;
893 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
894 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_NONE
); ac
++;
895 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_NONE
); ac
++;
896 icon_separator
= XmCreateLabel (form
, "", al
, ac
);
901 XtSetArg(al
[ac
], XmNcolumns
, 50); ac
++;
902 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
903 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
904 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
905 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
906 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
907 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
908 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
909 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
910 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
911 value
= XmCreateTextField (form
, "value", al
, ac
);
917 XtSetArg(al
[ac
], XmNmarginWidth
, 0); ac
++;
918 XtSetArg(al
[ac
], XmNmarginHeight
, 0); ac
++;
919 XtSetArg(al
[ac
], XmNspacing
, 13); ac
++;
920 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
921 XtSetArg(al
[ac
], XmNorientation
, XmHORIZONTAL
); ac
++;
922 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
923 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
924 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
925 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
926 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
927 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
928 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
929 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
930 value
= XmCreateRadioBox (form
, "radiobutton1", al
, ac
);
933 radio_butt
= XmCreateToggleButtonGadget (value
, "radio1", al
, ac
);
934 children
[i
++] = radio_butt
;
935 radio_butt
= XmCreateToggleButtonGadget (value
, "radio2", al
, ac
);
936 children
[i
++] = radio_butt
;
937 radio_butt
= XmCreateToggleButtonGadget (value
, "radio3", al
, ac
);
938 children
[i
++] = radio_butt
;
939 XtManageChildren (children
, i
);
944 XtSetArg(al
[ac
], XmNvisibleItemCount
, 5); ac
++;
945 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
946 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
947 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
948 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
949 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
950 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
951 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
952 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
953 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
954 value
= XmCreateScrolledList (form
, "list", al
, ac
);
956 /* this is the easiest way I found to have the dble click in the
957 list activate the default button */
958 XtAddCallback (value
, XmNdefaultActionCallback
, activate_button
, button
);
962 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_BEGINNING
); ac
++;
963 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_FORM
); ac
++;
964 XtSetArg(al
[ac
], XmNtopOffset
, 13); ac
++;
965 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
966 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
967 XtSetArg(al
[ac
], XmNbottomWidget
,
968 text_input_slot
|| radio_box
|| list
? value
: separator
); ac
++;
969 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
970 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
971 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
972 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
973 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
974 message
= XmCreateLabel (form
, "message", al
, ac
);
977 XtManageChild (value
);
980 children
[i
] = row
; i
++;
981 children
[i
] = separator
; i
++;
982 if (text_input_slot
|| radio_box
)
984 children
[i
] = value
; i
++;
986 children
[i
] = message
; i
++;
987 children
[i
] = icon
; i
++;
988 children
[i
] = icon_separator
; i
++;
989 XtManageChildren (children
, i
);
991 if (text_input_slot
|| list
)
993 XtInstallAccelerators (value
, button
);
994 XtSetKeyboardFocus (result
, value
);
998 XtInstallAccelerators (form
, button
);
999 XtSetKeyboardFocus (result
, button
);
1005 static destroyed_instance
*
1006 find_matching_instance (instance
)
1007 widget_instance
* instance
;
1009 destroyed_instance
* cur
;
1010 destroyed_instance
* prev
;
1011 char* type
= instance
->info
->type
;
1012 char* name
= instance
->info
->name
;
1014 for (prev
= NULL
, cur
= all_destroyed_instances
;
1016 prev
= cur
, cur
= cur
->next
)
1018 if (!strcmp (cur
->name
, name
)
1019 && !strcmp (cur
->type
, type
)
1020 && cur
->parent
== instance
->parent
1021 && cur
->pop_up_p
== instance
->pop_up_p
)
1024 prev
->next
= cur
->next
;
1026 all_destroyed_instances
= cur
->next
;
1029 /* do some cleanup */
1030 else if (!cur
->widget
)
1033 prev
->next
= cur
->next
;
1035 all_destroyed_instances
= cur
->next
;
1036 free_destroyed_instance (cur
);
1037 cur
= prev
? prev
: all_destroyed_instances
;
1044 mark_dead_instance_destroyed (widget
, closure
, call_data
)
1047 XtPointer call_data
;
1049 destroyed_instance
* instance
= (destroyed_instance
*)closure
;
1050 instance
->widget
= NULL
;
1054 recenter_widget (widget
)
1057 Widget parent
= XtParent (widget
);
1058 Screen
* screen
= XtScreen (widget
);
1059 Dimension screen_width
= WidthOfScreen (screen
);
1060 Dimension screen_height
= HeightOfScreen (screen
);
1061 Dimension parent_width
= 0;
1062 Dimension parent_height
= 0;
1063 Dimension child_width
= 0;
1064 Dimension child_height
= 0;
1068 XtVaGetValues (widget
, XtNwidth
, &child_width
, XtNheight
, &child_height
, 0);
1069 XtVaGetValues (parent
, XtNwidth
, &parent_width
, XtNheight
, &parent_height
,
1072 x
= (((Position
)parent_width
) - ((Position
)child_width
)) / 2;
1073 y
= (((Position
)parent_height
) - ((Position
)child_height
)) / 2;
1075 XtTranslateCoords (parent
, x
, y
, &x
, &y
);
1077 if (x
+ child_width
> screen_width
)
1078 x
= screen_width
- child_width
;
1082 if (y
+ child_height
> screen_height
)
1083 y
= screen_height
- child_height
;
1087 XtVaSetValues (widget
, XtNx
, x
, XtNy
, y
, 0);
1091 recycle_instance (instance
)
1092 destroyed_instance
* instance
;
1094 Widget widget
= instance
->widget
;
1096 /* widget is NULL if the parent was destroyed. */
1102 /* Remove the destroy callback as the instance is not in the list
1104 XtRemoveCallback (instance
->parent
, XtNdestroyCallback
,
1105 mark_dead_instance_destroyed
,
1106 (XtPointer
)instance
);
1108 /* Give the focus to the initial item */
1109 focus
= XtNameToWidget (widget
, "*value");
1111 focus
= XtNameToWidget (widget
, "*button1");
1113 XtSetKeyboardFocus (widget
, focus
);
1115 /* shrink the separator label back to their original size */
1116 separator
= XtNameToWidget (widget
, "*separator_button");
1118 XtVaSetValues (separator
, XtNwidth
, 5, XtNheight
, 5, 0);
1120 /* Center the dialog in its parent */
1121 recenter_widget (widget
);
1123 free_destroyed_instance (instance
);
1128 xm_create_dialog (instance
)
1129 widget_instance
* instance
;
1131 char* name
= instance
->info
->type
;
1132 Widget parent
= instance
->parent
;
1134 Boolean pop_up_p
= instance
->pop_up_p
;
1135 char* shell_name
= 0;
1137 Boolean text_input_slot
= False
;
1138 Boolean radio_box
= False
;
1139 Boolean list
= False
;
1141 int left_buttons
= 0;
1142 int right_buttons
= 1;
1143 destroyed_instance
* dead_one
;
1145 /* try to find a widget to recycle */
1146 dead_one
= find_matching_instance (instance
);
1149 Widget recycled_widget
= recycle_instance (dead_one
);
1150 if (recycled_widget
)
1151 return recycled_widget
;
1156 icon_name
= "dbox-error";
1157 shell_name
= "Error";
1161 icon_name
= "dbox-info";
1162 shell_name
= "Information";
1167 icon_name
= "dbox-question";
1168 shell_name
= "Prompt";
1172 text_input_slot
= True
;
1173 icon_name
= "dbox-question";
1174 shell_name
= "Prompt";
1178 icon_name
= "dbox-question";
1179 shell_name
= "Question";
1183 total_buttons
= name
[1] - '0';
1185 if (name
[3] == 'T' || name
[3] == 't')
1187 text_input_slot
= False
;
1191 right_buttons
= name
[4] - '0';
1193 left_buttons
= total_buttons
- right_buttons
;
1195 widget
= make_dialog (name
, parent
, pop_up_p
,
1196 shell_name
, icon_name
, text_input_slot
, radio_box
,
1197 list
, left_buttons
, right_buttons
);
1199 XtAddCallback (widget
, XmNpopdownCallback
, xm_nosel_callback
,
1200 (XtPointer
) instance
);
1205 make_menubar (instance
)
1206 widget_instance
* instance
;
1208 return XmCreateMenuBar (instance
->parent
, instance
->info
->name
, NULL
, 0);
1212 remove_grabs (shell
, closure
, call_data
)
1215 XtPointer call_data
;
1217 Widget menu
= (Widget
) closure
;
1218 XmRemoveFromPostFromList (menu
, XtParent (XtParent (menu
)));
1222 make_popup_menu (instance
)
1223 widget_instance
* instance
;
1225 Widget parent
= instance
->parent
;
1226 Window parent_window
= parent
->core
.window
;
1229 /* sets the parent window to 0 to fool Motif into not generating a grab */
1230 parent
->core
.window
= 0;
1231 result
= XmCreatePopupMenu (parent
, instance
->info
->name
, NULL
, 0);
1232 XtAddCallback (XtParent (result
), XmNpopdownCallback
, remove_grabs
,
1234 parent
->core
.window
= parent_window
;
1238 make_main (instance
)
1239 widget_instance
* instance
;
1241 Widget parent
= instance
->parent
;
1247 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
1248 XtSetArg (al
[ac
], XmNspacing
, 0); ac
++;
1249 result
= XmCreateMainWindow (parent
, instance
->info
->name
, al
, ac
);
1253 \f/* Table of functions to create widgets */
1257 /* interface with the XDesigner generated functions */
1258 typedef Widget (*widget_maker
) (Widget
);
1259 extern Widget
create_project_p_sheet (Widget parent
);
1260 extern Widget
create_debugger_p_sheet (Widget parent
);
1261 extern Widget
create_breaklist_p_sheet (Widget parent
);
1262 extern Widget
create_le_browser_p_sheet (Widget parent
);
1263 extern Widget
create_class_browser_p_sheet (Widget parent
);
1264 extern Widget
create_call_browser_p_sheet (Widget parent
);
1265 extern Widget
create_build_dialog (Widget parent
);
1266 extern Widget
create_editmode_dialog (Widget parent
);
1267 extern Widget
create_search_dialog (Widget parent
);
1268 extern Widget
create_project_display_dialog (Widget parent
);
1271 make_one (widget_instance
* instance
, widget_maker fn
)
1277 if (instance
->pop_up_p
)
1279 XtSetArg (al
[ac
], XmNallowShellResize
, TRUE
); ac
++;
1280 result
= XmCreateDialogShell (instance
->parent
, "dialog", NULL
, 0);
1281 XtAddCallback (result
, XmNpopdownCallback
, &xm_nosel_callback
,
1282 (XtPointer
) instance
);
1287 result
= (*fn
) (instance
->parent
);
1288 XtRealizeWidget (result
);
1294 make_project_p_sheet (widget_instance
* instance
)
1296 return make_one (instance
, create_project_p_sheet
);
1300 make_debugger_p_sheet (widget_instance
* instance
)
1302 return make_one (instance
, create_debugger_p_sheet
);
1306 make_breaklist_p_sheet (widget_instance
* instance
)
1308 return make_one (instance
, create_breaklist_p_sheet
);
1312 make_le_browser_p_sheet (widget_instance
* instance
)
1314 return make_one (instance
, create_le_browser_p_sheet
);
1318 make_class_browser_p_sheet (widget_instance
* instance
)
1320 return make_one (instance
, create_class_browser_p_sheet
);
1324 make_call_browser_p_sheet (widget_instance
* instance
)
1326 return make_one (instance
, create_call_browser_p_sheet
);
1330 make_build_dialog (widget_instance
* instance
)
1332 return make_one (instance
, create_build_dialog
);
1336 make_editmode_dialog (widget_instance
* instance
)
1338 return make_one (instance
, create_editmode_dialog
);
1342 make_search_dialog (widget_instance
* instance
)
1344 return make_one (instance
, create_search_dialog
);
1348 make_project_display_dialog (widget_instance
* instance
)
1350 return make_one (instance
, create_project_display_dialog
);
1353 #endif /* ENERGIZE */
1355 widget_creation_entry
1356 xm_creation_table
[] =
1358 {"menubar", make_menubar
},
1359 {"popup", make_popup_menu
},
1360 {"main", make_main
},
1362 {"project_p_sheet", make_project_p_sheet
},
1363 {"debugger_p_sheet", make_debugger_p_sheet
},
1364 {"breaklist_psheet", make_breaklist_p_sheet
},
1365 {"leb_psheet", make_le_browser_p_sheet
},
1366 {"class_browser_psheet", make_class_browser_p_sheet
},
1367 {"ctree_browser_psheet", make_call_browser_p_sheet
},
1368 {"build", make_build_dialog
},
1369 {"editmode", make_editmode_dialog
},
1370 {"search", make_search_dialog
},
1371 {"project_display", make_project_display_dialog
},
1372 #endif /* ENERGIZE */
1376 \f/* Destruction of instances */
1378 xm_destroy_instance (instance
)
1379 widget_instance
* instance
;
1381 Widget widget
= instance
->widget
;
1382 /* recycle the dialog boxes */
1383 /* Disable the recycling until we can find a way to have the dialog box
1384 get reasonable layout after we modify its contents. */
1386 && XtClass (widget
) == xmDialogShellWidgetClass
)
1388 destroyed_instance
* dead_instance
=
1389 make_destroyed_instance (instance
->info
->name
,
1390 instance
->info
->type
,
1393 instance
->pop_up_p
);
1394 dead_instance
->next
= all_destroyed_instances
;
1395 all_destroyed_instances
= dead_instance
;
1396 XtUnmanageChild (first_child (instance
->widget
));
1397 XFlush (XtDisplay (instance
->widget
));
1398 XtAddCallback (instance
->parent
, XtNdestroyCallback
,
1399 mark_dead_instance_destroyed
, (XtPointer
)dead_instance
);
1403 /* This might not be necessary now that the nosel is attached to
1404 popdown instead of destroy, but it can't hurt. */
1405 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
1406 xm_nosel_callback
, (XtPointer
)instance
);
1407 XtDestroyWidget (instance
->widget
);
1411 \f/* popup utility */
1413 xm_popup_menu (widget
, event
)
1417 XButtonPressedEvent dummy
;
1421 dummy
.type
= ButtonPress
;
1423 dummy
.send_event
= 0;
1424 dummy
.display
= XtDisplay (widget
);
1425 dummy
.window
= XtWindow (XtParent (widget
));
1428 XQueryPointer (dummy
.display
, dummy
.window
, &dummy
.root
,
1429 &dummy
.subwindow
, &dummy
.x_root
, &dummy
.y_root
,
1430 &dummy
.x
, &dummy
.y
, &dummy
.state
);
1431 event
= (XEvent
*) &dummy
;
1434 if (event
->type
== ButtonPress
|| event
->type
== ButtonRelease
)
1436 /* This is so totally ridiculous: there's NO WAY to tell Motif
1437 that *any* button can select a menu item. Only one button
1438 can have that honor.
1441 if (event
->xbutton
.state
& Button5Mask
) trans
= "<Btn5Down>";
1442 else if (event
->xbutton
.state
& Button4Mask
) trans
= "<Btn4Down>";
1443 else if (event
->xbutton
.state
& Button3Mask
) trans
= "<Btn3Down>";
1444 else if (event
->xbutton
.state
& Button2Mask
) trans
= "<Btn2Down>";
1445 else if (event
->xbutton
.state
& Button1Mask
) trans
= "<Btn1Down>";
1446 if (trans
) XtVaSetValues (widget
, XmNmenuPost
, trans
, 0);
1447 XmMenuPosition (widget
, (XButtonPressedEvent
*) event
);
1449 XtManageChild (widget
);
1453 set_min_dialog_size (w
)
1458 XtVaGetValues (w
, XmNwidth
, &width
, XmNheight
, &height
, 0);
1459 XtVaSetValues (w
, XmNminWidth
, width
, XmNminHeight
, height
, 0);
1463 xm_pop_instance (instance
, up
)
1464 widget_instance
* instance
;
1467 Widget widget
= instance
->widget
;
1469 if (XtClass (widget
) == xmDialogShellWidgetClass
)
1471 Widget widget_to_manage
= first_child (widget
);
1474 XtManageChild (widget_to_manage
);
1475 set_min_dialog_size (widget
);
1476 XtSetKeyboardFocus (instance
->parent
, widget
);
1479 XtUnmanageChild (widget_to_manage
);
1484 XtManageChild (widget
);
1486 XtUnmanageChild (widget
);
1491 /* motif callback */
1493 enum do_call_type
{ pre_activate
, selection
, no_selection
, post_activate
};
1496 do_call (widget
, closure
, type
)
1499 enum do_call_type type
;
1503 XtPointer user_data
;
1504 widget_instance
* instance
= (widget_instance
*)closure
;
1505 Widget instance_widget
;
1510 if (widget
->core
.being_destroyed
)
1513 instance_widget
= instance
->widget
;
1514 if (!instance_widget
)
1517 id
= instance
->info
->id
;
1520 XtSetArg (al
[ac
], XmNuserData
, &user_data
); ac
++;
1521 XtGetValues (widget
, al
, ac
);
1525 if (instance
->info
->pre_activate_cb
)
1526 instance
->info
->pre_activate_cb (widget
, id
, user_data
);
1529 if (instance
->info
->selection_cb
)
1530 instance
->info
->selection_cb (widget
, id
, user_data
);
1533 if (instance
->info
->selection_cb
)
1534 instance
->info
->selection_cb (widget
, id
, (XtPointer
) -1);
1537 if (instance
->info
->post_activate_cb
)
1538 instance
->info
->post_activate_cb (widget
, id
, user_data
);
1545 /* Like lw_internal_update_other_instances except that it does not do
1546 anything if its shell parent is not managed. This is to protect
1547 lw_internal_update_other_instances to dereference freed memory
1548 if the widget was ``destroyed'' by caching it in the all_destroyed_instances
1551 xm_internal_update_other_instances (widget
, closure
, call_data
)
1554 XtPointer call_data
;
1557 for (parent
= widget
; parent
; parent
= XtParent (parent
))
1558 if (XtIsShell (parent
))
1560 else if (!XtIsManaged (parent
))
1562 lw_internal_update_other_instances (widget
, closure
, call_data
);
1566 xm_generic_callback (widget
, closure
, call_data
)
1569 XtPointer call_data
;
1571 lw_internal_update_other_instances (widget
, closure
, call_data
);
1572 do_call (widget
, closure
, selection
);
1576 xm_nosel_callback (widget
, closure
, call_data
)
1579 XtPointer call_data
;
1581 /* This callback is only called when a dialog box is dismissed with the wm's
1582 destroy button (WM_DELETE_WINDOW.) We want the dialog box to be destroyed
1583 in that case, not just unmapped, so that it releases its keyboard grabs.
1584 But there are problems with running our callbacks while the widget is in
1585 the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
1586 instead of XmDESTROY and then destroy it ourself after having run the
1589 do_call (widget
, closure
, no_selection
);
1590 XtDestroyWidget (widget
);
1594 xm_pull_down_callback (widget
, closure
, call_data
)
1597 XtPointer call_data
;
1599 do_call (widget
, closure
, pre_activate
);
1603 xm_pop_down_callback (widget
, closure
, call_data
)
1606 XtPointer call_data
;
1608 widget_instance
*instance
= (widget_instance
*) closure
;
1610 if ((!instance
->pop_up_p
&& (XtParent (widget
) == instance
->widget
))
1611 || (XtParent (widget
) == instance
->parent
))
1612 do_call (widget
, closure
, post_activate
);
1616 /* set the keyboard focus */
1618 xm_set_keyboard_focus (parent
, w
)
1622 XmProcessTraversal (w
, 0);
1623 XtSetKeyboardFocus (parent
, w
);
1626 /* Motif hack to set the main window areas. */
1628 xm_set_main_areas (parent
, menubar
, work_area
)
1633 XmMainWindowSetAreas (parent
,
1634 menubar
, /* menubar (maybe 0) */
1635 0, /* command area (psheets) */
1636 0, /* horizontal scroll */
1637 0, /* vertical scroll */
1638 work_area
); /* work area */
1641 /* Motif hack to control resizing on the menubar. */
1643 xm_manage_resizing (w
, flag
)
1649 /* Enable the edit widget for resizing. */
1652 XtSetArg (al
[0], XtNallowShellResize
, 0);
1653 XtSetValues (w
, al
, 1);
1657 /* Disable the edit widget from resizing. */
1660 XtSetArg (al
[0], XtNallowShellResize
, 0);
1661 XtSetValues (w
, al
, 1);