]> git.eshelyaron.com Git - emacs.git/commitdiff
Ditto.
authorGerd Moellmann <gerd@gnu.org>
Wed, 21 Jul 1999 21:43:52 +0000 (21:43 +0000)
committerGerd Moellmann <gerd@gnu.org>
Wed, 21 Jul 1999 21:43:52 +0000 (21:43 +0000)
(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.

src/xmenu.c

index 46fb604f5f30b32ac9ee4b90100aa61049166d85..173810bc035e990ebbe80432a3463b386a9e2512 100644 (file)
@@ -78,6 +78,10 @@ Boston, MA 02111-1307, USA.  */
 #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 @@ static Lisp_Object xdialog_show ();
 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 @@ static void list_of_items ();
 #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 @@ push_menu_pane (name, prefix_vec)
   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 @@ push_menu_item (name, enable, key, def, equiv)
   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;
 }
 \f
 /* Look through KEYMAPS, a vector of keymaps that is NMAPS long,
@@ -561,7 +579,9 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
 
   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 @@ list_of_items (pane)
     {
       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 @@ list_of_items (pane)
          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 @@ single_submenu (item_key, item_name, maps)
             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 @@ single_submenu (item_key, item_name, maps)
   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 @@ single_submenu (item_key, item_name, maps)
                wv->name++;
              wv->value = 0;
              wv->enabled = 1;
+             wv->button_type = BUTTON_TYPE_NONE;
            }
          save_wv = wv;
          prev_wv = 0;
@@ -1408,18 +1430,22 @@ single_submenu (item_key, item_name, maps)
       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 @@ single_submenu (item_key, item_name, maps)
             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 @@ set_frame_menubar (f, first_time, deep_p)
   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 @@ set_frame_menubar (f, first_time, deep_p)
            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 @@ set_frame_menubar (f, first_time, deep_p)
          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 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
   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 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
                wv->name++;
              wv->value = 0;
              wv->enabled = 1;
+             wv->button_type = BUTTON_TYPE_NONE;
              save_wv = wv;
              prev_wv = 0;
            }
@@ -1955,19 +1998,22 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
       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 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
          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 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
 #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 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
   /* 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