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/CascadeBG.h>
38 #include <Xm/DrawingA.h>
39 #include <Xm/FileSB.h>
43 #include <Xm/MenuShell.h>
44 #include <Xm/MessageB.h>
45 #include <Xm/PanedW.h>
47 #include <Xm/PushBG.h>
48 #include <Xm/ArrowB.h>
49 #include <Xm/SelectioB.h>
52 #include <Xm/ToggleB.h>
53 #include <Xm/ToggleBG.h>
54 #include <Xm/RowColumn.h>
55 #include <Xm/ScrolledW.h>
56 #include <Xm/Separator.h>
57 #include <Xm/DialogS.h>
60 static void xm_pull_down_callback (/* Widget, XtPointer, XtPointer */);
61 static void xm_internal_update_other_instances (/* Widget, XtPointer,
63 static void xm_generic_callback (/* Widget, XtPointer, XtPointer */);
64 static void xm_nosel_callback (/* Widget, XtPointer, XtPointer */);
65 static void xm_pop_down_callback (/* Widget, XtPointer, XtPointer */);
67 static void xm_update_menu (/* widget_instance*, Widget, widget_value*,
71 \f/* Structures to keep destroyed instances */
72 typedef struct _destroyed_instance
79 struct _destroyed_instance
* next
;
82 static destroyed_instance
*
83 all_destroyed_instances
= NULL
;
85 static destroyed_instance
*
86 make_destroyed_instance (name
, type
, widget
, parent
, pop_up_p
)
93 destroyed_instance
* instance
=
94 (destroyed_instance
*)malloc (sizeof (destroyed_instance
));
95 instance
->name
= safe_strdup (name
);
96 instance
->type
= safe_strdup (type
);
97 instance
->widget
= widget
;
98 instance
->parent
= parent
;
99 instance
->pop_up_p
= pop_up_p
;
100 instance
->next
= NULL
;
105 free_destroyed_instance (instance
)
106 destroyed_instance
* instance
;
108 free (instance
->name
);
109 free (instance
->type
);
113 \f/* motif utility functions */
118 return ((CompositeWidget
)widget
)->composite
.children
[0];
122 lw_motif_widget_p (widget
)
126 XtClass (widget
) == xmDialogShellWidgetClass
127 || XmIsPrimitive (widget
) || XmIsManager (widget
) || XmIsGadget (widget
);
131 resource_motif_string (widget
, name
)
138 resource
.resource_name
= name
;
139 resource
.resource_class
= XmCXmString
;
140 resource
.resource_type
= XmRXmString
;
141 resource
.resource_size
= sizeof (XmString
);
142 resource
.resource_offset
= 0;
143 resource
.default_type
= XtRImmediate
;
144 resource
.default_addr
= 0;
146 XtGetSubresources (widget
, (XtPointer
)&result
, "dialogString",
147 "DialogString", &resource
, 1, NULL
, 0);
151 /* Destroy all of the children of WIDGET
152 starting with number FIRST_CHILD_TO_DESTROY. */
155 destroy_all_children (widget
, first_child_to_destroy
)
157 int first_child_to_destroy
;
163 children
= XtCompositeChildren (widget
, &number
);
166 XtUnmanageChildren (children
+ first_child_to_destroy
,
167 number
- first_child_to_destroy
);
169 /* Unmanage all children and destroy them. They will only be
170 really destroyed when we get out of DispatchEvent. */
171 for (i
= first_child_to_destroy
; i
< number
; i
++)
175 /* Cascade buttons have submenus,and these submenus
176 need to be freed. But they are not included in
177 XtCompositeChildren. So get it out of the cascade button
178 and free it. If this child is not a cascade button,
179 then submenu should remain unchanged. */
180 XtSetArg (al
[0], XmNsubMenuId
, &submenu
);
181 XtGetValues (children
[i
], al
, 1);
183 XtDestroyWidget (submenu
);
184 XtDestroyWidget (children
[i
]);
187 XtFree ((char *) children
);
191 \f/* update the label of anything subclass of a label */
193 xm_update_label (instance
, widget
, val
)
194 widget_instance
* instance
;
198 XmString res_string
= 0;
199 XmString built_string
= 0;
200 XmString key_string
= 0;
208 res_string
= resource_motif_string (widget
, val
->value
);
212 XtSetArg (al
[ac
], XmNlabelString
, res_string
); ac
++;
217 XmStringCreateLtoR (val
->value
, XmSTRING_DEFAULT_CHARSET
);
218 XtSetArg (al
[ac
], XmNlabelString
, built_string
); ac
++;
220 XtSetArg (al
[ac
], XmNlabelType
, XmSTRING
); ac
++;
225 key_string
= XmStringCreateLtoR (val
->key
, XmSTRING_DEFAULT_CHARSET
);
226 XtSetArg (al
[ac
], XmNacceleratorText
, key_string
); ac
++;
230 XtSetValues (widget
, al
, ac
);
233 XmStringFree (built_string
);
236 XmStringFree (key_string
);
239 \f/* update of list */
241 xm_update_list (instance
, widget
, val
)
242 widget_instance
* instance
;
248 XtRemoveAllCallbacks (widget
, XmNsingleSelectionCallback
);
249 XtAddCallback (widget
, XmNsingleSelectionCallback
, xm_generic_callback
,
251 for (cur
= val
->contents
, i
= 0; cur
; cur
= cur
->next
)
254 XmString xmstr
= XmStringCreate (cur
->value
, XmSTRING_DEFAULT_CHARSET
);
256 XmListAddItem (widget
, xmstr
, 0);
258 XmListSelectPos (widget
, i
, False
);
259 XmStringFree (xmstr
);
263 \f/* update of buttons */
265 xm_update_pushbutton (instance
, widget
, val
)
266 widget_instance
* instance
;
270 XtVaSetValues (widget
, XmNalignment
, XmALIGNMENT_CENTER
, 0);
271 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
272 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
276 xm_update_cascadebutton (instance
, widget
, val
)
277 widget_instance
* instance
;
281 /* Should also rebuild the menu by calling ...update_menu... */
282 XtRemoveAllCallbacks (widget
, XmNcascadingCallback
);
283 XtAddCallback (widget
, XmNcascadingCallback
, xm_pull_down_callback
,
287 \f/* update toggle and radiobox */
289 xm_update_toggle (instance
, widget
, val
)
290 widget_instance
* instance
;
294 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
295 XtAddCallback (widget
, XmNvalueChangedCallback
,
296 xm_internal_update_other_instances
, instance
);
297 XtVaSetValues (widget
, XmNset
, val
->selected
,
298 XmNalignment
, XmALIGNMENT_BEGINNING
, 0);
302 xm_update_radiobox (instance
, widget
, val
)
303 widget_instance
* instance
;
311 /* update the callback */
312 XtRemoveAllCallbacks (widget
, XmNentryCallback
);
313 XtAddCallback (widget
, XmNentryCallback
, xm_generic_callback
, instance
);
315 /* first update all the toggles */
316 /* Energize kernel interface is currently bad. It sets the selected widget
317 with the selected flag but returns it by its name. So we currently
318 have to support both setting the selection with the selected slot
319 of val contents and setting it with the "value" slot of val. The latter
320 has a higher priority. This to be removed when the kernel is fixed. */
321 for (cur
= val
->contents
; cur
; cur
= cur
->next
)
323 toggle
= XtNameToWidget (widget
, cur
->value
);
326 XtVaSetValues (toggle
, XmNsensitive
, cur
->enabled
, 0);
327 if (!val
->value
&& cur
->selected
)
328 XtVaSetValues (toggle
, XmNset
, cur
->selected
, 0);
329 if (val
->value
&& strcmp (val
->value
, cur
->value
))
330 XtVaSetValues (toggle
, XmNset
, False
, 0);
334 /* The selected was specified by the value slot */
337 toggle
= XtNameToWidget (widget
, val
->value
);
339 XtVaSetValues (toggle
, XmNset
, True
, 0);
343 \f/* update a popup menu, pulldown menu or a menubar */
355 /* KEEP_FIRST_CHILDREN gives the number of initial children to keep. */
358 make_menu_in_widget (instance
, widget
, val
, keep_first_children
)
359 widget_instance
* instance
;
362 int keep_first_children
;
364 Widget
* children
= 0;
374 Widget
* old_children
;
375 unsigned int old_num_children
;
377 old_children
= XtCompositeChildren (widget
, &old_num_children
);
379 /* Allocate the children array */
380 for (num_children
= 0, cur
= val
; cur
; num_children
++, cur
= cur
->next
);
381 children
= (Widget
*)XtMalloc (num_children
* sizeof (Widget
));
383 /* tricky way to know if this RowColumn is a menubar or a pulldown... */
385 XtSetArg (al
[0], XmNisHomogeneous
, &menubar_p
);
386 XtGetValues (widget
, al
, 1);
388 /* add the unmap callback for popups and pulldowns */
389 /*** this sounds bogus ***/
391 XtAddCallback (XtParent (widget
), XmNpopdownCallback
,
392 xm_pop_down_callback
, (XtPointer
)instance
);
394 /* Preserve the first KEEP_FIRST_CHILDREN old children. */
395 for (child_index
= 0, cur
= val
; child_index
< keep_first_children
;
396 child_index
++, cur
= cur
->next
)
397 children
[child_index
] = old_children
[child_index
];
399 /* Check that those are all we have
400 (the caller should have deleted the rest). */
401 if (old_num_children
!= keep_first_children
)
404 /* Create the rest. */
405 for (child_index
= keep_first_children
; cur
; child_index
++, cur
= cur
->next
)
408 XtSetArg (al
[ac
], XmNsensitive
, cur
->enabled
); ac
++;
409 XtSetArg (al
[ac
], XmNalignment
, XmALIGNMENT_BEGINNING
); ac
++;
410 XtSetArg (al
[ac
], XmNuserData
, cur
->call_data
); ac
++;
412 if (instance
->pop_up_p
&& !cur
->contents
&& !cur
->call_data
413 && !all_dashes_p (cur
->name
))
416 XtSetArg (al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
417 button
= XmCreateLabel (widget
, cur
->name
, al
, ac
);
419 else if (all_dashes_p (cur
->name
))
421 button
= XmCreateSeparator (widget
, cur
->name
, NULL
, 0);
423 else if (!cur
->contents
)
426 button
= XmCreateCascadeButton (widget
, cur
->name
, al
, ac
);
427 else if (!cur
->call_data
)
428 button
= XmCreateLabel (widget
, cur
->name
, al
, ac
);
430 button
= XmCreatePushButtonGadget (widget
, cur
->name
, al
, ac
);
432 xm_update_label (instance
, button
, cur
);
434 /* don't add a callback to a simple label */
436 XtAddCallback (button
, XmNactivateCallback
, xm_generic_callback
,
437 (XtPointer
)instance
);
441 menu
= XmCreatePulldownMenu (widget
, cur
->name
, NULL
, 0);
442 make_menu_in_widget (instance
, menu
, cur
->contents
, 0);
443 XtSetArg (al
[ac
], XmNsubMenuId
, menu
); ac
++;
444 button
= XmCreateCascadeButtonGadget (widget
, cur
->name
, al
, ac
);
446 xm_update_label (instance
, button
, cur
);
448 XtAddCallback (button
, XmNcascadingCallback
, xm_pull_down_callback
,
449 (XtPointer
)instance
);
452 children
[child_index
] = button
;
455 XtManageChildren (children
, num_children
);
457 /* Last entry is the help button. Has to be done after managing
458 * the buttons otherwise the menubar is only 4 pixels high... */
462 XtSetArg (al
[ac
], XmNmenuHelpWidget
, button
); ac
++;
463 XtSetValues (widget
, al
, ac
);
466 XtFree ((char *) children
);
468 XtFree ((char *) old_children
);
472 update_one_menu_entry (instance
, widget
, val
, deep_p
)
473 widget_instance
* instance
;
481 widget_value
* contents
;
483 if (val
->this_one_change
== NO_CHANGE
)
486 /* update the sensitivity and userdata */
487 /* Common to all widget types */
488 XtVaSetValues (widget
,
489 XmNsensitive
, val
->enabled
,
490 XmNuserData
, val
->call_data
,
493 /* update the menu button as a label. */
494 if (val
->this_one_change
>= VISIBLE_CHANGE
)
495 xm_update_label (instance
, widget
, val
);
497 /* update the pulldown/pullaside as needed */
500 XtSetArg (al
[ac
], XmNsubMenuId
, &menu
); ac
++;
501 XtGetValues (widget
, al
, ac
);
503 contents
= val
->contents
;
509 menu
= XmCreatePulldownMenu (XtParent (widget
), XtName (widget
), NULL
, 0);
510 make_menu_in_widget (instance
, menu
, contents
, 0);
512 XtSetArg (al
[ac
], XmNsubMenuId
, menu
); ac
++;
513 XtSetValues (widget
, al
, ac
);
519 XtSetArg (al
[ac
], XmNsubMenuId
, NULL
); ac
++;
520 XtSetValues (widget
, al
, ac
);
521 XtDestroyWidget (menu
);
523 else if (deep_p
&& contents
->change
!= NO_CHANGE
)
524 xm_update_menu (instance
, menu
, val
, 1);
528 xm_update_menu (instance
, widget
, val
, deep_p
)
529 widget_instance
* instance
;
535 unsigned int num_children
;
536 int num_children_to_keep
= 0;
540 children
= XtCompositeChildren (widget
, &num_children
);
542 /* Widget is a RowColumn widget whose contents have to be updated
543 * to reflect the list of items in val->contents */
545 /* See how many buttons we can keep, and how many we
546 must completely replace. */
547 if (val
->contents
== 0)
548 num_children_to_keep
= 0;
549 else if (val
->contents
->change
== STRUCTURAL_CHANGE
)
553 for (i
= 0, cur
= val
->contents
; i
< num_children
;
554 i
++, cur
= cur
->next
)
556 if (cur
->this_one_change
== STRUCTURAL_CHANGE
)
560 num_children_to_keep
= i
;
564 num_children_to_keep
= num_children
;
566 /* Update all the buttons of the RowColumn, in order,
567 except for those we are going to replace entirely. */
570 for (i
= 0, cur
= val
->contents
; i
< num_children_to_keep
; i
++)
574 if (children
[i
]->core
.being_destroyed
575 || strcmp (XtName (children
[i
]), cur
->name
))
577 update_one_menu_entry (instance
, children
[i
], cur
, deep_p
);
582 /* Now replace from scratch all the buttons after the last
583 place that the top-level structure changed. */
584 if (val
->contents
->change
== STRUCTURAL_CHANGE
)
586 destroy_all_children (widget
, num_children_to_keep
);
587 make_menu_in_widget (instance
, widget
, val
->contents
,
588 num_children_to_keep
);
591 XtFree ((char *) children
);
595 /* update text widgets */
598 xm_update_text (instance
, widget
, val
)
599 widget_instance
* instance
;
603 XmTextSetString (widget
, val
->value
? val
->value
: "");
604 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
605 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
606 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
607 XtAddCallback (widget
, XmNvalueChangedCallback
,
608 xm_internal_update_other_instances
, instance
);
612 xm_update_text_field (instance
, widget
, val
)
613 widget_instance
* instance
;
617 XmTextFieldSetString (widget
, val
->value
? val
->value
: "");
618 XtRemoveAllCallbacks (widget
, XmNactivateCallback
);
619 XtAddCallback (widget
, XmNactivateCallback
, xm_generic_callback
, instance
);
620 XtRemoveAllCallbacks (widget
, XmNvalueChangedCallback
);
621 XtAddCallback (widget
, XmNvalueChangedCallback
,
622 xm_internal_update_other_instances
, instance
);
626 /* update a motif widget */
629 xm_update_one_widget (instance
, widget
, val
, deep_p
)
630 widget_instance
* instance
;
637 /* Mark as not edited */
640 /* Common to all widget types */
641 XtVaSetValues (widget
,
642 XmNsensitive
, val
->enabled
,
643 XmNuserData
, val
->call_data
,
646 /* Common to all label like widgets */
647 if (XtIsSubclass (widget
, xmLabelWidgetClass
))
648 xm_update_label (instance
, widget
, val
);
650 class = XtClass (widget
);
651 /* Class specific things */
652 if (class == xmPushButtonWidgetClass
||
653 class == xmArrowButtonWidgetClass
)
655 xm_update_pushbutton (instance
, widget
, val
);
657 else if (class == xmCascadeButtonWidgetClass
)
659 xm_update_cascadebutton (instance
, widget
, val
);
661 else if (class == xmToggleButtonWidgetClass
662 || class == xmToggleButtonGadgetClass
)
664 xm_update_toggle (instance
, widget
, val
);
666 else if (class == xmRowColumnWidgetClass
)
668 Boolean radiobox
= 0;
672 XtSetArg (al
[ac
], XmNradioBehavior
, &radiobox
); ac
++;
673 XtGetValues (widget
, al
, ac
);
676 xm_update_radiobox (instance
, widget
, val
);
678 xm_update_menu (instance
, widget
, val
, deep_p
);
680 else if (class == xmTextWidgetClass
)
682 xm_update_text (instance
, widget
, val
);
684 else if (class == xmTextFieldWidgetClass
)
686 xm_update_text_field (instance
, widget
, val
);
688 else if (class == xmListWidgetClass
)
690 xm_update_list (instance
, widget
, val
);
694 \f/* getting the value back */
696 xm_update_one_value (instance
, widget
, val
)
697 widget_instance
* instance
;
701 WidgetClass
class = XtClass (widget
);
702 widget_value
*old_wv
;
704 /* copy the call_data slot into the "return" widget_value */
705 for (old_wv
= instance
->info
->val
->contents
; old_wv
; old_wv
= old_wv
->next
)
706 if (!strcmp (val
->name
, old_wv
->name
))
708 val
->call_data
= old_wv
->call_data
;
712 if (class == xmToggleButtonWidgetClass
|| class == xmToggleButtonGadgetClass
)
714 XtVaGetValues (widget
, XmNset
, &val
->selected
, 0);
717 else if (class == xmTextWidgetClass
)
721 val
->value
= XmTextGetString (widget
);
724 else if (class == xmTextFieldWidgetClass
)
728 val
->value
= XmTextFieldGetString (widget
);
731 else if (class == xmRowColumnWidgetClass
)
733 Boolean radiobox
= 0;
737 XtSetArg (al
[ac
], XmNradioBehavior
, &radiobox
); ac
++;
738 XtGetValues (widget
, al
, ac
);
742 CompositeWidget radio
= (CompositeWidget
)widget
;
744 for (i
= 0; i
< radio
->composite
.num_children
; i
++)
747 Widget toggle
= radio
->composite
.children
[i
];
749 XtVaGetValues (toggle
, XmNset
, &set
, 0);
754 val
->value
= safe_strdup (XtName (toggle
));
760 else if (class == xmListWidgetClass
)
764 if (XmListGetSelectedPos (widget
, &pos_list
, &pos_cnt
))
768 for (cur
= val
->contents
, i
= 0; cur
; cur
= cur
->next
)
772 cur
->selected
= False
;
774 for (j
= 0; j
< pos_cnt
; j
++)
775 if (pos_list
[j
] == i
)
777 cur
->selected
= True
;
778 val
->value
= safe_strdup (cur
->name
);
782 XtFree ((char *) pos_list
);
788 /* This function is for activating a button from a program. It's wrong because
789 we pass a NULL argument in the call_data which is not Motif compatible.
790 This is used from the XmNdefaultAction callback of the List widgets to
791 have a double-click put down a dialog box like the button would do.
792 I could not find a way to do that with accelerators.
795 activate_button (widget
, closure
, call_data
)
800 Widget button
= (Widget
)closure
;
801 XtCallCallbacks (button
, XmNactivateCallback
, NULL
);
804 /* creation functions */
808 make_dialog (name
, parent
, pop_up_p
, shell_title
, icon_name
, text_input_slot
,
809 radio_box
, list
, left_buttons
, right_buttons
)
815 Boolean text_input_slot
;
825 Widget icon_separator
;
830 Widget children
[16]; /* for the final XtManageChildren */
832 Arg al
[64]; /* Arg List */
833 int ac
; /* Arg Count */
839 XtSetArg(al
[ac
], XmNtitle
, shell_title
); ac
++;
840 XtSetArg(al
[ac
], XtNallowShellResize
, True
); ac
++;
841 XtSetArg(al
[ac
], XmNdeleteResponse
, XmUNMAP
); ac
++;
842 result
= XmCreateDialogShell (parent
, "dialog", al
, ac
);
844 XtSetArg(al
[ac
], XmNautoUnmanage
, FALSE
); ac
++;
845 /* XtSetArg(al[ac], XmNautoUnmanage, TRUE); ac++; */ /* ####is this ok? */
846 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
847 form
= XmCreateForm (result
, shell_title
, al
, ac
);
852 XtSetArg(al
[ac
], XmNautoUnmanage
, FALSE
); ac
++;
853 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
854 form
= XmCreateForm (parent
, shell_title
, al
, ac
);
858 n_children
= left_buttons
+ right_buttons
+ 1;
860 XtSetArg(al
[ac
], XmNpacking
, n_children
== 3?
861 XmPACK_COLUMN
: XmPACK_TIGHT
); ac
++;
862 XtSetArg(al
[ac
], XmNorientation
, n_children
== 3?
863 XmVERTICAL
: XmHORIZONTAL
); ac
++;
864 XtSetArg(al
[ac
], XmNnumColumns
, left_buttons
+ right_buttons
+ 1); ac
++;
865 XtSetArg(al
[ac
], XmNmarginWidth
, 0); ac
++;
866 XtSetArg(al
[ac
], XmNmarginHeight
, 0); ac
++;
867 XtSetArg(al
[ac
], XmNspacing
, 13); ac
++;
868 XtSetArg(al
[ac
], XmNadjustLast
, False
); ac
++;
869 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
870 XtSetArg(al
[ac
], XmNisAligned
, True
); ac
++;
871 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
872 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_FORM
); ac
++;
873 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
874 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
875 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
876 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
877 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
878 row
= XmCreateRowColumn (form
, "row", al
, ac
);
881 for (i
= 0; i
< left_buttons
; i
++)
883 char button_name
[16];
884 sprintf (button_name
, "button%d", i
+ 1);
888 XtSetArg(al
[ac
], XmNhighlightThickness
, 1); ac
++;
889 XtSetArg(al
[ac
], XmNshowAsDefault
, TRUE
); ac
++;
891 XtSetArg(al
[ac
], XmNmarginWidth
, 10); ac
++;
892 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
893 children
[n_children
] = XmCreatePushButton (row
, button_name
, al
, ac
);
897 button
= children
[n_children
];
899 XtSetArg(al
[ac
], XmNdefaultButton
, button
); ac
++;
900 XtSetValues (row
, al
, ac
);
906 /* invisible separator button */
908 XtSetArg (al
[ac
], XmNmappedWhenManaged
, FALSE
); ac
++;
909 children
[n_children
] = XmCreateLabel (row
, "separator_button", al
, ac
);
912 for (i
= 0; i
< right_buttons
; i
++)
914 char button_name
[16];
915 sprintf (button_name
, "button%d", left_buttons
+ i
+ 1);
917 XtSetArg(al
[ac
], XmNmarginWidth
, 10); ac
++;
918 XtSetArg(al
[ac
], XmNnavigationType
, XmTAB_GROUP
); ac
++;
919 children
[n_children
] = XmCreatePushButton (row
, button_name
, al
, ac
);
920 if (! button
) button
= children
[n_children
];
924 XtManageChildren (children
, n_children
);
927 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
928 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
929 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
930 XtSetArg(al
[ac
], XmNbottomWidget
, row
); ac
++;
931 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
932 XtSetArg(al
[ac
], XmNleftOffset
, 0); ac
++;
933 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
934 XtSetArg(al
[ac
], XmNrightOffset
, 0); ac
++;
935 separator
= XmCreateSeparator (form
, "", al
, ac
);
938 XtSetArg(al
[ac
], XmNlabelType
, XmPIXMAP
); ac
++;
939 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_FORM
); ac
++;
940 XtSetArg(al
[ac
], XmNtopOffset
, 13); ac
++;
941 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_NONE
); ac
++;
942 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_FORM
); ac
++;
943 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
944 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_NONE
); ac
++;
945 icon
= XmCreateLabel (form
, icon_name
, al
, ac
);
948 XtSetArg(al
[ac
], XmNmappedWhenManaged
, FALSE
); ac
++;
949 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_WIDGET
); ac
++;
950 XtSetArg(al
[ac
], XmNtopOffset
, 6); ac
++;
951 XtSetArg(al
[ac
], XmNtopWidget
, icon
); ac
++;
952 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
953 XtSetArg(al
[ac
], XmNbottomOffset
, 6); ac
++;
954 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
955 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_NONE
); ac
++;
956 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_NONE
); ac
++;
957 icon_separator
= XmCreateLabel (form
, "", al
, ac
);
962 XtSetArg(al
[ac
], XmNcolumns
, 50); ac
++;
963 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
964 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
965 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
966 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
967 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
968 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
969 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
970 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
971 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
972 value
= XmCreateTextField (form
, "value", al
, ac
);
978 XtSetArg(al
[ac
], XmNmarginWidth
, 0); ac
++;
979 XtSetArg(al
[ac
], XmNmarginHeight
, 0); ac
++;
980 XtSetArg(al
[ac
], XmNspacing
, 13); ac
++;
981 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_CENTER
); ac
++;
982 XtSetArg(al
[ac
], XmNorientation
, XmHORIZONTAL
); ac
++;
983 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
984 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
985 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
986 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
987 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
988 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
989 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
990 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
991 value
= XmCreateRadioBox (form
, "radiobutton1", al
, ac
);
994 radio_butt
= XmCreateToggleButtonGadget (value
, "radio1", al
, ac
);
995 children
[i
++] = radio_butt
;
996 radio_butt
= XmCreateToggleButtonGadget (value
, "radio2", al
, ac
);
997 children
[i
++] = radio_butt
;
998 radio_butt
= XmCreateToggleButtonGadget (value
, "radio3", al
, ac
);
999 children
[i
++] = radio_butt
;
1000 XtManageChildren (children
, i
);
1005 XtSetArg(al
[ac
], XmNvisibleItemCount
, 5); ac
++;
1006 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_NONE
); ac
++;
1007 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
1008 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
1009 XtSetArg(al
[ac
], XmNbottomWidget
, separator
); ac
++;
1010 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
1011 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
1012 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
1013 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
1014 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
1015 value
= XmCreateScrolledList (form
, "list", al
, ac
);
1017 /* this is the easiest way I found to have the dble click in the
1018 list activate the default button */
1019 XtAddCallback (value
, XmNdefaultActionCallback
, activate_button
, button
);
1023 XtSetArg(al
[ac
], XmNalignment
, XmALIGNMENT_BEGINNING
); ac
++;
1024 XtSetArg(al
[ac
], XmNtopAttachment
, XmATTACH_FORM
); ac
++;
1025 XtSetArg(al
[ac
], XmNtopOffset
, 13); ac
++;
1026 XtSetArg(al
[ac
], XmNbottomAttachment
, XmATTACH_WIDGET
); ac
++;
1027 XtSetArg(al
[ac
], XmNbottomOffset
, 13); ac
++;
1028 XtSetArg(al
[ac
], XmNbottomWidget
,
1029 text_input_slot
|| radio_box
|| list
? value
: separator
); ac
++;
1030 XtSetArg(al
[ac
], XmNleftAttachment
, XmATTACH_WIDGET
); ac
++;
1031 XtSetArg(al
[ac
], XmNleftOffset
, 13); ac
++;
1032 XtSetArg(al
[ac
], XmNleftWidget
, icon
); ac
++;
1033 XtSetArg(al
[ac
], XmNrightAttachment
, XmATTACH_FORM
); ac
++;
1034 XtSetArg(al
[ac
], XmNrightOffset
, 13); ac
++;
1035 message
= XmCreateLabel (form
, "message", al
, ac
);
1038 XtManageChild (value
);
1041 children
[i
] = row
; i
++;
1042 children
[i
] = separator
; i
++;
1043 if (text_input_slot
|| radio_box
)
1045 children
[i
] = value
; i
++;
1047 children
[i
] = message
; i
++;
1048 children
[i
] = icon
; i
++;
1049 children
[i
] = icon_separator
; i
++;
1050 XtManageChildren (children
, i
);
1052 if (text_input_slot
|| list
)
1054 XtInstallAccelerators (value
, button
);
1055 XtSetKeyboardFocus (result
, value
);
1059 XtInstallAccelerators (form
, button
);
1060 XtSetKeyboardFocus (result
, button
);
1066 static destroyed_instance
*
1067 find_matching_instance (instance
)
1068 widget_instance
* instance
;
1070 destroyed_instance
* cur
;
1071 destroyed_instance
* prev
;
1072 char* type
= instance
->info
->type
;
1073 char* name
= instance
->info
->name
;
1075 for (prev
= NULL
, cur
= all_destroyed_instances
;
1077 prev
= cur
, cur
= cur
->next
)
1079 if (!strcmp (cur
->name
, name
)
1080 && !strcmp (cur
->type
, type
)
1081 && cur
->parent
== instance
->parent
1082 && cur
->pop_up_p
== instance
->pop_up_p
)
1085 prev
->next
= cur
->next
;
1087 all_destroyed_instances
= cur
->next
;
1090 /* do some cleanup */
1091 else if (!cur
->widget
)
1094 prev
->next
= cur
->next
;
1096 all_destroyed_instances
= cur
->next
;
1097 free_destroyed_instance (cur
);
1098 cur
= prev
? prev
: all_destroyed_instances
;
1105 mark_dead_instance_destroyed (widget
, closure
, call_data
)
1108 XtPointer call_data
;
1110 destroyed_instance
* instance
= (destroyed_instance
*)closure
;
1111 instance
->widget
= NULL
;
1115 recenter_widget (widget
)
1118 Widget parent
= XtParent (widget
);
1119 Screen
* screen
= XtScreen (widget
);
1120 Dimension screen_width
= WidthOfScreen (screen
);
1121 Dimension screen_height
= HeightOfScreen (screen
);
1122 Dimension parent_width
= 0;
1123 Dimension parent_height
= 0;
1124 Dimension child_width
= 0;
1125 Dimension child_height
= 0;
1129 XtVaGetValues (widget
, XtNwidth
, &child_width
, XtNheight
, &child_height
, 0);
1130 XtVaGetValues (parent
, XtNwidth
, &parent_width
, XtNheight
, &parent_height
,
1133 x
= (((Position
)parent_width
) - ((Position
)child_width
)) / 2;
1134 y
= (((Position
)parent_height
) - ((Position
)child_height
)) / 2;
1136 XtTranslateCoords (parent
, x
, y
, &x
, &y
);
1138 if (x
+ child_width
> screen_width
)
1139 x
= screen_width
- child_width
;
1143 if (y
+ child_height
> screen_height
)
1144 y
= screen_height
- child_height
;
1148 XtVaSetValues (widget
, XtNx
, x
, XtNy
, y
, 0);
1152 recycle_instance (instance
)
1153 destroyed_instance
* instance
;
1155 Widget widget
= instance
->widget
;
1157 /* widget is NULL if the parent was destroyed. */
1163 /* Remove the destroy callback as the instance is not in the list
1165 XtRemoveCallback (instance
->parent
, XtNdestroyCallback
,
1166 mark_dead_instance_destroyed
,
1167 (XtPointer
)instance
);
1169 /* Give the focus to the initial item */
1170 focus
= XtNameToWidget (widget
, "*value");
1172 focus
= XtNameToWidget (widget
, "*button1");
1174 XtSetKeyboardFocus (widget
, focus
);
1176 /* shrink the separator label back to their original size */
1177 separator
= XtNameToWidget (widget
, "*separator_button");
1179 XtVaSetValues (separator
, XtNwidth
, 5, XtNheight
, 5, 0);
1181 /* Center the dialog in its parent */
1182 recenter_widget (widget
);
1184 free_destroyed_instance (instance
);
1189 xm_create_dialog (instance
)
1190 widget_instance
* instance
;
1192 char* name
= instance
->info
->type
;
1193 Widget parent
= instance
->parent
;
1195 Boolean pop_up_p
= instance
->pop_up_p
;
1196 char* shell_name
= 0;
1198 Boolean text_input_slot
= False
;
1199 Boolean radio_box
= False
;
1200 Boolean list
= False
;
1202 int left_buttons
= 0;
1203 int right_buttons
= 1;
1204 destroyed_instance
* dead_one
;
1206 /* try to find a widget to recycle */
1207 dead_one
= find_matching_instance (instance
);
1210 Widget recycled_widget
= recycle_instance (dead_one
);
1211 if (recycled_widget
)
1212 return recycled_widget
;
1217 icon_name
= "dbox-error";
1218 shell_name
= "Error";
1222 icon_name
= "dbox-info";
1223 shell_name
= "Information";
1228 icon_name
= "dbox-question";
1229 shell_name
= "Prompt";
1233 text_input_slot
= True
;
1234 icon_name
= "dbox-question";
1235 shell_name
= "Prompt";
1239 icon_name
= "dbox-question";
1240 shell_name
= "Question";
1244 total_buttons
= name
[1] - '0';
1246 if (name
[3] == 'T' || name
[3] == 't')
1248 text_input_slot
= False
;
1252 right_buttons
= name
[4] - '0';
1254 left_buttons
= total_buttons
- right_buttons
;
1256 widget
= make_dialog (name
, parent
, pop_up_p
,
1257 shell_name
, icon_name
, text_input_slot
, radio_box
,
1258 list
, left_buttons
, right_buttons
);
1260 XtAddCallback (widget
, XmNpopdownCallback
, xm_nosel_callback
,
1261 (XtPointer
) instance
);
1266 make_menubar (instance
)
1267 widget_instance
* instance
;
1269 return XmCreateMenuBar (instance
->parent
, instance
->info
->name
, NULL
, 0);
1273 remove_grabs (shell
, closure
, call_data
)
1276 XtPointer call_data
;
1278 Widget menu
= (Widget
) closure
;
1279 XmRemoveFromPostFromList (menu
, XtParent (XtParent (menu
)));
1283 make_popup_menu (instance
)
1284 widget_instance
* instance
;
1286 Widget parent
= instance
->parent
;
1287 Window parent_window
= parent
->core
.window
;
1290 /* sets the parent window to 0 to fool Motif into not generating a grab */
1291 parent
->core
.window
= 0;
1292 result
= XmCreatePopupMenu (parent
, instance
->info
->name
, NULL
, 0);
1293 XtAddCallback (XtParent (result
), XmNpopdownCallback
, remove_grabs
,
1295 parent
->core
.window
= parent_window
;
1299 make_main (instance
)
1300 widget_instance
* instance
;
1302 Widget parent
= instance
->parent
;
1308 XtSetArg (al
[ac
], XtNborderWidth
, 0); ac
++;
1309 XtSetArg (al
[ac
], XmNspacing
, 0); ac
++;
1310 result
= XmCreateMainWindow (parent
, instance
->info
->name
, al
, ac
);
1314 \f/* Table of functions to create widgets */
1318 /* interface with the XDesigner generated functions */
1319 typedef Widget (*widget_maker
) (Widget
);
1320 extern Widget
create_project_p_sheet (Widget parent
);
1321 extern Widget
create_debugger_p_sheet (Widget parent
);
1322 extern Widget
create_breaklist_p_sheet (Widget parent
);
1323 extern Widget
create_le_browser_p_sheet (Widget parent
);
1324 extern Widget
create_class_browser_p_sheet (Widget parent
);
1325 extern Widget
create_call_browser_p_sheet (Widget parent
);
1326 extern Widget
create_build_dialog (Widget parent
);
1327 extern Widget
create_editmode_dialog (Widget parent
);
1328 extern Widget
create_search_dialog (Widget parent
);
1329 extern Widget
create_project_display_dialog (Widget parent
);
1332 make_one (widget_instance
* instance
, widget_maker fn
)
1338 if (instance
->pop_up_p
)
1340 XtSetArg (al
[ac
], XmNallowShellResize
, TRUE
); ac
++;
1341 result
= XmCreateDialogShell (instance
->parent
, "dialog", NULL
, 0);
1342 XtAddCallback (result
, XmNpopdownCallback
, &xm_nosel_callback
,
1343 (XtPointer
) instance
);
1348 result
= (*fn
) (instance
->parent
);
1349 XtRealizeWidget (result
);
1355 make_project_p_sheet (widget_instance
* instance
)
1357 return make_one (instance
, create_project_p_sheet
);
1361 make_debugger_p_sheet (widget_instance
* instance
)
1363 return make_one (instance
, create_debugger_p_sheet
);
1367 make_breaklist_p_sheet (widget_instance
* instance
)
1369 return make_one (instance
, create_breaklist_p_sheet
);
1373 make_le_browser_p_sheet (widget_instance
* instance
)
1375 return make_one (instance
, create_le_browser_p_sheet
);
1379 make_class_browser_p_sheet (widget_instance
* instance
)
1381 return make_one (instance
, create_class_browser_p_sheet
);
1385 make_call_browser_p_sheet (widget_instance
* instance
)
1387 return make_one (instance
, create_call_browser_p_sheet
);
1391 make_build_dialog (widget_instance
* instance
)
1393 return make_one (instance
, create_build_dialog
);
1397 make_editmode_dialog (widget_instance
* instance
)
1399 return make_one (instance
, create_editmode_dialog
);
1403 make_search_dialog (widget_instance
* instance
)
1405 return make_one (instance
, create_search_dialog
);
1409 make_project_display_dialog (widget_instance
* instance
)
1411 return make_one (instance
, create_project_display_dialog
);
1414 #endif /* ENERGIZE */
1416 widget_creation_entry
1417 xm_creation_table
[] =
1419 {"menubar", make_menubar
},
1420 {"popup", make_popup_menu
},
1421 {"main", make_main
},
1423 {"project_p_sheet", make_project_p_sheet
},
1424 {"debugger_p_sheet", make_debugger_p_sheet
},
1425 {"breaklist_psheet", make_breaklist_p_sheet
},
1426 {"leb_psheet", make_le_browser_p_sheet
},
1427 {"class_browser_psheet", make_class_browser_p_sheet
},
1428 {"ctree_browser_psheet", make_call_browser_p_sheet
},
1429 {"build", make_build_dialog
},
1430 {"editmode", make_editmode_dialog
},
1431 {"search", make_search_dialog
},
1432 {"project_display", make_project_display_dialog
},
1433 #endif /* ENERGIZE */
1437 \f/* Destruction of instances */
1439 xm_destroy_instance (instance
)
1440 widget_instance
* instance
;
1442 Widget widget
= instance
->widget
;
1443 /* recycle the dialog boxes */
1444 /* Disable the recycling until we can find a way to have the dialog box
1445 get reasonable layout after we modify its contents. */
1447 && XtClass (widget
) == xmDialogShellWidgetClass
)
1449 destroyed_instance
* dead_instance
=
1450 make_destroyed_instance (instance
->info
->name
,
1451 instance
->info
->type
,
1454 instance
->pop_up_p
);
1455 dead_instance
->next
= all_destroyed_instances
;
1456 all_destroyed_instances
= dead_instance
;
1457 XtUnmanageChild (first_child (instance
->widget
));
1458 XFlush (XtDisplay (instance
->widget
));
1459 XtAddCallback (instance
->parent
, XtNdestroyCallback
,
1460 mark_dead_instance_destroyed
, (XtPointer
)dead_instance
);
1464 /* This might not be necessary now that the nosel is attached to
1465 popdown instead of destroy, but it can't hurt. */
1466 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
1467 xm_nosel_callback
, (XtPointer
)instance
);
1468 XtDestroyWidget (instance
->widget
);
1472 \f/* popup utility */
1474 xm_popup_menu (widget
, event
)
1478 XButtonPressedEvent dummy
;
1482 dummy
.type
= ButtonPress
;
1484 dummy
.send_event
= 0;
1485 dummy
.display
= XtDisplay (widget
);
1486 dummy
.window
= XtWindow (XtParent (widget
));
1489 XQueryPointer (dummy
.display
, dummy
.window
, &dummy
.root
,
1490 &dummy
.subwindow
, &dummy
.x_root
, &dummy
.y_root
,
1491 &dummy
.x
, &dummy
.y
, &dummy
.state
);
1492 event
= (XEvent
*) &dummy
;
1495 if (event
->type
== ButtonPress
|| event
->type
== ButtonRelease
)
1497 /* This is so totally ridiculous: there's NO WAY to tell Motif
1498 that *any* button can select a menu item. Only one button
1499 can have that honor.
1502 if (event
->xbutton
.state
& Button5Mask
) trans
= "<Btn5Down>";
1503 else if (event
->xbutton
.state
& Button4Mask
) trans
= "<Btn4Down>";
1504 else if (event
->xbutton
.state
& Button3Mask
) trans
= "<Btn3Down>";
1505 else if (event
->xbutton
.state
& Button2Mask
) trans
= "<Btn2Down>";
1506 else if (event
->xbutton
.state
& Button1Mask
) trans
= "<Btn1Down>";
1507 if (trans
) XtVaSetValues (widget
, XmNmenuPost
, trans
, 0);
1508 XmMenuPosition (widget
, (XButtonPressedEvent
*) event
);
1510 XtManageChild (widget
);
1514 set_min_dialog_size (w
)
1519 XtVaGetValues (w
, XmNwidth
, &width
, XmNheight
, &height
, 0);
1520 XtVaSetValues (w
, XmNminWidth
, width
, XmNminHeight
, height
, 0);
1524 xm_pop_instance (instance
, up
)
1525 widget_instance
* instance
;
1528 Widget widget
= instance
->widget
;
1530 if (XtClass (widget
) == xmDialogShellWidgetClass
)
1532 Widget widget_to_manage
= first_child (widget
);
1535 XtManageChild (widget_to_manage
);
1536 set_min_dialog_size (widget
);
1537 XtSetKeyboardFocus (instance
->parent
, widget
);
1540 XtUnmanageChild (widget_to_manage
);
1545 XtManageChild (widget
);
1547 XtUnmanageChild (widget
);
1552 /* motif callback */
1554 enum do_call_type
{ pre_activate
, selection
, no_selection
, post_activate
};
1557 do_call (widget
, closure
, type
)
1560 enum do_call_type type
;
1564 XtPointer user_data
;
1565 widget_instance
* instance
= (widget_instance
*)closure
;
1566 Widget instance_widget
;
1571 if (widget
->core
.being_destroyed
)
1574 instance_widget
= instance
->widget
;
1575 if (!instance_widget
)
1578 id
= instance
->info
->id
;
1581 XtSetArg (al
[ac
], XmNuserData
, &user_data
); ac
++;
1582 XtGetValues (widget
, al
, ac
);
1586 if (instance
->info
->pre_activate_cb
)
1587 instance
->info
->pre_activate_cb (widget
, id
, user_data
);
1590 if (instance
->info
->selection_cb
)
1591 instance
->info
->selection_cb (widget
, id
, user_data
);
1594 if (instance
->info
->selection_cb
)
1595 instance
->info
->selection_cb (widget
, id
, (XtPointer
) -1);
1598 if (instance
->info
->post_activate_cb
)
1599 instance
->info
->post_activate_cb (widget
, id
, user_data
);
1606 /* Like lw_internal_update_other_instances except that it does not do
1607 anything if its shell parent is not managed. This is to protect
1608 lw_internal_update_other_instances to dereference freed memory
1609 if the widget was ``destroyed'' by caching it in the all_destroyed_instances
1612 xm_internal_update_other_instances (widget
, closure
, call_data
)
1615 XtPointer call_data
;
1618 for (parent
= widget
; parent
; parent
= XtParent (parent
))
1619 if (XtIsShell (parent
))
1621 else if (!XtIsManaged (parent
))
1623 lw_internal_update_other_instances (widget
, closure
, call_data
);
1627 xm_generic_callback (widget
, closure
, call_data
)
1630 XtPointer call_data
;
1632 lw_internal_update_other_instances (widget
, closure
, call_data
);
1633 do_call (widget
, closure
, selection
);
1637 xm_nosel_callback (widget
, closure
, call_data
)
1640 XtPointer call_data
;
1642 /* This callback is only called when a dialog box is dismissed with the wm's
1643 destroy button (WM_DELETE_WINDOW.) We want the dialog box to be destroyed
1644 in that case, not just unmapped, so that it releases its keyboard grabs.
1645 But there are problems with running our callbacks while the widget is in
1646 the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
1647 instead of XmDESTROY and then destroy it ourself after having run the
1650 do_call (widget
, closure
, no_selection
);
1651 XtDestroyWidget (widget
);
1655 xm_pull_down_callback (widget
, closure
, call_data
)
1658 XtPointer call_data
;
1660 do_call (widget
, closure
, pre_activate
);
1664 xm_pop_down_callback (widget
, closure
, call_data
)
1667 XtPointer call_data
;
1669 widget_instance
*instance
= (widget_instance
*) closure
;
1671 if ((!instance
->pop_up_p
&& (XtParent (widget
) == instance
->widget
))
1672 || (XtParent (widget
) == instance
->parent
))
1673 do_call (widget
, closure
, post_activate
);
1677 /* set the keyboard focus */
1679 xm_set_keyboard_focus (parent
, w
)
1683 XmProcessTraversal (w
, 0);
1684 XtSetKeyboardFocus (parent
, w
);
1687 /* Motif hack to set the main window areas. */
1689 xm_set_main_areas (parent
, menubar
, work_area
)
1694 XmMainWindowSetAreas (parent
,
1695 menubar
, /* menubar (maybe 0) */
1696 0, /* command area (psheets) */
1697 0, /* horizontal scroll */
1698 0, /* vertical scroll */
1699 work_area
); /* work area */
1702 /* Motif hack to control resizing on the menubar. */
1704 xm_manage_resizing (w
, flag
)
1710 /* Enable the edit widget for resizing. */
1713 XtSetArg (al
[0], XtNallowShellResize
, 0);
1714 XtSetValues (w
, al
, 1);
1718 /* Disable the edit widget from resizing. */
1721 XtSetArg (al
[0], XtNallowShellResize
, 0);
1722 XtSetValues (w
, al
, 1);