changeset 24993:825f11b1c34d

Ditto. (xmenu_show) [LESSTIF_VERSION]: Add workaround for remaining button grab under LessTif (HAVE_BOXES): Define if USE_X_TOOLKIT. (HAVE_BOXES): Define if using Lucid menus. (single_submenu): Set button_type of menu to BUTTON_TYPE_NONE. (single_submenu): Likewise for panes and menu items. (set_frame_menubar): Set button_type of menu bar to none. (xmenu_show): Likewise. (single_submenu): Set widget values selected slot. (xmenu_show): Likewise. (push_menu_item): Add parameters `type' and `selected'. Store it in menu_items. (MENU_ITEMS_ITEM_TYPE): New. (MENU_ITEMS_ITEM_SELECTED): New. (MENU_ITEMS_ITEM_LENGTH): Increase by two. (popup_get_selection): Use xmalloc/xfree instead of malloc/free.
author Gerd Moellmann <gerd@gnu.org>
date Wed, 21 Jul 1999 21:43:52 +0000
parents f1632be03391
children d549b7ac676d
files src/xmenu.c
diffstat 1 files changed, 95 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/xmenu.c	Wed Jul 21 21:43:52 1999 +0000
+++ b/src/xmenu.c	Wed Jul 21 21:43:52 1999 +0000
@@ -78,6 +78,10 @@
 #endif /* not USE_X_TOOLKIT */
 #endif /* HAVE_X_WINDOWS */
 
+#ifdef USE_MOTIF
+#include <Xm/Xm.h>		/* for LESSTIF_VERSION */
+#endif
+
 #define min(x,y) (((x) < (y)) ? (x) : (y))
 #define max(x,y) (((x) > (y)) ? (x) : (y))
 
@@ -111,6 +115,16 @@
 void popup_get_selection ();
 #endif
 
+#ifdef USE_X_TOOLKIT
+
+/* Define HAVE_BOXES if meus can handle radio and toggle buttons.  */
+
+#define HAVE_BOXES 1
+#endif
+
+static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
+				Lisp_Object, Lisp_Object, Lisp_Object,
+				Lisp_Object));
 static Lisp_Object xmenu_show ();
 static void keymap_panes ();
 static void single_keymap_panes ();
@@ -149,7 +163,9 @@
 #define MENU_ITEMS_ITEM_VALUE 2
 #define MENU_ITEMS_ITEM_EQUIV_KEY 3
 #define MENU_ITEMS_ITEM_DEFINITION 4
-#define MENU_ITEMS_ITEM_LENGTH 5
+#define MENU_ITEMS_ITEM_TYPE 5
+#define MENU_ITEMS_ITEM_SELECTED 6
+#define MENU_ITEMS_ITEM_LENGTH 7
 
 static Lisp_Object menu_items;
 
@@ -315,17 +331,17 @@
   XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec;
 }
 
-/* Push one menu item into the current pane.
-   NAME is the string to display.  ENABLE if non-nil means
-   this item can be selected.  KEY is the key generated by
-   choosing this item, or nil if this item doesn't really have a definition.
-   DEF is the definition of this item.
-   EQUIV is the textual description of the keyboard equivalent for
-   this item (or nil if none).  */
+/* Push one menu item into the current pane.  NAME is the string to
+   display.  ENABLE if non-nil means this item can be selected.  KEY
+   is the key generated by choosing this item, or nil if this item
+   doesn't really have a definition.  DEF is the definition of this
+   item.  EQUIV is the textual description of the keyboard equivalent
+   for this item (or nil if none).  TYPE is the type of this menu
+   item, one of nil, `toggle' or `radio'. */
 
 static void
-push_menu_item (name, enable, key, def, equiv)
-     Lisp_Object name, enable, key, def, equiv;
+push_menu_item (name, enable, key, def, equiv, type, selected)
+     Lisp_Object name, enable, key, def, equiv, type, selected;
 {
   if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated)
     grow_menu_items ();
@@ -335,6 +351,8 @@
   XVECTOR (menu_items)->contents[menu_items_used++] = key;
   XVECTOR (menu_items)->contents[menu_items_used++] = equiv;
   XVECTOR (menu_items)->contents[menu_items_used++] = def;
+  XVECTOR (menu_items)->contents[menu_items_used++] = type;
+  XVECTOR (menu_items)->contents[menu_items_used++] = selected;
 }
 
 /* Look through KEYMAPS, a vector of keymaps that is NMAPS long,
@@ -561,7 +579,9 @@
 
   push_menu_item (item_string, enabled, key,
 		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],
-		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]);
+		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ],
+		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE],
+		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]);
 
 #ifdef USE_X_TOOLKIT
   /* Display a submenu using the toolkit.  */
@@ -613,7 +633,7 @@
     {
       item = Fcar (tail);
       if (STRINGP (item))
-	push_menu_item (item, Qnil, Qnil, Qt, Qnil);
+	push_menu_item (item, Qnil, Qnil, Qt, Qnil, Qnil, Qnil);
       else if (NILP (item))
 	push_left_right_boundary ();
       else
@@ -621,7 +641,7 @@
 	  CHECK_CONS (item, 0);
 	  item1 = Fcar (item);
 	  CHECK_STRING (item1, 1);
-	  push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil);
+	  push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil, Qnil, Qnil);
 	}
     }
 }
@@ -1319,7 +1339,7 @@
 	     as opposed to a submenu.  */
 	  top_level_items = 1;
 	  push_menu_pane (Qnil, Qnil);
-	  push_menu_item (item_name, Qt, item_key, mapvec[i], Qnil);
+	  push_menu_item (item_name, Qt, item_key, mapvec[i], Qnil, Qnil, Qnil);
 	}
       else
 	single_keymap_panes (mapvec[i], item_name, item_key, 0, 10);
@@ -1334,6 +1354,7 @@
   wv->name = "menu";
   wv->value = 0;
   wv->enabled = 1;
+  wv->button_type = BUTTON_TYPE_NONE;
   first_wv = wv;
   save_wv = 0;
   prev_wv = 0;
@@ -1400,6 +1421,7 @@
 		wv->name++;
 	      wv->value = 0;
 	      wv->enabled = 1;
+	      wv->button_type = BUTTON_TYPE_NONE;
 	    }
 	  save_wv = wv;
 	  prev_wv = 0;
@@ -1408,18 +1430,22 @@
       else
 	{
 	  /* Create a new item within current pane.  */
-	  Lisp_Object item_name, enable, descrip, def;
+	  Lisp_Object item_name, enable, descrip, def, type, selected;
 	  item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
 	  enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
 	  descrip
 	    = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
 	  def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION];
+	  type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE];
+	  selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED];
+
 #ifndef HAVE_MULTILINGUAL_MENU
-	  if (STRING_MULTIBYTE (item_name))
-	    item_name = string_make_unibyte (item_name);
-	  if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
-	    descrip = string_make_unibyte (descrip);
+          if (STRING_MULTIBYTE (item_name))
+            item_name = string_make_unibyte (item_name);
+          if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
+            descrip = string_make_unibyte (descrip);
 #endif
+
 	  wv = xmalloc_widget_value ();
 	  if (prev_wv) 
 	    prev_wv->next = wv;
@@ -1434,6 +1460,18 @@
 	     as long as pointers have enough bits to hold small integers.  */
 	  wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0);
 	  wv->enabled = !NILP (enable);
+	  
+	  if (NILP (type))
+	    wv->button_type = BUTTON_TYPE_NONE;
+	  else if (EQ (type, QCradio))
+	    wv->button_type = BUTTON_TYPE_RADIO;
+	  else if (EQ (type, QCtoggle))
+	    wv->button_type = BUTTON_TYPE_TOGGLE;
+	  else
+	    abort ();
+
+	  wv->selected = !NILP (selected);
+		   
 	  prev_wv = wv;
 
 	  i += MENU_ITEMS_ITEM_LENGTH;
@@ -1551,6 +1589,7 @@
   wv->name = "menubar";
   wv->value = 0;
   wv->enabled = 1;
+  wv->button_type = BUTTON_TYPE_NONE;
   first_wv = wv;
 
   if (deep_p)
@@ -1623,6 +1662,7 @@
 	    first_wv->contents = wv;
 	  /* Don't set wv->name here; GC during the loop might relocate it.  */
 	  wv->enabled = 1;
+	  wv->button_type = BUTTON_TYPE_NONE;
 	  prev_wv = wv;
 	}
 
@@ -1681,6 +1721,7 @@
 	  wv->name = (char *) XSTRING (string)->data;
 	  wv->value = 0;
 	  wv->enabled = 1;
+	  wv->button_type = BUTTON_TYPE_NONE;
 	  /* This prevents lwlib from assuming this
 	     menu item is really supposed to be empty.  */
 	  /* The EMACS_INT cast avoids a warning.
@@ -1879,6 +1920,7 @@
   wv->name = "menu";
   wv->value = 0;
   wv->enabled = 1;
+  wv->button_type = BUTTON_TYPE_NONE;
   first_wv = wv;
   first_pane = 1;
  
@@ -1941,6 +1983,7 @@
 		wv->name++;
 	      wv->value = 0;
 	      wv->enabled = 1;
+	      wv->button_type = BUTTON_TYPE_NONE;
 	      save_wv = wv;
 	      prev_wv = 0;
 	    }
@@ -1955,19 +1998,22 @@
       else
 	{
 	  /* Create a new item within current pane.  */
-	  Lisp_Object item_name, enable, descrip, def;
+	  Lisp_Object item_name, enable, descrip, def, type, selected;
 	  item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
 	  enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
 	  descrip
 	    = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
 	  def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION];
+	  type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE];
+	  selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED];
+
 #ifndef HAVE_MULTILINGUAL_MENU
-	  if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
-	    item_name = string_make_unibyte (item_name);
-	  if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
-	    item_name = string_make_unibyte (descrip);
+          if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
+            item_name = string_make_unibyte (item_name);
+          if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
+            item_name = string_make_unibyte (descrip);
 #endif
-
+ 
 	  wv = xmalloc_widget_value ();
 	  if (prev_wv) 
 	    prev_wv->next = wv;
@@ -1983,6 +2029,18 @@
 	  wv->call_data
 	    = (!NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0);
 	  wv->enabled = !NILP (enable);
+
+	  if (NILP (type))
+	    wv->button_type = BUTTON_TYPE_NONE;
+	  else if (EQ (type, QCtoggle))
+	    wv->button_type = BUTTON_TYPE_TOGGLE;
+	  else if (EQ (type, QCradio))
+	    wv->button_type = BUTTON_TYPE_RADIO;
+	  else
+	    abort ();
+
+	  wv->selected = !NILP (selected);
+	  
 	  prev_wv = wv;
 
 	  i += MENU_ITEMS_ITEM_LENGTH;
@@ -2008,6 +2066,7 @@
 #endif
       wv_title->name = (char *) XSTRING (title)->data;
       wv_title->enabled = True;
+      wv_title->button_type = BUTTON_TYPE_NONE;
       wv_title->next = wv_sep1;
       first_wv->contents = wv_title;
     }
@@ -2085,6 +2144,17 @@
   /* Process events that apply to the menu.  */
   popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id);
 
+#ifdef LESSTIF_VERSION
+  /* Nov 1998: For an unknown reason a button grab remains active
+     after the popup menu has gone.  */
+  XUngrabButton (XtDisplay (f->output_data.x->widget),
+		 AnyButton, AnyModifier,
+		 XtWindow (f->output_data.x->widget));
+  XUngrabButton (XtDisplay (f->output_data.x->edit_widget),
+		 AnyButton, AnyModifier,
+		 XtWindow (f->output_data.x->edit_widget));
+#endif /* LESSTIF_VERSION */
+
   /* fp turned off the following statement and wrote a comment
      that it is unnecessary--that the menu has already disappeared.
      Nowadays the menu disappears ok, all right, but