#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))
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 ();
#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;
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 ();
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,
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. */
{
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
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);
}
}
}
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);
wv->name = "menu";
wv->value = 0;
wv->enabled = 1;
+ wv->button_type = BUTTON_TYPE_NONE;
first_wv = wv;
save_wv = 0;
prev_wv = 0;
wv->name++;
wv->value = 0;
wv->enabled = 1;
+ wv->button_type = BUTTON_TYPE_NONE;
}
save_wv = wv;
prev_wv = 0;
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;
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;
wv->name = "menubar";
wv->value = 0;
wv->enabled = 1;
+ wv->button_type = BUTTON_TYPE_NONE;
first_wv = wv;
if (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;
}
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.
wv->name = "menu";
wv->value = 0;
wv->enabled = 1;
+ wv->button_type = BUTTON_TYPE_NONE;
first_wv = wv;
first_pane = 1;
wv->name++;
wv->value = 0;
wv->enabled = 1;
+ wv->button_type = BUTTON_TYPE_NONE;
save_wv = wv;
prev_wv = 0;
}
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;
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;
#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;
}
/* 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