]> code.delx.au - gnu-emacs/blobdiff - lwlib/lwlib-Xm.c
(idlwave-completion-help-info): Add defvar.
[gnu-emacs] / lwlib / lwlib-Xm.c
index 7444d3634dcae85fa834dace512cb06c1334b226..32abbca760195dd534feabee2b69db4ab3d0f422 100644 (file)
@@ -1,25 +1,30 @@
 /* The lwlib interface to Motif widgets.
 /* The lwlib interface to Motif widgets.
+   Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
+                 2004, 2005 Free Software Foundation, Inc.
    Copyright (C) 1992 Lucid, Inc.
 
 This file is part of the Lucid Widget Library.
 
    Copyright (C) 1992 Lucid, Inc.
 
 This file is part of the Lucid Widget Library.
 
-The Lucid Widget Library is free software; you can redistribute it and/or 
+The Lucid Widget Library is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 modify it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 The Lucid Widget Library is distributed in the hope that it will be useful,
 any later version.
 
 The Lucid Widget Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of 
+but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 
-#include <stdlib.h>
 #include <unistd.h>
 #include <unistd.h>
-#include <string.h>
 #include <stdio.h>
 
 #include <X11/StringDefs.h>
 #include <stdio.h>
 
 #include <X11/StringDefs.h>
@@ -28,11 +33,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <X11/CoreP.h>
 #include <X11/CompositeP.h>
 
 #include <X11/CoreP.h>
 #include <X11/CompositeP.h>
 
+#include "../src/lisp.h"
+
 #include "lwlib-Xm.h"
 #include "lwlib-utils.h"
 
 #include <Xm/BulletinB.h>
 #include <Xm/CascadeB.h>
 #include "lwlib-Xm.h"
 #include "lwlib-utils.h"
 
 #include <Xm/BulletinB.h>
 #include <Xm/CascadeB.h>
+#include <Xm/CascadeBG.h>
 #include <Xm/DrawingA.h>
 #include <Xm/FileSB.h>
 #include <Xm/Label.h>
 #include <Xm/DrawingA.h>
 #include <Xm/FileSB.h>
 #include <Xm/Label.h>
@@ -55,19 +63,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <Xm/DialogS.h>
 #include <Xm/Form.h>
 
 #include <Xm/DialogS.h>
 #include <Xm/Form.h>
 
-static void xm_pull_down_callback (Widget, XtPointer, XtPointer);
-static void xm_internal_update_other_instances (Widget, XtPointer,
-                                               XtPointer);
-static void xm_generic_callback (Widget, XtPointer, XtPointer);
-static void xm_nosel_callback (Widget, XtPointer, XtPointer);
-static void xm_pop_down_callback (Widget, XtPointer, XtPointer);
+#undef P_
+#if defined __STDC__ || defined PROTOTYPES
+#define P_(X) X
+#else
+#define P_(X) ()
+#endif
+
+enum do_call_type { pre_activate, selection, no_selection, post_activate };
 
 
-static void
-xm_update_menu (widget_instance* instance, Widget widget, widget_value* val,
-               Boolean deep_p);
 
 \f/* Structures to keep destroyed instances */
 
 \f/* Structures to keep destroyed instances */
-typedef struct _destroyed_instance 
+typedef struct _destroyed_instance
 {
   char*                name;
   char*                type;
 {
   char*                name;
   char*                type;
@@ -77,12 +84,101 @@ typedef struct _destroyed_instance
   struct _destroyed_instance*  next;
 } destroyed_instance;
 
   struct _destroyed_instance*  next;
 } destroyed_instance;
 
-static destroyed_instance*
-all_destroyed_instances = NULL;
+static destroyed_instance *make_destroyed_instance P_ ((char *, char *,
+                                                       Widget, Widget,
+                                                       Boolean));
+static void free_destroyed_instance P_ ((destroyed_instance*));
+Widget first_child P_ ((Widget));
+Boolean lw_motif_widget_p P_ ((Widget));
+static XmString resource_motif_string P_ ((Widget, char *));
+static void destroy_all_children P_ ((Widget, int));
+static void xm_update_label P_ ((widget_instance *, Widget, widget_value *));
+static void xm_update_list P_ ((widget_instance *, Widget, widget_value *));
+static void xm_update_pushbutton P_ ((widget_instance *, Widget,
+                                     widget_value *));
+static void xm_update_cascadebutton P_ ((widget_instance *, Widget,
+                                        widget_value *));
+static void xm_update_toggle P_ ((widget_instance *, Widget, widget_value *));
+static void xm_update_radiobox P_ ((widget_instance *, Widget, widget_value *));
+static void make_menu_in_widget P_ ((widget_instance *, Widget,
+                                    widget_value *, int));
+static void update_one_menu_entry P_ ((widget_instance *, Widget,
+                                      widget_value *, Boolean));
+static void xm_update_menu P_ ((widget_instance *, Widget, widget_value *,
+                               Boolean));
+static void xm_update_text P_ ((widget_instance *, Widget, widget_value *));
+static void xm_update_text_field P_ ((widget_instance *, Widget,
+                                     widget_value *));
+void xm_update_one_value P_ ((widget_instance *, Widget, widget_value *));
+static void activate_button P_ ((Widget, XtPointer, XtPointer));
+static Widget make_dialog P_ ((char *, Widget, Boolean, char *, char *,
+                              Boolean, Boolean, Boolean, int, int));
+static destroyed_instance* find_matching_instance P_ ((widget_instance*));
+static void mark_dead_instance_destroyed P_ ((Widget, XtPointer, XtPointer));
+static void recenter_widget P_ ((Widget));
+static Widget recycle_instance P_ ((destroyed_instance*));
+Widget xm_create_dialog P_ ((widget_instance*));
+static Widget make_menubar P_ ((widget_instance*));
+static void remove_grabs P_ ((Widget, XtPointer, XtPointer));
+static Widget make_popup_menu P_ ((widget_instance*));
+static Widget make_main P_ ((widget_instance*));
+void xm_destroy_instance P_ ((widget_instance*));
+void xm_popup_menu P_ ((Widget, XEvent *));
+static void set_min_dialog_size P_ ((Widget));
+static void do_call P_ ((Widget, XtPointer, enum do_call_type));
+static void xm_generic_callback P_ ((Widget, XtPointer, XtPointer));
+static void xm_nosel_callback P_ ((Widget, XtPointer, XtPointer));
+static void xm_pull_down_callback P_ ((Widget, XtPointer, XtPointer));
+static void xm_pop_down_callback P_ ((Widget, XtPointer, XtPointer));
+void xm_set_keyboard_focus P_ ((Widget, Widget));
+void xm_set_main_areas P_ ((Widget, Widget, Widget));
+static void xm_internal_update_other_instances P_ ((Widget, XtPointer,
+                                                   XtPointer));
+static void xm_arm_callback P_ ((Widget, XtPointer, XtPointer));
+
+#if 0
+void xm_update_one_widget P_ ((widget_instance *, Widget, widget_value *,
+                              Boolean));
+void xm_pop_instance P_ ((widget_instance*, Boolean));
+void xm_manage_resizing P_ ((Widget, Boolean));
+#endif
+
+
+#if 0
+
+/* Print the complete X resource name of widget WIDGET to stderr.
+   This is sometimes handy to have available.  */
+
+void
+x_print_complete_resource_name (widget)
+     Widget widget;
+{
+  int i;
+  String names[100];
+
+  for (i = 0; i < 100 && widget != NULL; ++i)
+    {
+      names[i] = XtName (widget);
+      widget = XtParent (widget);
+    }
+
+  for (--i; i >= 1; --i)
+    fprintf (stderr, "%s.", names[i]);
+  fprintf (stderr, "%s\n", names[0]);
+}
+
+#endif /* 0 */
+
+
+static destroyed_instance *all_destroyed_instances = NULL;
 
 static destroyed_instance*
 
 static destroyed_instance*
-make_destroyed_instance (char* name, char* type, Widget widget, Widget parent,
-                        Boolean pop_up_p)
+make_destroyed_instance (name, type, widget, parent, pop_up_p)
+     char* name;
+     char* type;
+     Widget widget;
+     Widget parent;
+     Boolean pop_up_p;
 {
   destroyed_instance* instance =
     (destroyed_instance*)malloc (sizeof (destroyed_instance));
 {
   destroyed_instance* instance =
     (destroyed_instance*)malloc (sizeof (destroyed_instance));
@@ -94,9 +190,10 @@ make_destroyed_instance (char* name, char* type, Widget widget, Widget parent,
   instance->next = NULL;
   return instance;
 }
   instance->next = NULL;
   return instance;
 }
-                        
+
 static void
 static void
-free_destroyed_instance (destroyed_instance* instance)
+free_destroyed_instance (instance)
+     destroyed_instance* instance;
 {
   free (instance->name);
   free (instance->type);
 {
   free (instance->name);
   free (instance->type);
@@ -105,25 +202,29 @@ free_destroyed_instance (destroyed_instance* instance)
 
 \f/* motif utility functions */
 Widget
 
 \f/* motif utility functions */
 Widget
-first_child (Widget widget)
+first_child (widget)
+     Widget widget;
 {
   return ((CompositeWidget)widget)->composite.children [0];
 }
 
 Boolean
 {
   return ((CompositeWidget)widget)->composite.children [0];
 }
 
 Boolean
-lw_motif_widget_p (Widget widget)
+lw_motif_widget_p (widget)
+     Widget widget;
 {
 {
-  return 
+  return
     XtClass (widget) == xmDialogShellWidgetClass
       || XmIsPrimitive (widget) || XmIsManager (widget) || XmIsGadget (widget);
 }
 
 static XmString
     XtClass (widget) == xmDialogShellWidgetClass
       || XmIsPrimitive (widget) || XmIsManager (widget) || XmIsGadget (widget);
 }
 
 static XmString
-resource_motif_string (Widget widget, char* name)
+resource_motif_string (widget, name)
+     Widget widget;
+     char* name;
 {
   XtResource resource;
   XmString result = 0;
 {
   XtResource resource;
   XmString result = 0;
-  
+
   resource.resource_name = name;
   resource.resource_class = XmCXmString;
   resource.resource_type = XmRXmString;
   resource.resource_name = name;
   resource.resource_class = XmCXmString;
   resource.resource_type = XmRXmString;
@@ -137,8 +238,13 @@ resource_motif_string (Widget widget, char* name)
   return result;
 }
 
   return result;
 }
 
+/* Destroy all of the children of WIDGET
+   starting with number FIRST_CHILD_TO_DESTROY.  */
+
 static void
 static void
-destroy_all_children (Widget widget)
+destroy_all_children (widget, first_child_to_destroy)
+     Widget widget;
+     int first_child_to_destroy;
 {
   Widget* children;
   unsigned int number;
 {
   Widget* children;
   unsigned int number;
@@ -147,35 +253,114 @@ destroy_all_children (Widget widget)
   children = XtCompositeChildren (widget, &number);
   if (children)
     {
   children = XtCompositeChildren (widget, &number);
   if (children)
     {
-      /* Unmanage all children and destroy them.  They will only be 
-       * really destroyed when we get out of DispatchEvent. */
-      for (i = 0; i < number; i++)
+      XtUnmanageChildren (children + first_child_to_destroy,
+                         number - first_child_to_destroy);
+
+      /* Unmanage all children and destroy them.  They will only be
+        really destroyed when we get out of DispatchEvent.  */
+      for (i = first_child_to_destroy; i < number; i++)
        {
        {
-         Widget child = children [i];
-         if (!child->core.being_destroyed)
-           {
-             XtUnmanageChild (child);
-             XtDestroyWidget (child);
-           }
+         Arg al[2];
+         Widget submenu = 0;
+         /* Cascade buttons have submenus,and these submenus
+            need to be freed.  But they are not included in
+            XtCompositeChildren.  So get it out of the cascade button
+            and free it.  If this child is not a cascade button,
+            then submenu should remain unchanged.  */
+         XtSetArg (al[0], XmNsubMenuId, &submenu);
+         XtGetValues (children[i], al, 1);
+         if (submenu)
+            {
+              destroy_all_children (submenu, 0);
+              XtDestroyWidget (submenu);
+            }
+         XtDestroyWidget (children[i]);
        }
        }
+
       XtFree ((char *) children);
     }
 }
 
       XtFree ((char *) children);
     }
 }
 
-\f/* update the label of anything subclass of a label */
+
+\f
+/* Callback XmNarmCallback and XmNdisarmCallback for buttons in a
+   menu.  CLIENT_DATA contains a pointer to the widget_value
+   corresponding to widget W.  CALL_DATA contains a
+   XmPushButtonCallbackStruct containing the reason why the callback
+   is called.  */
+
+static void
+xm_arm_callback (w, client_data, call_data)
+     Widget w;
+     XtPointer client_data, call_data;
+{
+  XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *) call_data;
+  widget_value *wv = (widget_value *) client_data;
+  widget_instance *instance;
+
+  /* Get the id of the menu bar or popup menu this widget is in.  */
+  while (w != NULL)
+    {
+      if (XmIsRowColumn (w))
+       {
+         unsigned char type = 0xff;
+
+         XtVaGetValues (w, XmNrowColumnType, &type, NULL);
+         if (type == XmMENU_BAR || type == XmMENU_POPUP)
+           break;
+       }
+
+      w = XtParent (w);
+    }
+
+  if (w != NULL)
+    {
+      instance = lw_get_widget_instance (w);
+      if (instance && instance->info->highlight_cb)
+       {
+         call_data = cbs->reason == XmCR_DISARM ? NULL : wv;
+         instance->info->highlight_cb (w, instance->info->id, call_data);
+       }
+    }
+}
+
+
+\f
+/* Update the label of widget WIDGET.  WIDGET must be a Label widget
+   or a subclass of Label.  WIDGET_INSTANCE is unused.  VAL contains
+   the value to update.
+
+   Menus:
+
+   Emacs fills VAL->name with the text to display in the menu, and
+   sets VAL->value to null.  Function make_menu_in_widget creates
+   widgets with VAL->name as resource name.  This works because the
+   Label widget uses its resource name for display if no
+   XmNlabelString is set.
+
+   Dialogs:
+
+   VAL->name is again set to the resource name, but VAL->value is
+   not null, and contains the label string to display.  */
+
 static void
 static void
-xm_update_label (widget_instance* instance, Widget widget, widget_value* val)
+xm_update_label (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
 {
   XmString res_string = 0;
   XmString built_string = 0;
   XmString key_string = 0;
   Arg al [256];
   int ac;
 {
   XmString res_string = 0;
   XmString built_string = 0;
   XmString key_string = 0;
   Arg al [256];
   int ac;
-  
+
   ac = 0;
 
   if (val->value)
     {
   ac = 0;
 
   if (val->value)
     {
+      /* A label string is specified, i.e. we are in a dialog.  First
+        see if it is overridden by something from the resource file.  */
       res_string = resource_motif_string (widget, val->value);
 
       if (res_string)
       res_string = resource_motif_string (widget, val->value);
 
       if (res_string)
@@ -185,15 +370,16 @@ xm_update_label (widget_instance* instance, Widget widget, widget_value* val)
       else
        {
          built_string =
       else
        {
          built_string =
-           XmStringCreateLtoR (val->value, XmSTRING_DEFAULT_CHARSET);
+           XmStringCreateLocalized (val->value);
          XtSetArg (al [ac], XmNlabelString, built_string); ac++;
        }
          XtSetArg (al [ac], XmNlabelString, built_string); ac++;
        }
+
       XtSetArg (al [ac], XmNlabelType, XmSTRING); ac++;
     }
       XtSetArg (al [ac], XmNlabelType, XmSTRING); ac++;
     }
-  
+
   if (val->key)
     {
   if (val->key)
     {
-      key_string = XmStringCreateLtoR (val->key, XmSTRING_DEFAULT_CHARSET);
+      key_string = XmStringCreateLocalized (val->key);
       XtSetArg (al [ac], XmNacceleratorText, key_string); ac++;
     }
 
       XtSetArg (al [ac], XmNacceleratorText, key_string); ac++;
     }
 
@@ -209,7 +395,10 @@ xm_update_label (widget_instance* instance, Widget widget, widget_value* val)
 
 \f/* update of list */
 static void
 
 \f/* update of list */
 static void
-xm_update_list (widget_instance* instance, Widget widget, widget_value* val)
+xm_update_list (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
 {
   widget_value* cur;
   int i;
 {
   widget_value* cur;
   int i;
@@ -219,7 +408,7 @@ xm_update_list (widget_instance* instance, Widget widget, widget_value* val)
   for (cur = val->contents, i = 0; cur; cur = cur->next)
     if (cur->value)
       {
   for (cur = val->contents, i = 0; cur; cur = cur->next)
     if (cur->value)
       {
-       XmString xmstr = XmStringCreate (cur->value, XmSTRING_DEFAULT_CHARSET);
+       XmString xmstr = XmStringCreateLocalized (cur->value);
        i += 1;
        XmListAddItem (widget, xmstr, 0);
        if (cur->selected)
        i += 1;
        XmListAddItem (widget, xmstr, 0);
        if (cur->selected)
@@ -230,17 +419,21 @@ xm_update_list (widget_instance* instance, Widget widget, widget_value* val)
 
 \f/* update of buttons */
 static void
 
 \f/* update of buttons */
 static void
-xm_update_pushbutton (widget_instance* instance, Widget widget,
-                     widget_value* val)
+xm_update_pushbutton (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
 {
 {
-  XtVaSetValues (widget, XmNalignment, XmALIGNMENT_CENTER, 0);
+  XtVaSetValues (widget, XmNalignment, XmALIGNMENT_CENTER, NULL);
   XtRemoveAllCallbacks (widget, XmNactivateCallback);
   XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
 }
 
 static void
   XtRemoveAllCallbacks (widget, XmNactivateCallback);
   XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
 }
 
 static void
-xm_update_cascadebutton (widget_instance* instance, Widget widget,
-                        widget_value* val)
+xm_update_cascadebutton (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
 {
   /* Should also rebuild the menu by calling ...update_menu... */
   XtRemoveAllCallbacks (widget, XmNcascadingCallback);
 {
   /* Should also rebuild the menu by calling ...update_menu... */
   XtRemoveAllCallbacks (widget, XmNcascadingCallback);
@@ -250,18 +443,24 @@ xm_update_cascadebutton (widget_instance* instance, Widget widget,
 
 \f/* update toggle and radiobox */
 static void
 
 \f/* update toggle and radiobox */
 static void
-xm_update_toggle (widget_instance* instance, Widget widget, widget_value* val)
+xm_update_toggle (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
 {
   XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
   XtAddCallback (widget, XmNvalueChangedCallback,
 {
   XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
   XtAddCallback (widget, XmNvalueChangedCallback,
-                xm_internal_update_other_instances, instance);
+                xm_generic_callback, instance);
   XtVaSetValues (widget, XmNset, val->selected,
   XtVaSetValues (widget, XmNset, val->selected,
-                XmNalignment, XmALIGNMENT_BEGINNING, 0);
+                XmNalignment, XmALIGNMENT_BEGINNING, NULL);
 }
 
 static void
 }
 
 static void
-xm_update_radiobox (widget_instance* instance, Widget widget,
-                   widget_value* val)
+xm_update_radiobox (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
+
 {
   Widget toggle;
   widget_value* cur;
 {
   Widget toggle;
   widget_value* cur;
@@ -281,11 +480,11 @@ xm_update_radiobox (widget_instance* instance, Widget widget,
       toggle = XtNameToWidget (widget, cur->value);
       if (toggle)
        {
       toggle = XtNameToWidget (widget, cur->value);
       if (toggle)
        {
-         XtVaSetValues (toggle, XmNsensitive, cur->enabled, 0);
+         XtSetSensitive (toggle, cur->enabled);
          if (!val->value && cur->selected)
          if (!val->value && cur->selected)
-           XtVaSetValues (toggle, XmNset, cur->selected, 0);
+           XtVaSetValues (toggle, XmNset, cur->selected, NULL);
          if (val->value && strcmp (val->value, cur->value))
          if (val->value && strcmp (val->value, cur->value))
-           XtVaSetValues (toggle, XmNset, False, 0);
+           XtVaSetValues (toggle, XmNset, False, NULL);
        }
     }
 
        }
     }
 
@@ -294,66 +493,98 @@ xm_update_radiobox (widget_instance* instance, Widget widget,
     {
       toggle = XtNameToWidget (widget, val->value);
       if (toggle)
     {
       toggle = XtNameToWidget (widget, val->value);
       if (toggle)
-       XtVaSetValues (toggle, XmNset, True, 0);
+       XtVaSetValues (toggle, XmNset, True, NULL);
     }
 }
 
     }
 }
 
-\f/* update a popup menu, pulldown menu or a menubar */
-static Boolean
-all_dashes_p (char* s)
-{
-  char* t;
-  for (t = s; *t; t++)
-    if (*t != '-')
-      return False;
-  return True;
-}
+\f
+/* update a popup menu, pulldown menu or a menubar */
+
+/* KEEP_FIRST_CHILDREN gives the number of initial children to keep.  */
 
 static void
 
 static void
-make_menu_in_widget (widget_instance* instance, Widget widget,
-                    widget_value* val)
+make_menu_in_widget (instance, widget, val, keep_first_children)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
+     int keep_first_children;
 {
   Widget* children = 0;
   int num_children;
   int child_index;
   widget_value* cur;
   Widget button = 0;
 {
   Widget* children = 0;
   int num_children;
   int child_index;
   widget_value* cur;
   Widget button = 0;
+  Widget title = 0;
   Widget menu;
   Arg al [256];
   int ac;
   Boolean menubar_p;
   Widget menu;
   Arg al [256];
   int ac;
   Boolean menubar_p;
+  unsigned char type;
+
+  Widget* old_children;
+  unsigned int old_num_children;
+
+  /* Disable drag and drop for labels in menu bar.  */
+  static char overrideTrans[] = "<Btn2Down>: Noop()";
+  XtTranslations override = XtParseTranslationTable (overrideTrans);
+
+  old_children = XtCompositeChildren (widget, &old_num_children);
 
   /* Allocate the children array */
 
   /* Allocate the children array */
-  for (num_children = 0, cur = val; cur; num_children++, cur = cur->next);
+  for (num_children = 0, cur = val; cur; num_children++, cur = cur->next)
+    ;
   children = (Widget*)XtMalloc (num_children * sizeof (Widget));
 
   children = (Widget*)XtMalloc (num_children * sizeof (Widget));
 
-  /* tricky way to know if this RowColumn is a menubar or a pulldown... */
-  menubar_p = False;
-  XtSetArg (al[0], XmNisHomogeneous, &menubar_p);
+  /* WIDGET should be a RowColumn.  */
+  if (!XmIsRowColumn (widget))
+    abort ();
+
+  /* Determine whether WIDGET is a menu bar.  */
+  type = -1;
+  XtSetArg (al[0], XmNrowColumnType, &type);
   XtGetValues (widget, al, 1);
   XtGetValues (widget, al, 1);
+  if (type != XmMENU_BAR && type != XmMENU_PULLDOWN && type != XmMENU_POPUP)
+    abort ();
+  menubar_p = type == XmMENU_BAR;
 
 
-  /* add the unmap callback for popups and pulldowns */
-  /*** this sounds bogus ***/
+  /* Add a callback to popups and pulldowns that is called when
+     it is made invisible again.  */
   if (!menubar_p)
     XtAddCallback (XtParent (widget), XmNpopdownCallback,
                   xm_pop_down_callback, (XtPointer)instance);
 
   if (!menubar_p)
     XtAddCallback (XtParent (widget), XmNpopdownCallback,
                   xm_pop_down_callback, (XtPointer)instance);
 
-  for (child_index = 0, cur = val; cur; child_index++, cur = cur->next)
-    {    
+  /* Preserve the first KEEP_FIRST_CHILDREN old children.  */
+  for (child_index = 0, cur = val; child_index < keep_first_children;
+       child_index++, cur = cur->next)
+    children[child_index] = old_children[child_index];
+
+  /* Check that those are all we have
+     (the caller should have deleted the rest).  */
+  if (old_num_children != keep_first_children)
+    abort ();
+
+  /* Create the rest.  */
+  for (child_index = keep_first_children; cur; child_index++, cur = cur->next)
+    {
+      enum menu_separator separator;
+
       ac = 0;
       ac = 0;
-      XtSetArg (al [ac], XmNsensitive, cur->enabled); ac++;
-      XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
-      XtSetArg (al [ac], XmNuserData, cur->call_data); ac++;
-      
-      if (instance->pop_up_p && !cur->contents && !cur->call_data)
+      XtSetArg (al[ac], XmNsensitive, cur->enabled); ac++;
+      XtSetArg (al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
+      XtSetArg (al[ac], XmNuserData, cur->call_data); ac++;
+
+      if (instance->pop_up_p && !cur->contents && !cur->call_data
+         && !lw_separator_p (cur->name, &separator, 1))
        {
          ac = 0;
          XtSetArg (al[ac], XmNalignment, XmALIGNMENT_CENTER); ac++;
        {
          ac = 0;
          XtSetArg (al[ac], XmNalignment, XmALIGNMENT_CENTER); ac++;
-         button = XmCreateLabel (widget, cur->name, al, ac);
+         title = button = XmCreateLabel (widget, cur->name, al, ac);
        }
        }
-      else if (all_dashes_p (cur->name))
+      else if (lw_separator_p (cur->name, &separator, 1))
        {
        {
-         button = XmCreateSeparator (widget, cur->name, NULL, 0);
+         ac = 0;
+         XtSetArg (al[ac], XmNseparatorType, separator); ++ac;
+         button = XmCreateSeparator (widget, cur->name, al, ac);
        }
       else if (!cur->contents)
        {
        }
       else if (!cur->contents)
        {
@@ -361,86 +592,162 @@ make_menu_in_widget (widget_instance* instance, Widget widget,
            button = XmCreateCascadeButton (widget, cur->name, al, ac);
          else if (!cur->call_data)
            button = XmCreateLabel (widget, cur->name, al, ac);
            button = XmCreateCascadeButton (widget, cur->name, al, ac);
          else if (!cur->call_data)
            button = XmCreateLabel (widget, cur->name, al, ac);
+         else if (cur->button_type == BUTTON_TYPE_TOGGLE
+                  || cur->button_type == BUTTON_TYPE_RADIO)
+           {
+             XtSetArg (al[ac], XmNset, cur->selected); ++ac;
+             XtSetArg (al[ac], XmNvisibleWhenOff, True); ++ac;
+             XtSetArg (al[ac], XmNindicatorType,
+                       (cur->button_type == BUTTON_TYPE_TOGGLE
+                        ? XmN_OF_MANY : XmONE_OF_MANY));
+             ++ac;
+             button = XmCreateToggleButton (widget, cur->name, al, ac);
+             XtAddCallback (button, XmNarmCallback, xm_arm_callback, cur);
+             XtAddCallback (button, XmNdisarmCallback, xm_arm_callback, cur);
+           }
          else
          else
-           button = XmCreatePushButtonGadget (widget, cur->name, al, ac);
+           {
+             button = XmCreatePushButton (widget, cur->name, al, ac);
+             XtAddCallback (button, XmNarmCallback, xm_arm_callback, cur);
+             XtAddCallback (button, XmNdisarmCallback, xm_arm_callback, cur);
+           }
 
          xm_update_label (instance, button, cur);
 
 
          xm_update_label (instance, button, cur);
 
-         /* don't add a callback to a simple label */
-         if (cur->call_data)
+         /* Add a callback that is called when the button is
+            selected.  Toggle buttons don't support
+            XmNactivateCallback, we use XmNvalueChangedCallback in
+            that case.  Don't add a callback to a simple label.  */
+         if (cur->button_type)
+           xm_update_toggle (instance, button, cur);
+         else if (cur->call_data)
            XtAddCallback (button, XmNactivateCallback, xm_generic_callback,
                           (XtPointer)instance);
        }
       else
        {
            XtAddCallback (button, XmNactivateCallback, xm_generic_callback,
                           (XtPointer)instance);
        }
       else
        {
-         menu = XmCreatePulldownMenu (widget, "pulldown", NULL, 0);
-         make_menu_in_widget (instance, menu, cur->contents);
-         XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
+         menu = XmCreatePulldownMenu (widget, cur->name, NULL, 0);
+
+         make_menu_in_widget (instance, menu, cur->contents, 0);
+          XtSetArg (al[ac], XmNsubMenuId, menu); ac++;
          button = XmCreateCascadeButton (widget, cur->name, al, ac);
 
          xm_update_label (instance, button, cur);
 
          XtAddCallback (button, XmNcascadingCallback, xm_pull_down_callback,
                         (XtPointer)instance);
          button = XmCreateCascadeButton (widget, cur->name, al, ac);
 
          xm_update_label (instance, button, cur);
 
          XtAddCallback (button, XmNcascadingCallback, xm_pull_down_callback,
                         (XtPointer)instance);
+          XtOverrideTranslations (button, override);
+
        }
 
        }
 
-      children [child_index] = button;
+      children[child_index] = button;
     }
 
     }
 
-  XtManageChildren (children, num_children);
-
-  /* Last entry is the help button.  Has to be done after managing
-   * the buttons otherwise the menubar is only 4 pixels high... */
+  /* Last entry is the help button.  The original comment read "Has to
+     be done after managing the buttons otherwise the menubar is only
+     4 pixels high."  This is no longer true, and to make
+     XmNmenuHelpWidget work, we need to set it before managing the
+     children.. --gerd.  */
   if (button)
   if (button)
-    {
-      ac = 0;
-      XtSetArg (al [ac], XmNmenuHelpWidget, button); ac++;
-      XtSetValues (widget, al, ac);
-    }
+    XtVaSetValues (widget, XmNmenuHelpWidget, button, NULL);
+
+  if (num_children)
+    XtManageChildren (children, num_children);
 
   XtFree ((char *) children);
 
   XtFree ((char *) children);
+  if (old_children)
+    XtFree ((char *) old_children);
 }
 
 static void
 }
 
 static void
-update_one_menu_entry (widget_instance* instance, Widget widget,
-                      widget_value* val, Boolean deep_p)
+update_one_menu_entry (instance, widget, val, deep_p)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
+     Boolean deep_p;
 {
   Arg al [256];
   int ac;
   Widget menu;
   widget_value* contents;
 
 {
   Arg al [256];
   int ac;
   Widget menu;
   widget_value* contents;
 
-  if (val->change == NO_CHANGE)
+  if (val->this_one_change == NO_CHANGE)
     return;
 
   /* update the sensitivity and userdata */
   /* Common to all widget types */
     return;
 
   /* update the sensitivity and userdata */
   /* Common to all widget types */
-  XtVaSetValues (widget,
-                XmNsensitive, val->enabled,
-                XmNuserData, val->call_data,
-                0);
+  XtSetSensitive (widget, val->enabled);
+  XtVaSetValues (widget, XmNuserData, val->call_data, NULL);
 
   /* update the menu button as a label. */
 
   /* update the menu button as a label. */
-  if (val->change >= VISIBLE_CHANGE)
-    xm_update_label (instance, widget, val);
+  if (val->this_one_change >= VISIBLE_CHANGE)
+    {
+      xm_update_label (instance, widget, val);
+      if (val->button_type)
+       xm_update_toggle (instance, widget, val);
+    }
 
   /* update the pulldown/pullaside as needed */
   ac = 0;
   menu = NULL;
   XtSetArg (al [ac], XmNsubMenuId, &menu); ac++;
   XtGetValues (widget, al, ac);
 
   /* update the pulldown/pullaside as needed */
   ac = 0;
   menu = NULL;
   XtSetArg (al [ac], XmNsubMenuId, &menu); ac++;
   XtGetValues (widget, al, ac);
-  
+
   contents = val->contents;
 
   if (!menu)
     {
       if (contents)
        {
   contents = val->contents;
 
   if (!menu)
     {
       if (contents)
        {
-         menu = XmCreatePulldownMenu (widget, "pulldown", NULL, 0);
-         make_menu_in_widget (instance, menu, contents);
-         ac = 0;
-         XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
-         XtSetValues (widget, al, ac);
+         unsigned int old_num_children, i;
+         Widget parent;
+         Widget *widget_list;
+
+         parent = XtParent (widget);
+         widget_list = XtCompositeChildren (parent, &old_num_children);
+
+         /* Find the widget position within the parent's widget list.  */
+         for (i = 0; i < old_num_children; i++)
+           if (strcmp (XtName (widget_list[i]), XtName (widget)) == 0)
+             break;
+         if (i == old_num_children)
+           abort ();
+         if (XmIsCascadeButton (widget_list[i]))
+           {
+             menu = XmCreatePulldownMenu (parent, XtName(widget), NULL, 0);
+             make_menu_in_widget (instance, menu, contents, 0);
+             ac = 0;
+             XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
+             XtSetValues (widget, al, ac);
+           }
+         else
+           {
+             Widget button;
+
+             /* The current menuitem is a XmPushButtonGadget, it
+                needs to be replaced by a CascadeButtonGadget */
+             XtDestroyWidget (widget_list[i]);
+             menu = XmCreatePulldownMenu (parent, val->name, NULL, 0);
+             make_menu_in_widget (instance, menu, contents, 0);
+             ac = 0;
+             XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
+             /* Non-zero values don't work reliably in
+                conjunction with Emacs' event loop */
+             XtSetArg (al [ac], XmNmappingDelay, 0); ac++;
+#ifdef XmNpositionIndex /* This is undefined on SCO ODT 2.0.  */
+             /* Tell Motif to put it in the right place */
+             XtSetArg (al [ac], XmNpositionIndex , i); ac++;
+#endif
+             button = XmCreateCascadeButton (parent, val->name, al, ac);
+             xm_update_label (instance, button, val);
+
+             XtAddCallback (button, XmNcascadingCallback, xm_pull_down_callback,
+                            (XtPointer)instance);
+             XtManageChild (button);
+           }
+
+          if (widget_list)
+            XtFree ((char*) widget_list);
        }
     }
   else if (!contents)
        }
     }
   else if (!contents)
@@ -455,49 +762,85 @@ update_one_menu_entry (widget_instance* instance, Widget widget,
 }
 
 static void
 }
 
 static void
-xm_update_menu (widget_instance* instance, Widget widget, widget_value* val,
-               Boolean deep_p)
+xm_update_menu (instance, widget, val, deep_p)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
+     Boolean deep_p;
 {
 {
+  Widget* children;
+  unsigned int num_children;
+  int num_children_to_keep = 0;
+  int i;
+  widget_value* cur;
+
+  children = XtCompositeChildren (widget, &num_children);
+
   /* Widget is a RowColumn widget whose contents have to be updated
    * to reflect the list of items in val->contents */
   /* Widget is a RowColumn widget whose contents have to be updated
    * to reflect the list of items in val->contents */
-  if (val->contents->change == STRUCTURAL_CHANGE)
+
+  /* See how many buttons we can keep, and how many we
+     must completely replace.  */
+  if (val->contents == 0)
+    num_children_to_keep = 0;
+  else if (val->contents->change == STRUCTURAL_CHANGE)
     {
     {
-      destroy_all_children (widget);
-      make_menu_in_widget (instance, widget, val->contents);
+      if (children)
+       {
+         for (i = 0, cur = val->contents;
+               (i < num_children
+               && cur); /* how else to ditch unwanted children ?? - mgd */
+              i++, cur = cur->next)
+           {
+             if (cur->this_one_change == STRUCTURAL_CHANGE)
+               break;
+           }
+
+         num_children_to_keep = i;
+       }
     }
   else
     }
   else
-    {
-      /* Update all the buttons of the RowColumn in order. */
-      Widget* children;
-      unsigned int num_children;
-      int i;
-      widget_value* cur;
+    num_children_to_keep = num_children;
 
 
-      children = XtCompositeChildren (widget, &num_children);
-      if (children)
+  /* Update all the buttons of the RowColumn, in order,
+     except for those we are going to replace entirely.  */
+  if (children)
+    {
+      for (i = 0, cur = val->contents; i < num_children_to_keep; i++)
        {
        {
-         for (i = 0, cur = val->contents; i < num_children; i++)
+         if (!cur)
            {
            {
-             if (!cur)
-               abort ();
-             if (children [i]->core.being_destroyed
-                 || strcmp (XtName (children [i]), cur->name))
-               continue;
-             update_one_menu_entry (instance, children [i], cur, deep_p);
-             cur = cur->next;
+             num_children_to_keep = i;
+             break;
            }
            }
-         XtFree ((char *) children);
+         if (children [i]->core.being_destroyed
+             || strcmp (XtName (children [i]), cur->name))
+           continue;
+         update_one_menu_entry (instance, children [i], cur, deep_p);
+         cur = cur->next;
        }
        }
-      if (cur)
-       abort ();
     }
     }
+
+  /* Now replace from scratch all the buttons after the last
+     place that the top-level structure changed.  */
+  if (val->contents->change == STRUCTURAL_CHANGE)
+    {
+      destroy_all_children (widget, num_children_to_keep);
+      make_menu_in_widget (instance, widget, val->contents,
+                           num_children_to_keep);
+    }
+
+  XtFree ((char *) children);
 }
 
 \f
 /* update text widgets */
 
 static void
 }
 
 \f
 /* update text widgets */
 
 static void
-xm_update_text (widget_instance* instance, Widget widget, widget_value* val)
+xm_update_text (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
 {
   XmTextSetString (widget, val->value ? val->value : "");
   XtRemoveAllCallbacks (widget, XmNactivateCallback);
 {
   XmTextSetString (widget, val->value ? val->value : "");
   XtRemoveAllCallbacks (widget, XmNactivateCallback);
@@ -508,8 +851,10 @@ xm_update_text (widget_instance* instance, Widget widget, widget_value* val)
 }
 
 static void
 }
 
 static void
-xm_update_text_field (widget_instance* instance, Widget widget,
-                     widget_value* val)
+xm_update_text_field (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
 {
   XmTextFieldSetString (widget, val->value ? val->value : "");
   XtRemoveAllCallbacks (widget, XmNactivateCallback);
 {
   XmTextFieldSetString (widget, val->value ? val->value : "");
   XtRemoveAllCallbacks (widget, XmNactivateCallback);
@@ -523,24 +868,25 @@ xm_update_text_field (widget_instance* instance, Widget widget,
 /* update a motif widget */
 
 void
 /* update a motif widget */
 
 void
-xm_update_one_widget (widget_instance* instance, Widget widget,
-                     widget_value* val, Boolean deep_p)
+xm_update_one_widget (instance, widget, val, deep_p)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
+     Boolean deep_p;
 {
   WidgetClass class;
 {
   WidgetClass class;
-  
+
   /* Mark as not edited */
   val->edited = False;
 
   /* Common to all widget types */
   /* Mark as not edited */
   val->edited = False;
 
   /* Common to all widget types */
-  XtVaSetValues (widget,
-                XmNsensitive, val->enabled,
-                XmNuserData, val->call_data,
-                0);
-  
+  XtSetSensitive (widget, val->enabled);
+  XtVaSetValues (widget, XmNuserData, val->call_data, NULL);
+
   /* Common to all label like widgets */
   if (XtIsSubclass (widget, xmLabelWidgetClass))
     xm_update_label (instance, widget, val);
   /* Common to all label like widgets */
   if (XtIsSubclass (widget, xmLabelWidgetClass))
     xm_update_label (instance, widget, val);
-  
+
   class = XtClass (widget);
   /* Class specific things */
   if (class == xmPushButtonWidgetClass ||
   class = XtClass (widget);
   /* Class specific things */
   if (class == xmPushButtonWidgetClass ||
@@ -562,10 +908,10 @@ xm_update_one_widget (widget_instance* instance, Widget widget,
       Boolean radiobox = 0;
       int ac = 0;
       Arg al [1];
       Boolean radiobox = 0;
       int ac = 0;
       Arg al [1];
-      
+
       XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++;
       XtGetValues (widget, al, ac);
       XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++;
       XtGetValues (widget, al, ac);
-      
+
       if (radiobox)
        xm_update_radiobox (instance, widget, val);
       else
       if (radiobox)
        xm_update_radiobox (instance, widget, val);
       else
@@ -587,8 +933,10 @@ xm_update_one_widget (widget_instance* instance, Widget widget,
 
 \f/* getting the value back */
 void
 
 \f/* getting the value back */
 void
-xm_update_one_value (widget_instance* instance, Widget widget,
-                    widget_value* val)
+xm_update_one_value (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
 {
   WidgetClass class = XtClass (widget);
   widget_value *old_wv;
 {
   WidgetClass class = XtClass (widget);
   widget_value *old_wv;
@@ -600,10 +948,10 @@ xm_update_one_value (widget_instance* instance, Widget widget,
        val->call_data = old_wv->call_data;
        break;
       }
        val->call_data = old_wv->call_data;
        break;
       }
-  
+
   if (class == xmToggleButtonWidgetClass || class == xmToggleButtonGadgetClass)
     {
   if (class == xmToggleButtonWidgetClass || class == xmToggleButtonGadgetClass)
     {
-      XtVaGetValues (widget, XmNset, &val->selected, 0);
+      XtVaGetValues (widget, XmNset, &val->selected, NULL);
       val->edited = True;
     }
   else if (class == xmTextWidgetClass)
       val->edited = True;
     }
   else if (class == xmTextWidgetClass)
@@ -625,10 +973,10 @@ xm_update_one_value (widget_instance* instance, Widget widget,
       Boolean radiobox = 0;
       int ac = 0;
       Arg al [1];
       Boolean radiobox = 0;
       int ac = 0;
       Arg al [1];
-      
+
       XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++;
       XtGetValues (widget, al, ac);
       XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++;
       XtGetValues (widget, al, ac);
-      
+
       if (radiobox)
        {
          CompositeWidget radio = (CompositeWidget)widget;
       if (radiobox)
        {
          CompositeWidget radio = (CompositeWidget)widget;
@@ -637,8 +985,8 @@ xm_update_one_value (widget_instance* instance, Widget widget,
            {
              int set = False;
              Widget toggle = radio->composite.children [i];
            {
              int set = False;
              Widget toggle = radio->composite.children [i];
-             
-             XtVaGetValues (toggle, XmNset, &set, 0);
+
+             XtVaGetValues (toggle, XmNset, &set, NULL);
              if (set)
                {
                  if (val->value)
              if (set)
                {
                  if (val->value)
@@ -680,11 +1028,14 @@ xm_update_one_value (widget_instance* instance, Widget widget,
 /* This function is for activating a button from a program.  It's wrong because
    we pass a NULL argument in the call_data which is not Motif compatible.
    This is used from the XmNdefaultAction callback of the List widgets to
 /* This function is for activating a button from a program.  It's wrong because
    we pass a NULL argument in the call_data which is not Motif compatible.
    This is used from the XmNdefaultAction callback of the List widgets to
-   have a dble-click put down a dialog box like the button woudl do. 
+   have a double-click put down a dialog box like the button would do.
    I could not find a way to do that with accelerators.
  */
 static void
    I could not find a way to do that with accelerators.
  */
 static void
-activate_button (Widget widget, XtPointer closure, XtPointer call_data)
+activate_button (widget, closure, call_data)
+     Widget widget;
+     XtPointer closure;
+     XtPointer call_data;
 {
   Widget button = (Widget)closure;
   XtCallCallbacks (button, XmNactivateCallback, NULL);
 {
   Widget button = (Widget)closure;
   XtCallCallbacks (button, XmNactivateCallback, NULL);
@@ -692,12 +1043,47 @@ activate_button (Widget widget, XtPointer closure, XtPointer call_data)
 
 /* creation functions */
 
 
 /* creation functions */
 
+/* Called for key press in dialogs.  Used to pop down dialog on ESC.  */
+static void
+dialog_key_cb (widget, closure, event, continue_to_dispatch)
+     Widget widget;
+     XtPointer closure;
+     XEvent *event;
+     Boolean *continue_to_dispatch;
+{
+  KeySym sym = 0;
+  Modifiers modif_ret;
+  
+  XtTranslateKeycode (event->xkey.display, event->xkey.keycode, 0,
+                      &modif_ret, &sym);
+                      
+  if (sym == osfXK_Cancel)
+    {
+      Widget w = *((Widget *) closure);
+
+      while (w && ! XtIsShell (w))
+        w = XtParent (w);
+
+      if (XtIsShell (w)) XtPopdown (w);
+    }
+
+  *continue_to_dispatch = TRUE;
+}
+
 /* dialogs */
 static Widget
 /* dialogs */
 static Widget
-make_dialog (char* name, Widget parent, Boolean pop_up_p,
-            char* shell_title, char* icon_name, Boolean text_input_slot,
-            Boolean radio_box, Boolean list,
-            int left_buttons, int right_buttons)
+make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot,
+            radio_box, list, left_buttons, right_buttons)
+     char* name;
+     Widget parent;
+     Boolean pop_up_p;
+     char* shell_title;
+     char* icon_name;
+     Boolean text_input_slot;
+     Boolean radio_box;
+     Boolean list;
+     int left_buttons;
+     int right_buttons;
 {
   Widget result;
   Widget form;
 {
   Widget result;
   Widget form;
@@ -713,7 +1099,7 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
   Arg  al[64];                 /* Arg List */
   int  ac;                     /* Arg Count */
   int  i;
   Arg  al[64];                 /* Arg List */
   int  ac;                     /* Arg Count */
   int  i;
-  
+
   if (pop_up_p)
     {
       ac = 0;
   if (pop_up_p)
     {
       ac = 0;
@@ -738,9 +1124,9 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
 
   n_children = left_buttons + right_buttons + 1;
   ac = 0;
 
   n_children = left_buttons + right_buttons + 1;
   ac = 0;
-  XtSetArg(al[ac], XmNpacking, n_children == 3? 
+  XtSetArg(al[ac], XmNpacking, n_children == 3?
           XmPACK_COLUMN: XmPACK_TIGHT); ac++;
           XmPACK_COLUMN: XmPACK_TIGHT); ac++;
-  XtSetArg(al[ac], XmNorientation, n_children == 3? 
+  XtSetArg(al[ac], XmNorientation, n_children == 3?
           XmVERTICAL: XmHORIZONTAL); ac++;
   XtSetArg(al[ac], XmNnumColumns, left_buttons + right_buttons + 1); ac++;
   XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
           XmVERTICAL: XmHORIZONTAL); ac++;
   XtSetArg(al[ac], XmNnumColumns, left_buttons + right_buttons + 1); ac++;
   XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
@@ -757,7 +1143,7 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
   XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
   XtSetArg(al[ac], XmNrightOffset, 13); ac++;
   row = XmCreateRowColumn (form, "row", al, ac);
   XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
   XtSetArg(al[ac], XmNrightOffset, 13); ac++;
   row = XmCreateRowColumn (form, "row", al, ac);
-  
+
   n_children = 0;
   for (i = 0; i < left_buttons; i++)
     {
   n_children = 0;
   for (i = 0; i < left_buttons; i++)
     {
@@ -772,6 +1158,8 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
       XtSetArg(al[ac], XmNmarginWidth, 10); ac++;
       XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
       children [n_children] = XmCreatePushButton (row, button_name, al, ac);
       XtSetArg(al[ac], XmNmarginWidth, 10); ac++;
       XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
       children [n_children] = XmCreatePushButton (row, button_name, al, ac);
+      XtAddEventHandler (children [n_children],
+                         KeyPressMask, False, dialog_key_cb, result);
 
       if (i == 0)
        {
 
       if (i == 0)
        {
@@ -784,12 +1172,12 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
       n_children++;
     }
 
       n_children++;
     }
 
-  /* invisible seperator button */
+  /* invisible separator button */
   ac = 0;
   XtSetArg (al[ac], XmNmappedWhenManaged, FALSE); ac++;
   children [n_children] = XmCreateLabel (row, "separator_button", al, ac);
   n_children++;
   ac = 0;
   XtSetArg (al[ac], XmNmappedWhenManaged, FALSE); ac++;
   children [n_children] = XmCreateLabel (row, "separator_button", al, ac);
   n_children++;
-  
+
   for (i = 0; i < right_buttons; i++)
     {
       char button_name [16];
   for (i = 0; i < right_buttons; i++)
     {
       char button_name [16];
@@ -798,12 +1186,15 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
       XtSetArg(al[ac], XmNmarginWidth, 10); ac++;
       XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
       children [n_children] = XmCreatePushButton (row, button_name, al, ac);
       XtSetArg(al[ac], XmNmarginWidth, 10); ac++;
       XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
       children [n_children] = XmCreatePushButton (row, button_name, al, ac);
+      XtAddEventHandler (children [n_children],
+                         KeyPressMask, False, dialog_key_cb, result);
+
       if (! button) button = children [n_children];
       n_children++;
     }
       if (! button) button = children [n_children];
       n_children++;
     }
-  
+
   XtManageChildren (children, n_children);
   XtManageChildren (children, n_children);
-  
+
   ac = 0;
   XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
   XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
   ac = 0;
   XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
   XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
@@ -899,7 +1290,7 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
         list activate the default button */
       XtAddCallback (value, XmNdefaultActionCallback, activate_button, button);
     }
         list activate the default button */
       XtAddCallback (value, XmNdefaultActionCallback, activate_button, button);
     }
-  
+
   ac = 0;
   XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
   XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
   ac = 0;
   XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
   XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
@@ -914,7 +1305,7 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
   XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
   XtSetArg(al[ac], XmNrightOffset, 13); ac++;
   message = XmCreateLabel (form, "message", al, ac);
   XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
   XtSetArg(al[ac], XmNrightOffset, 13); ac++;
   message = XmCreateLabel (form, "message", al, ac);
-  
+
   if (list)
     XtManageChild (value);
 
   if (list)
     XtManageChild (value);
 
@@ -929,7 +1320,7 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
   children [i] = icon; i++;
   children [i] = icon_separator; i++;
   XtManageChildren (children, i);
   children [i] = icon; i++;
   children [i] = icon_separator; i++;
   XtManageChildren (children, i);
-  
+
   if (text_input_slot || list)
     {
       XtInstallAccelerators (value, button);
   if (text_input_slot || list)
     {
       XtInstallAccelerators (value, button);
@@ -940,12 +1331,13 @@ make_dialog (char* name, Widget parent, Boolean pop_up_p,
       XtInstallAccelerators (form, button);
       XtSetKeyboardFocus (result, button);
     }
       XtInstallAccelerators (form, button);
       XtSetKeyboardFocus (result, button);
     }
-  
+
   return result;
 }
 
 static destroyed_instance*
   return result;
 }
 
 static destroyed_instance*
-find_matching_instance (widget_instance* instance)
+find_matching_instance (instance)
+     widget_instance* instance;
 {
   destroyed_instance*  cur;
   destroyed_instance*  prev;
 {
   destroyed_instance*  cur;
   destroyed_instance*  prev;
@@ -982,15 +1374,18 @@ find_matching_instance (widget_instance* instance)
 }
 
 static void
 }
 
 static void
-mark_dead_instance_destroyed (Widget widget, XtPointer closure,
-                             XtPointer call_data)
+mark_dead_instance_destroyed (widget, closure, call_data)
+     Widget widget;
+     XtPointer closure;
+     XtPointer call_data;
 {
   destroyed_instance* instance = (destroyed_instance*)closure;
   instance->widget = NULL;
 }
 
 static void
 {
   destroyed_instance* instance = (destroyed_instance*)closure;
   instance->widget = NULL;
 }
 
 static void
-recenter_widget (Widget widget)
+recenter_widget (widget)
+     Widget widget;
 {
   Widget parent = XtParent (widget);
   Screen* screen = XtScreen (widget);
 {
   Widget parent = XtParent (widget);
   Screen* screen = XtScreen (widget);
@@ -1003,13 +1398,13 @@ recenter_widget (Widget widget)
   Position x;
   Position y;
 
   Position x;
   Position y;
 
-  XtVaGetValues (widget, XtNwidth, &child_width, XtNheight, &child_height, 0);
+  XtVaGetValues (widget, XtNwidth, &child_width, XtNheight, &child_height, NULL);
   XtVaGetValues (parent, XtNwidth, &parent_width, XtNheight, &parent_height,
   XtVaGetValues (parent, XtNwidth, &parent_width, XtNheight, &parent_height,
-                0);
+                NULL);
 
   x = (((Position)parent_width) - ((Position)child_width)) / 2;
   y = (((Position)parent_height) - ((Position)child_height)) / 2;
 
   x = (((Position)parent_width) - ((Position)child_width)) / 2;
   y = (((Position)parent_height) - ((Position)child_height)) / 2;
-  
+
   XtTranslateCoords (parent, x, y, &x, &y);
 
   if (x + child_width > screen_width)
   XtTranslateCoords (parent, x, y, &x, &y);
 
   if (x + child_width > screen_width)
@@ -1022,11 +1417,12 @@ recenter_widget (Widget widget)
   if (y < 0)
     y = 0;
 
   if (y < 0)
     y = 0;
 
-  XtVaSetValues (widget, XtNx, x, XtNy, y, 0);
+  XtVaSetValues (widget, XtNx, x, XtNy, y, NULL);
 }
 
 static Widget
 }
 
 static Widget
-recycle_instance (destroyed_instance* instance)
+recycle_instance (instance)
+     destroyed_instance* instance;
 {
   Widget widget = instance->widget;
 
 {
   Widget widget = instance->widget;
 
@@ -1048,11 +1444,11 @@ recycle_instance (destroyed_instance* instance)
        focus = XtNameToWidget (widget, "*button1");
       if (focus)
        XtSetKeyboardFocus (widget, focus);
        focus = XtNameToWidget (widget, "*button1");
       if (focus)
        XtSetKeyboardFocus (widget, focus);
-      
+
       /* shrink the separator label back to their original size */
       separator = XtNameToWidget (widget, "*separator_button");
       if (separator)
       /* shrink the separator label back to their original size */
       separator = XtNameToWidget (widget, "*separator_button");
       if (separator)
-       XtVaSetValues (separator, XtNwidth, 5, XtNheight, 5, 0);
+       XtVaSetValues (separator, XtNwidth, 5, XtNheight, 5, NULL);
 
       /* Center the dialog in its parent */
       recenter_widget (widget);
 
       /* Center the dialog in its parent */
       recenter_widget (widget);
@@ -1062,14 +1458,15 @@ recycle_instance (destroyed_instance* instance)
 }
 
 Widget
 }
 
 Widget
-xm_create_dialog (widget_instance* instance)
+xm_create_dialog (instance)
+     widget_instance* instance;
 {
   char*        name = instance->info->type;
   Widget       parent = instance->parent;
   Widget       widget;
   Boolean      pop_up_p = instance->pop_up_p;
   char*                shell_name = 0;
 {
   char*        name = instance->info->type;
   Widget       parent = instance->parent;
   Widget       widget;
   Boolean      pop_up_p = instance->pop_up_p;
   char*                shell_name = 0;
-  char*        icon_name;
+  char*        icon_name = 0;
   Boolean      text_input_slot = False;
   Boolean      radio_box = False;
   Boolean      list = False;
   Boolean      text_input_slot = False;
   Boolean      radio_box = False;
   Boolean      list = False;
@@ -1115,7 +1512,7 @@ xm_create_dialog (widget_instance* instance)
     shell_name = "Question";
     break;
   }
     shell_name = "Question";
     break;
   }
-  
+
   total_buttons = name [1] - '0';
 
   if (name [3] == 'T' || name [3] == 't')
   total_buttons = name [1] - '0';
 
   if (name [3] == 'T' || name [3] == 't')
@@ -1125,33 +1522,47 @@ xm_create_dialog (widget_instance* instance)
     }
   else if (name [3])
     right_buttons = name [4] - '0';
     }
   else if (name [3])
     right_buttons = name [4] - '0';
-  
+
   left_buttons = total_buttons - right_buttons;
   left_buttons = total_buttons - right_buttons;
-  
+
   widget = make_dialog (name, parent, pop_up_p,
                        shell_name, icon_name, text_input_slot, radio_box,
                        list, left_buttons, right_buttons);
 
   XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback,
                 (XtPointer) instance);
   widget = make_dialog (name, parent, pop_up_p,
                        shell_name, icon_name, text_input_slot, radio_box,
                        list, left_buttons, right_buttons);
 
   XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback,
                 (XtPointer) instance);
+
   return widget;
 }
 
   return widget;
 }
 
+/* Create a menu bar.  We turn off the f10 key
+   because we have not yet managed to make it work right in Motif.  */
+
 static Widget
 static Widget
-make_menubar (widget_instance* instance)
+make_menubar (instance)
+     widget_instance* instance;
 {
 {
-  return XmCreateMenuBar (instance->parent, instance->info->name, NULL, 0);
+  Arg al[3];
+  int ac;
+
+  ac = 0;
+  XtSetArg(al[ac], XmNmenuAccelerator, 0); ++ac;
+  return XmCreateMenuBar (instance->parent, instance->info->name, al, ac);
 }
 
 static void
 }
 
 static void
-remove_grabs (Widget shell, XtPointer closure, XtPointer call_data)
+remove_grabs (shell, closure, call_data)
+     Widget shell;
+     XtPointer closure;
+     XtPointer call_data;
 {
 {
-  XmRowColumnWidget menu = (XmRowColumnWidget) closure;
-  XmRemoveFromPostFromList (menu, XtParent (XtParent ((Widget) menu)));
+  Widget menu = (Widget) closure;
+  XmRemoveFromPostFromList (menu, XtParent (XtParent (menu)));
 }
 
 static Widget
 }
 
 static Widget
-make_popup_menu (widget_instance* instance)
+make_popup_menu (instance)
+     widget_instance* instance;
 {
   Widget parent = instance->parent;
   Window parent_window = parent->core.window;
 {
   Widget parent = instance->parent;
   Window parent_window = parent->core.window;
@@ -1165,8 +1576,10 @@ make_popup_menu (widget_instance* instance)
   parent->core.window = parent_window;
   return result;
 }
   parent->core.window = parent_window;
   return result;
 }
+
 static Widget
 static Widget
-make_main (widget_instance* instance)
+make_main (instance)
+     widget_instance* instance;
 {
   Widget parent = instance->parent;
   Widget result;
 {
   Widget parent = instance->parent;
   Widget result;
@@ -1283,7 +1696,7 @@ make_project_display_dialog (widget_instance* instance)
 #endif /* ENERGIZE */
 
 widget_creation_entry
 #endif /* ENERGIZE */
 
 widget_creation_entry
-xm_creation_table [] = 
+xm_creation_table [] =
 {
   {"menubar",                  make_menubar},
   {"popup",                    make_popup_menu},
 {
   {"menubar",                  make_menubar},
   {"popup",                    make_popup_menu},
@@ -1305,7 +1718,8 @@ xm_creation_table [] =
 
 \f/* Destruction of instances */
 void
 
 \f/* Destruction of instances */
 void
-xm_destroy_instance (widget_instance* instance)
+xm_destroy_instance (instance)
+     widget_instance* instance;
 {
   Widget widget = instance->widget;
   /* recycle the dialog boxes */
 {
   Widget widget = instance->widget;
   /* recycle the dialog boxes */
@@ -1339,52 +1753,69 @@ xm_destroy_instance (widget_instance* instance)
 
 \f/* popup utility */
 void
 
 \f/* popup utility */
 void
-xm_popup_menu (Widget widget)
+xm_popup_menu (widget, event)
+     Widget widget;
+     XEvent *event;
 {
   XButtonPressedEvent dummy;
 {
   XButtonPressedEvent dummy;
-  XEvent* event;
-
-  dummy.type = ButtonPress;
-  dummy.serial = 0;
-  dummy.send_event = 0;
-  dummy.display = XtDisplay (widget);
-  dummy.window = XtWindow (XtParent (widget));
-  dummy.time = 0;
-  dummy.button = 0;
-  XQueryPointer (dummy.display, dummy.window, &dummy.root,
-                &dummy.subwindow, &dummy.x_root, &dummy.y_root,
-                &dummy.x, &dummy.y, &dummy.state);
-  event = (XEvent *) &dummy;
+
+  if (event == 0)
+    {
+      dummy.type = ButtonPress;
+      dummy.serial = 0;
+      dummy.send_event = 0;
+      dummy.display = XtDisplay (widget);
+      dummy.window = XtWindow (XtParent (widget));
+      dummy.time = 0;
+      dummy.button = 0;
+      XQueryPointer (dummy.display, dummy.window, &dummy.root,
+                    &dummy.subwindow, &dummy.x_root, &dummy.y_root,
+                    &dummy.x, &dummy.y, &dummy.state);
+      event = (XEvent *) &dummy;
+    }
 
   if (event->type == ButtonPress || event->type == ButtonRelease)
     {
 
   if (event->type == ButtonPress || event->type == ButtonRelease)
     {
-      /* This is so totally ridiculous: there's NO WAY to tell Motif
-        that *any* button can select a menu item.  Only one button
-        can have that honor.
-       */
-      char *trans = 0;
-      if      (event->xbutton.state & Button5Mask) trans = "<Btn5Down>";
-      else if (event->xbutton.state & Button4Mask) trans = "<Btn4Down>";
-      else if (event->xbutton.state & Button3Mask) trans = "<Btn3Down>";
-      else if (event->xbutton.state & Button2Mask) trans = "<Btn2Down>";
-      else if (event->xbutton.state & Button1Mask) trans = "<Btn1Down>";
-      if (trans) XtVaSetValues (widget, XmNmenuPost, trans, 0);
+      /* Setting the menuPost resource only required by Motif 1.1 and
+        LessTif 0.84 and earlier.  With later versions of LessTif,
+        setting menuPost is unnecessary and may cause problems, so
+        don't do it.  */
+#if XmVersion < 1002 || (defined LESSTIF_VERSION && LESSTIF_VERSION < 84)
+       {
+         /* This is so totally ridiculous: there's NO WAY to tell Motif
+            that *any* button can select a menu item.  Only one button
+            can have that honor.  */
+
+         char *trans = 0;
+         if      (event->xbutton.state & Button5Mask) trans = "<Btn5Down>";
+         else if (event->xbutton.state & Button4Mask) trans = "<Btn4Down>";
+         else if (event->xbutton.state & Button3Mask) trans = "<Btn3Down>";
+         else if (event->xbutton.state & Button2Mask) trans = "<Btn2Down>";
+         else if (event->xbutton.state & Button1Mask) trans = "<Btn1Down>";
+         if (trans) XtVaSetValues (widget, XmNmenuPost, trans, NULL);
+       }
+#endif
+
       XmMenuPosition (widget, (XButtonPressedEvent *) event);
     }
       XmMenuPosition (widget, (XButtonPressedEvent *) event);
     }
+
   XtManageChild (widget);
 }
 
 static void
   XtManageChild (widget);
 }
 
 static void
-set_min_dialog_size (Widget w)
+set_min_dialog_size (w)
+     Widget w;
 {
   short width;
   short height;
 {
   short width;
   short height;
-  XtVaGetValues (w, XmNwidth, &width, XmNheight, &height, 0);
-  XtVaSetValues (w, XmNminWidth, width, XmNminHeight, height, 0);
+  XtVaGetValues (w, XmNwidth, &width, XmNheight, &height, NULL);
+  XtVaSetValues (w, XmNminWidth, width, XmNminHeight, height, NULL);
 }
 
 void
 }
 
 void
-xm_pop_instance (widget_instance* instance, Boolean up)
+xm_pop_instance (instance, up)
+     widget_instance* instance;
+     Boolean up;
 {
   Widget widget = instance->widget;
 
 {
   Widget widget = instance->widget;
 
@@ -1405,17 +1836,18 @@ xm_pop_instance (widget_instance* instance, Boolean up)
       if (up)
        XtManageChild (widget);
       else
       if (up)
        XtManageChild (widget);
       else
-       XtUnmanageChild (widget);       
+       XtUnmanageChild (widget);
     }
 }
 
 \f
     }
 }
 
 \f
-/* motif callback */ 
-
-enum do_call_type { pre_activate, selection, no_selection, post_activate };
+/* motif callback */
 
 static void
 
 static void
-do_call (Widget widget, XtPointer closure, enum do_call_type type)
+do_call (widget, closure, type)
+     Widget widget;
+     XtPointer closure;
+     enum do_call_type type;
 {
   Arg al [256];
   int ac;
 {
   Arg al [256];
   int ac;
@@ -1438,37 +1870,44 @@ do_call (Widget widget, XtPointer closure, enum do_call_type type)
   user_data = NULL;
   XtSetArg (al [ac], XmNuserData, &user_data); ac++;
   XtGetValues (widget, al, ac);
   user_data = NULL;
   XtSetArg (al [ac], XmNuserData, &user_data); ac++;
   XtGetValues (widget, al, ac);
+
   switch (type)
     {
     case pre_activate:
       if (instance->info->pre_activate_cb)
        instance->info->pre_activate_cb (widget, id, user_data);
       break;
   switch (type)
     {
     case pre_activate:
       if (instance->info->pre_activate_cb)
        instance->info->pre_activate_cb (widget, id, user_data);
       break;
+
     case selection:
       if (instance->info->selection_cb)
        instance->info->selection_cb (widget, id, user_data);
       break;
     case selection:
       if (instance->info->selection_cb)
        instance->info->selection_cb (widget, id, user_data);
       break;
+
     case no_selection:
       if (instance->info->selection_cb)
        instance->info->selection_cb (widget, id, (XtPointer) -1);
       break;
     case no_selection:
       if (instance->info->selection_cb)
        instance->info->selection_cb (widget, id, (XtPointer) -1);
       break;
+
     case post_activate:
       if (instance->info->post_activate_cb)
        instance->info->post_activate_cb (widget, id, user_data);
       break;
     case post_activate:
       if (instance->info->post_activate_cb)
        instance->info->post_activate_cb (widget, id, user_data);
       break;
+
     default:
       abort ();
     }
 }
 
 /* Like lw_internal_update_other_instances except that it does not do
     default:
       abort ();
     }
 }
 
 /* Like lw_internal_update_other_instances except that it does not do
-   anything if its shell parent is not managed.  This is to protect 
+   anything if its shell parent is not managed.  This is to protect
    lw_internal_update_other_instances to dereference freed memory
    if the widget was ``destroyed'' by caching it in the all_destroyed_instances
    list */
 static void
    lw_internal_update_other_instances to dereference freed memory
    if the widget was ``destroyed'' by caching it in the all_destroyed_instances
    list */
 static void
-xm_internal_update_other_instances (Widget widget, XtPointer closure,
-                                   XtPointer call_data)
+xm_internal_update_other_instances (widget, closure, call_data)
+     Widget widget;
+     XtPointer closure;
+     XtPointer call_data;
 {
   Widget parent;
   for (parent = widget; parent; parent = XtParent (parent))
 {
   Widget parent;
   for (parent = widget; parent; parent = XtParent (parent))
@@ -1480,43 +1919,76 @@ xm_internal_update_other_instances (Widget widget, XtPointer closure,
 }
 
 static void
 }
 
 static void
-xm_generic_callback (Widget widget, XtPointer closure, XtPointer call_data)
+xm_generic_callback (widget, closure, call_data)
+     Widget widget;
+     XtPointer closure;
+     XtPointer call_data;
 {
   lw_internal_update_other_instances (widget, closure, call_data);
   do_call (widget, closure, selection);
 }
 
 static void
 {
   lw_internal_update_other_instances (widget, closure, call_data);
   do_call (widget, closure, selection);
 }
 
 static void
-xm_nosel_callback (Widget widget, XtPointer closure, XtPointer call_data)
+xm_nosel_callback (widget, closure, call_data)
+     Widget widget;
+     XtPointer closure;
+     XtPointer call_data;
 {
 {
-  /* This callback is only called when a dialog box is dismissed with the wm's
-     destroy button (WM_DELETE_WINDOW.)  We want the dialog box to be destroyed
-     in that case, not just unmapped, so that it releases its keyboard grabs.
-     But there are problems with running our callbacks while the widget is in
-     the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
-     instead of XmDESTROY and then destroy it ourself after having run the
-     callback.
-   */
+  /* This callback is only called when a dialog box is dismissed with
+     the wm's destroy button (WM_DELETE_WINDOW.)  We want the dialog
+     box to be destroyed in that case, not just unmapped, so that it
+     releases its keyboard grabs.  But there are problems with running
+     our callbacks while the widget is in the process of being
+     destroyed, so we set XmNdeleteResponse to XmUNMAP instead of
+     XmDESTROY and then destroy it ourself after having run the
+     callback.  */
   do_call (widget, closure, no_selection);
   XtDestroyWidget (widget);
 }
 
 static void
   do_call (widget, closure, no_selection);
   XtDestroyWidget (widget);
 }
 
 static void
-xm_pull_down_callback (Widget widget, XtPointer closure, XtPointer call_data)
+xm_pull_down_callback (widget, closure, call_data)
+     Widget widget;
+     XtPointer closure;
+     XtPointer call_data;
 {
 {
-  do_call (widget, closure, pre_activate);
+  Widget parent = XtParent (widget);
+
+  if (XmIsRowColumn (parent))
+    {
+      unsigned char type = 0xff;
+      XtVaGetValues (parent, XmNrowColumnType, &type, NULL);
+      if (type == XmMENU_BAR)
+       do_call (widget, closure, pre_activate);
+    }
 }
 
 }
 
+
+/* XmNpopdownCallback for MenuShell widgets.  WIDGET is the MenuShell,
+   CLOSURE is a pointer to the widget_instance of the shell,
+
+   Note that this callback is called for each cascade button in a
+   menu, whether or not its submenu is visible.  */
+
 static void
 static void
-xm_pop_down_callback (Widget widget, XtPointer closure, XtPointer call_data)
+xm_pop_down_callback (widget, closure, call_data)
+     Widget widget;
+     XtPointer closure;
+     XtPointer call_data;
 {
 {
-  do_call (widget, closure, post_activate);
+  widget_instance *instance = (widget_instance *) closure;
+
+  if ((!instance->pop_up_p && XtParent (widget) == instance->widget)
+      || XtParent (widget) == instance->parent)
+    do_call (widget, closure, post_activate);
 }
 
 \f
 /* set the keyboard focus */
 void
 }
 
 \f
 /* set the keyboard focus */
 void
-xm_set_keyboard_focus (Widget parent, Widget w)
+xm_set_keyboard_focus (parent, w)
+     Widget parent;
+     Widget w;
 {
   XmProcessTraversal (w, 0);
   XtSetKeyboardFocus (parent, w);
 {
   XmProcessTraversal (w, 0);
   XtSetKeyboardFocus (parent, w);
@@ -1543,20 +2015,8 @@ xm_manage_resizing (w, flag)
      Widget w;
      Boolean flag;
 {
      Widget w;
      Boolean flag;
 {
-  if (flag)
-    {
-      /* Enable the edit widget for resizing. */
-      Arg al[1];
-      
-      XtSetArg (al[0], XtNallowShellResize, 0);
-      XtSetValues (w, al, 1);
-    }
-  else
-    {
-      /* Disable the edit widget from resizing. */
-      Arg al[1];
-      
-      XtSetArg (al[0], XtNallowShellResize, 0);
-      XtSetValues (w, al, 1);
-    }
+  XtVaSetValues (w, XtNallowShellResize, flag, NULL);
 }
 }
+
+/* arch-tag: 73976f64-73b2-4600-aa13-d9ede20ee965
+   (do not change this comment) */