Remove obsolete USE_OLIT code.
[bpt/emacs.git] / lwlib / lwlib.c
index 6569b38..5f68a36 100644 (file)
@@ -22,6 +22,12 @@ Boston, MA 02111-1307, USA.  */
 #undef __STRICT_BSD__ /* ick */
 #endif
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "../src/lisp.h"
+
 #include <sys/types.h>
 #include <stdio.h>
 #include <ctype.h>
@@ -29,12 +35,6 @@ Boston, MA 02111-1307, USA.  */
 #include "lwlib-utils.h"
 #include <X11/StringDefs.h>
 
-#ifdef __osf__
-#include <string.h>
-#include <stdlib.h>
-extern long *xmalloc();
-#endif
-
 #if defined (USE_LUCID)
 #include "lwlib-Xlw.h"
 #endif
@@ -45,19 +45,13 @@ extern long *xmalloc();
 #define USE_XAW
 #endif /* not USE_MOTIF && USE_LUCID */
 #endif
-#if defined (USE_OLIT)
-#include "lwlib-Xol.h"
-#endif
 #if defined (USE_XAW)
+#include <X11/Xaw/Paned.h>
 #include "lwlib-Xaw.h"
 #endif
 
-#if !defined (USE_LUCID) && !defined (USE_MOTIF) && !defined (USE_OLIT)
-ERROR!  At least one of USE_LUCID, USE_MOTIF or USE_OLIT must be defined.
-#endif
-
-#if defined (USE_MOTIF) && defined (USE_OLIT)
-ERROR! no more than one of USE_MOTIF and USE_OLIT may be defined.
+#if !defined (USE_LUCID) && !defined (USE_MOTIF)
+ #error  At least one of USE_LUCID or USE_MOTIF must be defined.
 #endif
 
 #ifndef max
@@ -73,14 +67,46 @@ char *lwlib_toolkit_type = "motif";
 #else
 char *lwlib_toolkit_type = "lucid";
 #endif
-\f/* Forward declarations */
-static void
-instantiate_widget_instance (/* widget_instance* instance */);
 
+static widget_value *merge_widget_value P_ ((widget_value *,
+                                            widget_value *,
+                                            int, int *));
+static void instantiate_widget_instance P_ ((widget_instance *));
+static int my_strcasecmp P_ ((char *, char *));
+static void safe_free_str P_ ((char *));
+static void free_widget_value_tree P_ ((widget_value *));
+static widget_value *copy_widget_value_tree P_ ((widget_value *,
+                                                change_type));
+static widget_info *allocate_widget_info P_ ((char *, char *, LWLIB_ID,
+                                             widget_value *,
+                                             lw_callback, lw_callback,
+                                             lw_callback, lw_callback));
+static void free_widget_info P_ ((widget_info *));
+static void mark_widget_destroyed P_ ((Widget, XtPointer, XtPointer));
+static widget_instance *allocate_widget_instance P_ ((widget_info *,
+                                                     Widget, Boolean));
+static void free_widget_instance P_ ((widget_instance *));
+static widget_info *get_widget_info P_ ((LWLIB_ID, Boolean));
+static widget_instance *get_widget_instance P_ ((Widget, Boolean));
+static widget_instance *find_instance P_ ((LWLIB_ID, Widget, Boolean));
+static Boolean safe_strcmp P_ ((char *, char *));
+static Widget name_to_widget P_ ((widget_instance *, char *));
+static void set_one_value P_ ((widget_instance *, widget_value *, Boolean));
+static void update_one_widget_instance P_ ((widget_instance *, Boolean));
+static void update_all_widget_values P_ ((widget_info *, Boolean));
+static void initialize_widget_instance P_ ((widget_instance *));
+static widget_creation_function find_in_table P_ ((char *, widget_creation_entry *));
+static Boolean dialog_spec_p P_ ((char *));
+static void destroy_one_instance P_ ((widget_instance *));
+static void lw_pop_all_widgets P_ ((LWLIB_ID, Boolean));
+static Boolean get_one_value P_ ((widget_instance *, widget_value *));
+static void show_one_widget_busy P_ ((Widget, Boolean));
+     
+void
 lwlib_memset (address, value, length)
      char *address;
      int value;
-     int length;
+     size_t length;
 {
   int i;
 
@@ -88,6 +114,7 @@ lwlib_memset (address, value, length)
     address[i] = value;
 }
 
+void
 lwlib_bcopy (from, to, length)
      char *from;
      char *to;
@@ -101,7 +128,7 @@ lwlib_bcopy (from, to, length)
 \f/* utility functions for widget_instance and widget_info */
 char *
 safe_strdup (s)
-     char *s;
+     const char *s;
 {
   char *result;
   if (! s) return 0;
@@ -158,7 +185,7 @@ malloc_widget_value ()
       wv = (widget_value *) malloc (sizeof (widget_value));
       malloc_cpt++;
     }
-  lwlib_memset (wv, 0, sizeof (widget_value));
+  lwlib_memset ((void*) wv, 0, sizeof (widget_value));
   return wv;
 }
 
@@ -234,10 +261,13 @@ copy_widget_value_tree (val, change)
   copy->name = safe_strdup (val->name);
   copy->value = safe_strdup (val->value);
   copy->key = safe_strdup (val->key);
+  copy->help = val->help;
   copy->enabled = val->enabled;
+  copy->button_type = val->button_type;
   copy->selected = val->selected;
   copy->edited = False;
   copy->change = change;
+  copy->this_one_change = change;
   copy->contents = copy_widget_value_tree (val->contents, change);
   copy->call_data = val->call_data;
   copy->next = copy_widget_value_tree (val->next, change);
@@ -247,7 +277,8 @@ copy_widget_value_tree (val, change)
 }
 
 static widget_info *
-allocate_widget_info (type, name, id, val, pre_activate_cb, selection_cb, post_activate_cb)
+allocate_widget_info (type, name, id, val, pre_activate_cb,
+                     selection_cb, post_activate_cb, highlight_cb)
      char* type;
      char* name;
      LWLIB_ID id;
@@ -255,6 +286,7 @@ allocate_widget_info (type, name, id, val, pre_activate_cb, selection_cb, post_a
      lw_callback pre_activate_cb;
      lw_callback selection_cb;
      lw_callback post_activate_cb;
+     lw_callback highlight_cb;
 {
   widget_info* info = (widget_info*)malloc (sizeof (widget_info));
   info->type = safe_strdup (type);
@@ -265,6 +297,7 @@ allocate_widget_info (type, name, id, val, pre_activate_cb, selection_cb, post_a
   info->pre_activate_cb = pre_activate_cb;
   info->selection_cb = selection_cb;
   info->post_activate_cb = post_activate_cb;
+  info->highlight_cb = highlight_cb;
   info->instances = NULL;
 
   info->next = all_widget_info;
@@ -297,14 +330,22 @@ mark_widget_destroyed (widget, closure, call_data)
     instance->widget = NULL;
 }
 
+/* The messy #ifdef PROTOTYPES here and elsewhere are prompted by a
+   flood of warnings about argument promotion from proprietary ISO C
+   compilers.  (etags still only makes one entry for each function.)  */
 static widget_instance *
+#ifdef PROTOTYPES
+allocate_widget_instance (widget_info* info, Widget parent, Boolean pop_up_p)
+#else
 allocate_widget_instance (info, parent, pop_up_p)
      widget_info* info;
      Widget parent;
      Boolean pop_up_p;
+#endif
 {
   widget_instance* instance =
     (widget_instance*)malloc (sizeof (widget_instance));
+  bzero (instance, sizeof *instance);
   instance->parent = parent;
   instance->pop_up_p = pop_up_p;
   instance->info = info;
@@ -327,9 +368,13 @@ free_widget_instance (instance)
 }
 
 static widget_info *
+#ifdef PROTOTYPES
+get_widget_info (LWLIB_ID id, Boolean remove_p)
+#else
 get_widget_info (id, remove_p)
      LWLIB_ID id;
      Boolean remove_p;
+#endif
 {
   widget_info* info;
   widget_info* prev;
@@ -360,9 +405,13 @@ lw_get_widget_info (id)
 }
 
 static widget_instance *
+#ifdef PROTOTYPES
+get_widget_instance (Widget widget, Boolean remove_p)
+#else
 get_widget_instance (widget, remove_p)
      Widget widget;
      Boolean remove_p;
+#endif
 {
   widget_info* info;
   widget_instance* instance;
@@ -385,11 +434,25 @@ get_widget_instance (widget, remove_p)
   return (widget_instance *) 0;
 }
 
+/* Value is a pointer to the widget_instance corresponding to
+   WIDGET, or null if WIDGET is not a lwlib widget.  */
+
+widget_instance *
+lw_get_widget_instance (widget)
+     Widget widget;
+{
+  return get_widget_instance (widget, False);
+}
+
 static widget_instance*
+#ifdef PROTOTYPES
+find_instance (LWLIB_ID id, Widget parent, Boolean pop_up_p)
+#else
 find_instance (id, parent, pop_up_p)
      LWLIB_ID id;
      Widget parent;
      Boolean pop_up_p;
+#endif
 {
   widget_info* info = get_widget_info (id, False);
   widget_instance* instance;
@@ -434,24 +497,29 @@ safe_strcmp (s1, s2)
 
 
 static widget_value *
-merge_widget_value (val1, val2, level)
+merge_widget_value (val1, val2, level, change_p)
      widget_value* val1;
      widget_value* val2;
      int level;
+     int *change_p;
 {
-  change_type change;
+  change_type change, this_one_change;
   widget_value* merged_next;
   widget_value* merged_contents;
 
   if (!val1)
     {
       if (val2)
-       return copy_widget_value_tree (val2, STRUCTURAL_CHANGE);
+       {
+         *change_p = 1;
+         return copy_widget_value_tree (val2, STRUCTURAL_CHANGE);
+       }
       else
        return NULL;
     }
   if (!val2)
     {
+      *change_p = 1;
       free_widget_value_tree (val1);
       return NULL;
     }
@@ -482,6 +550,13 @@ merge_widget_value (val1, val2, level)
       safe_free_str (val1->key);
       val1->key = safe_strdup (val2->key);
     }
+  if (! EQ (val1->help, val2->help))
+    {
+      EXPLAIN (val1->name, change, VISIBLE_CHANGE, "help change",
+              val1->help, val2->help);
+      change = max (change, VISIBLE_CHANGE);
+      val1->help = val2->help;
+    }
   if (val1->enabled != val2->enabled)
     {
       EXPLAIN (val1->name, change, VISIBLE_CHANGE, "enablement change",
@@ -489,6 +564,13 @@ merge_widget_value (val1, val2, level)
       change = max (change, VISIBLE_CHANGE);
       val1->enabled = val2->enabled;
     }
+  if (val1->button_type != val2->button_type)
+    {
+      EXPLAIN (val1->name, change, VISIBLE_CHANGE, "button type change",
+              val1->button_type, val2->button_type);
+      change = max (change, VISIBLE_CHANGE);
+      val1->button_type = val2->button_type;
+    }
   if (val1->selected != val2->selected)
     {
       EXPLAIN (val1->name, change, VISIBLE_CHANGE, "selection change",
@@ -507,7 +589,8 @@ merge_widget_value (val1, val2, level)
   if (level > 0)
     {
       merged_contents =
-       merge_widget_value (val1->contents, val2->contents, level - 1);
+       merge_widget_value (val1->contents, val2->contents, level - 1,
+                           change_p);
       
       if (val1->contents && !merged_contents)
        {
@@ -525,12 +608,19 @@ merge_widget_value (val1, val2, level)
          EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "(contents change)",
                   0, 0);
          change = max (change, INVISIBLE_CHANGE);
+#if 0 /* This was replaced by the August 9 1996 change in lwlib-Xm.c.  */
+#ifdef USE_MOTIF
+         change = max (merged_contents->change, change);
+#endif
+#endif
        }
       
       val1->contents = merged_contents;
     }
 
-  merged_next = merge_widget_value (val1->next, val2->next, level);
+  this_one_change = change;
+
+  merged_next = merge_widget_value (val1->next, val2->next, level, change_p);
 
   if (val1->next && !merged_next)
     {
@@ -548,10 +638,12 @@ merge_widget_value (val1, val2, level)
 
   val1->next = merged_next;
 
+  val1->this_one_change = this_one_change;
   val1->change = change;
   
   if (change > NO_CHANGE && val1->toolkit_data)
     {
+      *change_p = 1;
       if (val1->free_toolkit_data)
        XtFree (val1->toolkit_data);
       val1->toolkit_data = NULL;
@@ -589,10 +681,14 @@ name_to_widget (instance, name)
 }
 
 static void
+#ifdef PROTOTYPES
+set_one_value (widget_instance* instance, widget_value* val, Boolean deep_p)
+#else
 set_one_value (instance, val, deep_p)
      widget_instance* instance;
      widget_value* val;
      Boolean deep_p;
+#endif
 {
   Widget widget = name_to_widget (instance, val->name);
   
@@ -606,10 +702,6 @@ set_one_value (instance, val, deep_p)
       if (lw_motif_widget_p (instance->widget))
        xm_update_one_widget (instance, widget, val, deep_p);
 #endif
-#if defined (USE_OLIT)
-      if (lw_olit_widget_p (instance->widget))
-       xol_update_one_widget (instance, widget, val, deep_p);
-#endif
 #if defined (USE_XAW)
       if (lw_xaw_widget_p (instance->widget))
        xaw_update_one_widget (instance, widget, val, deep_p);
@@ -618,9 +710,13 @@ set_one_value (instance, val, deep_p)
 }
 
 static void
+#ifdef PROTOTYPES
+update_one_widget_instance (widget_instance* instance, Boolean deep_p)
+#else
 update_one_widget_instance (instance, deep_p)
      widget_instance* instance;
      Boolean deep_p;
+#endif
 {
   widget_value *val;
 
@@ -634,9 +730,13 @@ update_one_widget_instance (instance, deep_p)
 }
 
 static void
+#ifdef PROTOTYPES
+update_all_widget_values (widget_info* info, Boolean deep_p)
+#else
 update_all_widget_values (info, deep_p)
      widget_info* info;
      Boolean deep_p;
+#endif
 {
   widget_instance* instance;
   widget_value* val;
@@ -648,11 +748,15 @@ update_all_widget_values (info, deep_p)
     val->change = NO_CHANGE;
 }
 
-void
+int
+#ifdef PROTOTYPES
+lw_modify_all_widgets (LWLIB_ID id, widget_value* val, Boolean deep_p)
+#else
 lw_modify_all_widgets (id, val, deep_p)
      LWLIB_ID id;
      widget_value* val;
      Boolean deep_p;
+#endif
 {
   widget_info* info = get_widget_info (id, False);
   widget_value* new_val;
@@ -661,9 +765,10 @@ lw_modify_all_widgets (id, val, deep_p)
   widget_value* prev;
   widget_value* next;
   int          found;
+  int change_p = 0;
 
   if (!info)
-    return;
+    return 0;
 
   for (new_val = val; new_val; new_val = new_val->next)
     {
@@ -676,7 +781,8 @@ lw_modify_all_widgets (id, val, deep_p)
            found = True;
            next = cur->next;
            cur->next = NULL;
-           cur = merge_widget_value (cur, new_val, deep_p ? 1000 : 1);
+           cur = merge_widget_value (cur, new_val, deep_p ? 1000 : 1,
+                                     &change_p);
            if (prev)
              prev->next = cur ? cur : next;
            else
@@ -692,11 +798,13 @@ lw_modify_all_widgets (id, val, deep_p)
            prev->next = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
          else
            info->val = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
+         change_p = 1;
        }
       new_val->next = next_new_val;
     }
 
   update_all_widget_values (info, deep_p);
+  return change_p;
 }
 
 \f
@@ -778,10 +886,6 @@ instantiate_widget_instance (instance)
   if (!function)
     function = find_in_table (instance->info->type, xm_creation_table);
 #endif
-#if defined (USE_OLIT)
-  if (!function)
-    function = find_in_table (instance->info->type, xol_creation_table);
-#endif
 #if defined (USE_XAW)
   if (!function)
     function = find_in_table (instance->info->type, xaw_creation_table);
@@ -801,9 +905,6 @@ instantiate_widget_instance (instance)
 #if defined (USE_XAW)
          if (!function)
            function = xaw_create_dialog;
-#endif
-#if defined (USE_OLIT)
-         /* not yet */
 #endif
        }
     }
@@ -824,7 +925,8 @@ instantiate_widget_instance (instance)
 }
 
 void 
-lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb, post_activate_cb)
+lw_register_widget (type, name, id, val, pre_activate_cb,
+                   selection_cb, post_activate_cb, highlight_cb)
      char* type;
      char* name;
      LWLIB_ID id;
@@ -832,17 +934,22 @@ lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb, post_act
      lw_callback pre_activate_cb;
      lw_callback selection_cb;
      lw_callback post_activate_cb;
+     lw_callback highlight_cb;
 {
   if (!get_widget_info (id, False))
     allocate_widget_info (type, name, id, val, pre_activate_cb, selection_cb,
-                         post_activate_cb);
+                         post_activate_cb, highlight_cb);
 }
 
 Widget
+#ifdef PROTOTYPES
+lw_get_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
+#else
 lw_get_widget (id, parent, pop_up_p)
      LWLIB_ID id;
      Widget parent;
      Boolean pop_up_p;
+#endif
 {
   widget_instance* instance;
   
@@ -851,10 +958,14 @@ lw_get_widget (id, parent, pop_up_p)
 }
 
 Widget
+#ifdef PROTOTYPES
+lw_make_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
+#else
 lw_make_widget (id, parent, pop_up_p)
      LWLIB_ID id;
      Widget parent;
      Boolean pop_up_p;
+#endif
 {
   widget_instance* instance;
   widget_info* info;
@@ -874,7 +985,14 @@ lw_make_widget (id, parent, pop_up_p)
 }
 
 Widget
-lw_create_widget (type, name, id, val, parent, pop_up_p, pre_activate_cb, selection_cb, post_activate_cb)
+#ifdef PROTOTYPES
+lw_create_widget (char* type, char* name, LWLIB_ID id, widget_value* val,
+                 Widget parent, Boolean pop_up_p,
+                 lw_callback pre_activate_cb, lw_callback selection_cb,
+                 lw_callback post_activate_cb, lw_callback highlight_cb)
+#else
+lw_create_widget (type, name, id, val, parent, pop_up_p, pre_activate_cb,
+                 selection_cb, post_activate_cb, highlight_cb)
      char* type;
      char* name;
      LWLIB_ID id;
@@ -884,9 +1002,11 @@ lw_create_widget (type, name, id, val, parent, pop_up_p, pre_activate_cb, select
      lw_callback pre_activate_cb;
      lw_callback selection_cb;
      lw_callback post_activate_cb;
+     lw_callback highlight_cb;
+#endif
 {
   lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb,
-                     post_activate_cb);
+                     post_activate_cb, highlight_cb);
   return lw_make_widget (id, parent, pop_up_p);
 }
                  
@@ -923,11 +1043,6 @@ destroy_one_instance (instance)
        xm_destroy_instance (instance);
       else
 #endif
-#if defined (USE_OLIT)
-      if (lw_olit_widget_p (instance->widget))
-       xol_destroy_instance (instance);
-      else
-#endif
 #if defined (USE_XAW)
       if (lw_xaw_widget_p (instance->widget))
        xaw_destroy_instance (instance);
@@ -1038,9 +1153,13 @@ lw_raise_all_pop_up_widgets ()
 }
 
 static void
+#ifdef PROTOTYPES
+lw_pop_all_widgets (LWLIB_ID id, Boolean up)
+#else
 lw_pop_all_widgets (id, up)
      LWLIB_ID id;
      Boolean up;
+#endif
 {
   widget_info* info = get_widget_info (id, False);
   widget_instance* instance;
@@ -1063,13 +1182,6 @@ lw_pop_all_widgets (id, up)
              xm_pop_instance (instance, up);
            }
 #endif
-#if defined (USE_OLIT)
-         if (lw_olit_widget_p (instance->widget))
-           {
-             XtRealizeWidget (instance->widget);
-             xol_pop_instance (instance, up);
-           }
-#endif
 #if defined (USE_XAW)
          if (lw_xaw_widget_p (instance->widget))
            {
@@ -1108,10 +1220,6 @@ lw_popup_menu (widget, event)
   if (lw_motif_widget_p (widget))
     xm_popup_menu (widget, event);
 #endif
-#if defined (USE_OLIT)
-  if (lw_olit_widget_p (widget))
-    xol_popup_menu (widget, event);
-#endif
 #if defined (USE_XAW)
   if (lw_xaw_widget_p (widget))
     xaw_popup_menu (widget, event);
@@ -1136,10 +1244,6 @@ get_one_value (instance, val)
       if (lw_motif_widget_p (instance->widget))
        xm_update_one_value (instance, widget, val);
 #endif
-#if defined (USE_OLIT)
-      if (lw_olit_widget_p (instance->widget))
-       xol_update_one_value (instance, widget, val);
-#endif
 #if defined (USE_XAW)
       if (lw_xaw_widget_p (instance->widget))
        xaw_update_one_value (instance, widget, val);
@@ -1273,9 +1377,13 @@ lw_set_keyboard_focus (parent, w)
 
 \f/* Show busy */
 static void
+#ifdef PROTOTYPES
+show_one_widget_busy (Widget w, Boolean flag)
+#else
 show_one_widget_busy (w, flag)
      Widget w;
      Boolean flag;
+#endif
 {
   Pixel foreground = 0;
   Pixel background = 1;
@@ -1286,17 +1394,21 @@ show_one_widget_busy (w, flag)
   XtVaGetValues (widget_to_invert,
                 XtNforeground, &foreground,
                 XtNbackground, &background,
-                0);
+                NULL);
   XtVaSetValues (widget_to_invert,
                 XtNforeground, background,
                 XtNbackground, foreground,
-                0);
+                NULL);
 }
 
 void
+#ifdef PROTOTYPES
+lw_show_busy (Widget w, Boolean busy)
+#else
 lw_show_busy (w, busy)
      Widget w;
      Boolean busy;
+#endif
 {
   widget_instance* instance = get_widget_instance (w, False);
   widget_info* info;
@@ -1318,9 +1430,13 @@ lw_show_busy (w, busy)
 /* This hack exists because Lucid/Athena need to execute the strange
    function below to support geometry management. */
 void
+#ifdef PROTOTYPES
+lw_refigure_widget (Widget w, Boolean doit)
+#else
 lw_refigure_widget (w, doit)
      Widget w;
      Boolean doit;
+#endif
 {
 #if defined (USE_XAW)  
   XawPanedSetRefigureMode (w, doit);
@@ -1345,9 +1461,10 @@ lw_window_is_in_menubar (win, menubar_widget)
       && XtWindow (menubar_widget) == win;
 #endif
 #if defined (USE_MOTIF)
-      && XtWindowToWidget (XtDisplay (menubar_widget), win)
-      && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget), win))
-         == menubar_widget);
+      && ((XtWindow (menubar_widget) == win)
+         || (XtWindowToWidget (XtDisplay (menubar_widget), win)
+             && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget), win))
+                 == menubar_widget)));
 #endif
 }
 
@@ -1366,11 +1483,131 @@ lw_set_main_areas (parent, menubar, work_area)
 /* Manage resizing for Motif.  This disables resizing when the menubar
    is about to be modified. */
 void
+#ifdef PROTOTYPES
+lw_allow_resizing (Widget w, Boolean flag)
+#else
 lw_allow_resizing (w, flag)
      Widget w;
      Boolean flag;
+#endif
 {
 #if defined (USE_MOTIF)
   xm_manage_resizing (w, flag);
 #endif
 }
+
+
+/* Value is non-zero if LABEL is a menu separator.  If it is, *TYPE is
+   set to an appropriate enumerator of type enum menu_separator.
+   MOTIF_P non-zero means map separator types not supported by Motif
+   to similar ones that are supported.  */
+
+int
+lw_separator_p (label, type, motif_p)
+     char *label;
+     enum menu_separator *type;
+     int motif_p;
+{
+  int separator_p = 0;
+
+  if (strlen (label) >= 3
+      && bcmp (label, "--:", 3) == 0)
+    {
+      static struct separator_table
+      {
+       char *name;
+       enum menu_separator type;
+      }
+      separator_names[] =
+      {
+       {"space",                     SEPARATOR_NO_LINE},
+       {"noLine",                    SEPARATOR_NO_LINE},
+       {"singleLine",                SEPARATOR_SINGLE_LINE},
+       {"doubleLine",                SEPARATOR_DOUBLE_LINE},
+       {"singleDashedLine",          SEPARATOR_SINGLE_DASHED_LINE},
+       {"doubleDashedLine",          SEPARATOR_DOUBLE_DASHED_LINE},
+       {"shadowEtchedIn",            SEPARATOR_SHADOW_ETCHED_IN},
+       {"shadowEtchedOut",           SEPARATOR_SHADOW_ETCHED_OUT},
+       {"shadowEtchedInDash",        SEPARATOR_SHADOW_ETCHED_IN_DASH},
+       {"shadowEtchedOutDash",       SEPARATOR_SHADOW_ETCHED_OUT_DASH},
+       {"shadowDoubleEtchedIn",      SEPARATOR_SHADOW_DOUBLE_ETCHED_IN},
+       {"shadowDoubleEtchedOut",     SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT},
+       {"shadowDoubleEtchedInDash",  SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH},
+       {"shadowDoubleEtchedOutDash", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH},
+       {0,0}
+      };
+
+      int i;
+
+      label += 3;
+      for (i = 0; separator_names[i].name; ++i)
+       if (strcmp (label, separator_names[i].name) == 0)
+         {
+           separator_p = 1;
+           *type = separator_names[i].type;
+
+           /* If separator type is not supported under Motif,
+              use a similar one.  */
+           if (motif_p && *type >= SEPARATOR_SHADOW_DOUBLE_ETCHED_IN)
+             *type -= 4;
+           break;
+         }
+    }
+  else if (strlen (label) > 3
+          && bcmp (label, "--", 2) == 0
+          && label[2] != '-')
+    {
+      /* Alternative, more Emacs-style names.  */
+      static struct separator_table
+      {
+       char *name;
+       enum menu_separator type;
+      }
+      separator_names[] =
+      {
+       {"space",                        SEPARATOR_NO_LINE},
+       {"no-line",                      SEPARATOR_NO_LINE},
+       {"single-line",                  SEPARATOR_SINGLE_LINE},
+       {"double-line",                  SEPARATOR_DOUBLE_LINE},
+       {"single-dashed-line",           SEPARATOR_SINGLE_DASHED_LINE},
+       {"double-dashed-line",           SEPARATOR_DOUBLE_DASHED_LINE},
+       {"shadow-etched-in",             SEPARATOR_SHADOW_ETCHED_IN},
+       {"shadow-etched-out",            SEPARATOR_SHADOW_ETCHED_OUT},
+       {"shadow-etched-in-dash",        SEPARATOR_SHADOW_ETCHED_IN_DASH},
+       {"shadow-etched-out-dash",       SEPARATOR_SHADOW_ETCHED_OUT_DASH},
+       {"shadow-double-etched-in",      SEPARATOR_SHADOW_DOUBLE_ETCHED_IN},
+       {"shadow-double-etched-out",     SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT},
+       {"shadow-double-etched-in-dash", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH},
+       {"shadow-double-etched-out-dash",SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH},
+       {0,0}
+      };
+
+      int i;
+
+      label += 2;
+      for (i = 0; separator_names[i].name; ++i)
+       if (strcmp (label, separator_names[i].name) == 0)
+         {
+           separator_p = 1;
+           *type = separator_names[i].type;
+
+           /* If separator type is not supported under Motif,
+              use a similar one.  */
+           if (motif_p && *type >= SEPARATOR_SHADOW_DOUBLE_ETCHED_IN)
+             *type -= 4;
+           break;
+         }
+    }
+  else
+    {
+      /* Old-style separator, maybe.  It's a separator if it contains
+        only dashes.  */
+      while (*label == '-')
+       ++label;
+      separator_p = *label == 0;
+      *type = SEPARATOR_SHADOW_ETCHED_IN;
+    }
+
+  return separator_p;
+}
+