Commit 3427a3db authored by Gerd Moellmann's avatar Gerd Moellmann
Browse files

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.
parent 4da4f201
...@@ -78,6 +78,10 @@ Boston, MA 02111-1307, USA. */ ...@@ -78,6 +78,10 @@ Boston, MA 02111-1307, USA. */
#endif /* not USE_X_TOOLKIT */ #endif /* not USE_X_TOOLKIT */
#endif /* HAVE_X_WINDOWS */ #endif /* HAVE_X_WINDOWS */
#ifdef USE_MOTIF
#include <Xm/Xm.h> /* for LESSTIF_VERSION */
#endif
#define min(x,y) (((x) < (y)) ? (x) : (y)) #define min(x,y) (((x) < (y)) ? (x) : (y))
#define max(x,y) (((x) > (y)) ? (x) : (y)) #define max(x,y) (((x) > (y)) ? (x) : (y))
...@@ -111,6 +115,16 @@ static Lisp_Object xdialog_show (); ...@@ -111,6 +115,16 @@ static Lisp_Object xdialog_show ();
void popup_get_selection (); void popup_get_selection ();
#endif #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 Lisp_Object xmenu_show ();
static void keymap_panes (); static void keymap_panes ();
static void single_keymap_panes (); static void single_keymap_panes ();
...@@ -149,7 +163,9 @@ static void list_of_items (); ...@@ -149,7 +163,9 @@ static void list_of_items ();
#define MENU_ITEMS_ITEM_VALUE 2 #define MENU_ITEMS_ITEM_VALUE 2
#define MENU_ITEMS_ITEM_EQUIV_KEY 3 #define MENU_ITEMS_ITEM_EQUIV_KEY 3
#define MENU_ITEMS_ITEM_DEFINITION 4 #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; static Lisp_Object menu_items;
...@@ -315,17 +331,17 @@ push_menu_pane (name, prefix_vec) ...@@ -315,17 +331,17 @@ push_menu_pane (name, prefix_vec)
XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec; XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec;
} }
/* Push one menu item into the current pane. /* Push one menu item into the current pane. NAME is the string to
NAME is the string to display. ENABLE if non-nil means display. ENABLE if non-nil means this item can be selected. KEY
this item can be selected. KEY is the key generated by is the key generated by choosing this item, or nil if this item
choosing this item, or nil if this item doesn't really have a definition. doesn't really have a definition. DEF is the definition of this
DEF is the definition of this item. item. EQUIV is the textual description of the keyboard equivalent
EQUIV is the textual description of the keyboard equivalent for for this item (or nil if none). TYPE is the type of this menu
this item (or nil if none). */ item, one of nil, `toggle' or `radio'. */
static void static void
push_menu_item (name, enable, key, def, equiv) push_menu_item (name, enable, key, def, equiv, type, selected)
Lisp_Object name, enable, key, def, equiv; Lisp_Object name, enable, key, def, equiv, type, selected;
{ {
if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated)
grow_menu_items (); grow_menu_items ();
...@@ -335,6 +351,8 @@ push_menu_item (name, enable, key, def, equiv) ...@@ -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++] = key;
XVECTOR (menu_items)->contents[menu_items_used++] = equiv; XVECTOR (menu_items)->contents[menu_items_used++] = equiv;
XVECTOR (menu_items)->contents[menu_items_used++] = def; 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, /* 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, ...@@ -561,7 +579,9 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
push_menu_item (item_string, enabled, key, push_menu_item (item_string, enabled, key,
XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], 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 #ifdef USE_X_TOOLKIT
/* Display a submenu using the toolkit. */ /* Display a submenu using the toolkit. */
...@@ -613,7 +633,7 @@ list_of_items (pane) ...@@ -613,7 +633,7 @@ list_of_items (pane)
{ {
item = Fcar (tail); item = Fcar (tail);
if (STRINGP (item)) 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)) else if (NILP (item))
push_left_right_boundary (); push_left_right_boundary ();
else else
...@@ -621,7 +641,7 @@ list_of_items (pane) ...@@ -621,7 +641,7 @@ list_of_items (pane)
CHECK_CONS (item, 0); CHECK_CONS (item, 0);
item1 = Fcar (item); item1 = Fcar (item);
CHECK_STRING (item1, 1); 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) ...@@ -1319,7 +1339,7 @@ single_submenu (item_key, item_name, maps)
as opposed to a submenu. */ as opposed to a submenu. */
top_level_items = 1; top_level_items = 1;
push_menu_pane (Qnil, Qnil); 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 else
single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); single_keymap_panes (mapvec[i], item_name, item_key, 0, 10);
...@@ -1334,6 +1354,7 @@ single_submenu (item_key, item_name, maps) ...@@ -1334,6 +1354,7 @@ single_submenu (item_key, item_name, maps)
wv->name = "menu"; wv->name = "menu";
wv->value = 0; wv->value = 0;
wv->enabled = 1; wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
first_wv = wv; first_wv = wv;
save_wv = 0; save_wv = 0;
prev_wv = 0; prev_wv = 0;
...@@ -1400,6 +1421,7 @@ single_submenu (item_key, item_name, maps) ...@@ -1400,6 +1421,7 @@ single_submenu (item_key, item_name, maps)
wv->name++; wv->name++;
wv->value = 0; wv->value = 0;
wv->enabled = 1; wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
} }
save_wv = wv; save_wv = wv;
prev_wv = 0; prev_wv = 0;
...@@ -1408,18 +1430,22 @@ single_submenu (item_key, item_name, maps) ...@@ -1408,18 +1430,22 @@ single_submenu (item_key, item_name, maps)
else else
{ {
/* Create a new item within current pane. */ /* 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]; item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
descrip descrip
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION]; 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 #ifndef HAVE_MULTILINGUAL_MENU
if (STRING_MULTIBYTE (item_name)) if (STRING_MULTIBYTE (item_name))
item_name = string_make_unibyte (item_name); item_name = string_make_unibyte (item_name);
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
descrip = string_make_unibyte (descrip); descrip = string_make_unibyte (descrip);
#endif #endif
wv = xmalloc_widget_value (); wv = xmalloc_widget_value ();
if (prev_wv) if (prev_wv)
prev_wv->next = wv; prev_wv->next = wv;
...@@ -1434,6 +1460,18 @@ single_submenu (item_key, item_name, maps) ...@@ -1434,6 +1460,18 @@ single_submenu (item_key, item_name, maps)
as long as pointers have enough bits to hold small integers. */ as long as pointers have enough bits to hold small integers. */
wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0); wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0);
wv->enabled = !NILP (enable); 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; prev_wv = wv;
i += MENU_ITEMS_ITEM_LENGTH; i += MENU_ITEMS_ITEM_LENGTH;
...@@ -1551,6 +1589,7 @@ set_frame_menubar (f, first_time, deep_p) ...@@ -1551,6 +1589,7 @@ set_frame_menubar (f, first_time, deep_p)
wv->name = "menubar"; wv->name = "menubar";
wv->value = 0; wv->value = 0;
wv->enabled = 1; wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
first_wv = wv; first_wv = wv;
if (deep_p) if (deep_p)
...@@ -1623,6 +1662,7 @@ set_frame_menubar (f, first_time, deep_p) ...@@ -1623,6 +1662,7 @@ set_frame_menubar (f, first_time, deep_p)
first_wv->contents = wv; first_wv->contents = wv;
/* Don't set wv->name here; GC during the loop might relocate it. */ /* Don't set wv->name here; GC during the loop might relocate it. */
wv->enabled = 1; wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
prev_wv = wv; prev_wv = wv;
} }
...@@ -1681,6 +1721,7 @@ set_frame_menubar (f, first_time, deep_p) ...@@ -1681,6 +1721,7 @@ set_frame_menubar (f, first_time, deep_p)
wv->name = (char *) XSTRING (string)->data; wv->name = (char *) XSTRING (string)->data;
wv->value = 0; wv->value = 0;
wv->enabled = 1; wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
/* This prevents lwlib from assuming this /* This prevents lwlib from assuming this
menu item is really supposed to be empty. */ menu item is really supposed to be empty. */
/* The EMACS_INT cast avoids a warning. /* The EMACS_INT cast avoids a warning.
...@@ -1879,6 +1920,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error) ...@@ -1879,6 +1920,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
wv->name = "menu"; wv->name = "menu";
wv->value = 0; wv->value = 0;
wv->enabled = 1; wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
first_wv = wv; first_wv = wv;
first_pane = 1; first_pane = 1;
...@@ -1941,6 +1983,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error) ...@@ -1941,6 +1983,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
wv->name++; wv->name++;
wv->value = 0; wv->value = 0;
wv->enabled = 1; wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
save_wv = wv; save_wv = wv;
prev_wv = 0; prev_wv = 0;
} }
...@@ -1955,19 +1998,22 @@ xmenu_show (f, x, y, for_click, keymaps, title, error) ...@@ -1955,19 +1998,22 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
else else
{ {
/* Create a new item within current pane. */ /* 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]; item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
descrip descrip
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION]; 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 #ifndef HAVE_MULTILINGUAL_MENU
if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
item_name = string_make_unibyte (item_name); item_name = string_make_unibyte (item_name);
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
item_name = string_make_unibyte (descrip); item_name = string_make_unibyte (descrip);
#endif #endif
wv = xmalloc_widget_value (); wv = xmalloc_widget_value ();
if (prev_wv) if (prev_wv)
prev_wv->next = wv; prev_wv->next = wv;
...@@ -1983,6 +2029,18 @@ xmenu_show (f, x, y, for_click, keymaps, title, error) ...@@ -1983,6 +2029,18 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
wv->call_data wv->call_data
= (!NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0); = (!NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0);
wv->enabled = !NILP (enable); 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; prev_wv = wv;
i += MENU_ITEMS_ITEM_LENGTH; i += MENU_ITEMS_ITEM_LENGTH;
...@@ -2008,6 +2066,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error) ...@@ -2008,6 +2066,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
#endif #endif
wv_title->name = (char *) XSTRING (title)->data; wv_title->name = (char *) XSTRING (title)->data;
wv_title->enabled = True; wv_title->enabled = True;
wv_title->button_type = BUTTON_TYPE_NONE;
wv_title->next = wv_sep1; wv_title->next = wv_sep1;
first_wv->contents = wv_title; first_wv->contents = wv_title;
} }
...@@ -2085,6 +2144,17 @@ xmenu_show (f, x, y, for_click, keymaps, title, error) ...@@ -2085,6 +2144,17 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
/* Process events that apply to the menu. */ /* Process events that apply to the menu. */
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id); 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 /* fp turned off the following statement and wrote a comment
that it is unnecessary--that the menu has already disappeared. that it is unnecessary--that the menu has already disappeared.
Nowadays the menu disappears ok, all right, but Nowadays the menu disappears ok, all right, but
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment