aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xmenu.c95
1 files changed, 77 insertions, 18 deletions
diff --git a/src/xmenu.c b/src/xmenu.c
index fd42d5f8a4a..780e08e1756 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -125,7 +125,7 @@ void popup_get_selection ();
125 125
126static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 126static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
127 Lisp_Object, Lisp_Object, Lisp_Object, 127 Lisp_Object, Lisp_Object, Lisp_Object,
128 Lisp_Object)); 128 Lisp_Object, Lisp_Object));
129static Lisp_Object xmenu_show (); 129static Lisp_Object xmenu_show ();
130static void keymap_panes (); 130static void keymap_panes ();
131static void single_keymap_panes (); 131static void single_keymap_panes ();
@@ -159,14 +159,18 @@ static void list_of_items ();
159#define MENU_ITEMS_PANE_PREFIX 2 159#define MENU_ITEMS_PANE_PREFIX 2
160#define MENU_ITEMS_PANE_LENGTH 3 160#define MENU_ITEMS_PANE_LENGTH 3
161 161
162#define MENU_ITEMS_ITEM_NAME 0 162enum menu_item_idx
163#define MENU_ITEMS_ITEM_ENABLE 1 163{
164#define MENU_ITEMS_ITEM_VALUE 2 164 MENU_ITEMS_ITEM_NAME = 0,
165#define MENU_ITEMS_ITEM_EQUIV_KEY 3 165 MENU_ITEMS_ITEM_ENABLE,
166#define MENU_ITEMS_ITEM_DEFINITION 4 166 MENU_ITEMS_ITEM_VALUE,
167#define MENU_ITEMS_ITEM_TYPE 5 167 MENU_ITEMS_ITEM_EQUIV_KEY,
168#define MENU_ITEMS_ITEM_SELECTED 6 168 MENU_ITEMS_ITEM_DEFINITION,
169#define MENU_ITEMS_ITEM_LENGTH 7 169 MENU_ITEMS_ITEM_TYPE,
170 MENU_ITEMS_ITEM_SELECTED,
171 MENU_ITEMS_ITEM_HELP,
172 MENU_ITEMS_ITEM_LENGTH
173};
170 174
171static Lisp_Object menu_items; 175static Lisp_Object menu_items;
172 176
@@ -341,8 +345,8 @@ push_menu_pane (name, prefix_vec)
341 item, one of nil, `toggle' or `radio'. */ 345 item, one of nil, `toggle' or `radio'. */
342 346
343static void 347static void
344push_menu_item (name, enable, key, def, equiv, type, selected) 348push_menu_item (name, enable, key, def, equiv, type, selected, help)
345 Lisp_Object name, enable, key, def, equiv, type, selected; 349 Lisp_Object name, enable, key, def, equiv, type, selected, help;
346{ 350{
347 if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) 351 if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated)
348 grow_menu_items (); 352 grow_menu_items ();
@@ -354,6 +358,7 @@ push_menu_item (name, enable, key, def, equiv, type, selected)
354 XVECTOR (menu_items)->contents[menu_items_used++] = def; 358 XVECTOR (menu_items)->contents[menu_items_used++] = def;
355 XVECTOR (menu_items)->contents[menu_items_used++] = type; 359 XVECTOR (menu_items)->contents[menu_items_used++] = type;
356 XVECTOR (menu_items)->contents[menu_items_used++] = selected; 360 XVECTOR (menu_items)->contents[menu_items_used++] = selected;
361 XVECTOR (menu_items)->contents[menu_items_used++] = help;
357} 362}
358 363
359/* Look through KEYMAPS, a vector of keymaps that is NMAPS long, 364/* Look through KEYMAPS, a vector of keymaps that is NMAPS long,
@@ -582,7 +587,8 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
582 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], 587 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],
583 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], 588 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ],
584 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], 589 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE],
585 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]); 590 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
591 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
586 592
587#ifdef USE_X_TOOLKIT 593#ifdef USE_X_TOOLKIT
588 /* Display a submenu using the toolkit. */ 594 /* Display a submenu using the toolkit. */
@@ -634,7 +640,7 @@ list_of_items (pane)
634 { 640 {
635 item = Fcar (tail); 641 item = Fcar (tail);
636 if (STRINGP (item)) 642 if (STRINGP (item))
637 push_menu_item (item, Qnil, Qnil, Qt, Qnil, Qnil, Qnil); 643 push_menu_item (item, Qnil, Qnil, Qt, Qnil, Qnil, Qnil, Qnil);
638 else if (NILP (item)) 644 else if (NILP (item))
639 push_left_right_boundary (); 645 push_left_right_boundary ();
640 else 646 else
@@ -642,7 +648,7 @@ list_of_items (pane)
642 CHECK_CONS (item, 0); 648 CHECK_CONS (item, 0);
643 item1 = Fcar (item); 649 item1 = Fcar (item);
644 CHECK_STRING (item1, 1); 650 CHECK_STRING (item1, 1);
645 push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil, Qnil, Qnil); 651 push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil, Qnil, Qnil, Qnil);
646 } 652 }
647 } 653 }
648} 654}
@@ -1156,6 +1162,51 @@ popup_activate_callback (widget, id, client_data)
1156 popup_activated_flag = 1; 1162 popup_activated_flag = 1;
1157} 1163}
1158 1164
1165/* Lwlib callback called when menu items are highlighted/unhighlighted
1166 while moving the mouse over them. WIDGET is the menu bar or menu
1167 popup widget. ID is its LWLIB_ID. CALL_DATA contains a pointer to
1168 the widget_value structure for the menu item, or null in case of
1169 unhighlighting. */
1170
1171void
1172menu_highlight_callback (widget, id, call_data)
1173 Widget widget;
1174 LWLIB_ID id;
1175 void *call_data;
1176{
1177 widget_value *wv = (widget_value *) call_data;
1178 struct frame *f;
1179 Lisp_Object frame, help;
1180 struct input_event buf;
1181
1182 /* Determine the frame for the help event. */
1183 f = menubar_id_to_frame (id);
1184 if (f)
1185 XSETFRAME (frame, f);
1186 else
1187 {
1188 /* WIDGET is the popup menu. It's parent is the frame's
1189 widget. See which frame that is. */
1190 Widget frame_widget = XtParent (widget);
1191 Lisp_Object tail;
1192
1193 for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
1194 {
1195 frame = XCAR (tail);
1196 if (GC_FRAMEP (frame)
1197 && (f = XFRAME (frame),
1198 FRAME_X_P (f) && f->output_data.x->widget == frame_widget))
1199 break;
1200 }
1201 }
1202
1203 /* Store the help event. */
1204 help = wv && wv->help ? build_string (wv->help) : Qnil;
1205 buf.kind = HELP_EVENT;
1206 buf.frame_or_window = Fcons (frame, help);
1207 kbd_buffer_store_event (&buf);
1208}
1209
1159/* This callback is called from the menu bar pulldown menu 1210/* This callback is called from the menu bar pulldown menu
1160 when the user makes a selection. 1211 when the user makes a selection.
1161 Figure out what the user chose 1212 Figure out what the user chose
@@ -1337,7 +1388,8 @@ single_submenu (item_key, item_name, maps)
1337 as opposed to a submenu. */ 1388 as opposed to a submenu. */
1338 top_level_items = 1; 1389 top_level_items = 1;
1339 push_menu_pane (Qnil, Qnil); 1390 push_menu_pane (Qnil, Qnil);
1340 push_menu_item (item_name, Qt, item_key, mapvec[i], Qnil, Qnil, Qnil); 1391 push_menu_item (item_name, Qt, item_key, mapvec[i],
1392 Qnil, Qnil, Qnil, Qnil);
1341 } 1393 }
1342 else 1394 else
1343 single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); 1395 single_keymap_panes (mapvec[i], item_name, item_key, 0, 10);
@@ -1429,6 +1481,8 @@ single_submenu (item_key, item_name, maps)
1429 { 1481 {
1430 /* Create a new item within current pane. */ 1482 /* Create a new item within current pane. */
1431 Lisp_Object item_name, enable, descrip, def, type, selected; 1483 Lisp_Object item_name, enable, descrip, def, type, selected;
1484 Lisp_Object help;
1485
1432 item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; 1486 item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME];
1433 enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; 1487 enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
1434 descrip 1488 descrip
@@ -1436,6 +1490,7 @@ single_submenu (item_key, item_name, maps)
1436 def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION]; 1490 def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION];
1437 type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE]; 1491 type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE];
1438 selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED]; 1492 selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED];
1493 help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];
1439 1494
1440#ifndef HAVE_MULTILINGUAL_MENU 1495#ifndef HAVE_MULTILINGUAL_MENU
1441 if (STRING_MULTIBYTE (item_name)) 1496 if (STRING_MULTIBYTE (item_name))
@@ -1469,6 +1524,8 @@ single_submenu (item_key, item_name, maps)
1469 abort (); 1524 abort ();
1470 1525
1471 wv->selected = !NILP (selected); 1526 wv->selected = !NILP (selected);
1527 if (STRINGP (help))
1528 wv->help = XSTRING (help)->data;
1472 1529
1473 prev_wv = wv; 1530 prev_wv = wv;
1474 1531
@@ -1760,7 +1817,8 @@ set_frame_menubar (f, first_time, deep_p)
1760 0, 1817 0,
1761 popup_activate_callback, 1818 popup_activate_callback,
1762 menubar_selection_callback, 1819 menubar_selection_callback,
1763 popup_deactivate_callback); 1820 popup_deactivate_callback,
1821 menu_highlight_callback);
1764 f->output_data.x->menubar_widget = menubar_widget; 1822 f->output_data.x->menubar_widget = menubar_widget;
1765 } 1823 }
1766 1824
@@ -2069,7 +2127,8 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
2069 menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv, 2127 menu = lw_create_widget ("popup", first_wv->name, menu_id, first_wv,
2070 f->output_data.x->widget, 1, 0, 2128 f->output_data.x->widget, 1, 0,
2071 popup_selection_callback, 2129 popup_selection_callback,
2072 popup_deactivate_callback); 2130 popup_deactivate_callback,
2131 menu_highlight_callback);
2073 2132
2074 /* Adjust coordinates to relative to the outer (window manager) window. */ 2133 /* Adjust coordinates to relative to the outer (window manager) window. */
2075 { 2134 {
@@ -2354,7 +2413,7 @@ xdialog_show (f, keymaps, title, error)
2354 dialog_id = widget_id_tick++; 2413 dialog_id = widget_id_tick++;
2355 menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv, 2414 menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
2356 f->output_data.x->widget, 1, 0, 2415 f->output_data.x->widget, 1, 0,
2357 dialog_selection_callback, 0); 2416 dialog_selection_callback, 0, 0);
2358 lw_modify_all_widgets (dialog_id, first_wv->contents, True); 2417 lw_modify_all_widgets (dialog_id, first_wv->contents, True);
2359 /* Free the widget_value objects we used to specify the contents. */ 2418 /* Free the widget_value objects we used to specify the contents. */
2360 free_menubar_widget_value_tree (first_wv); 2419 free_menubar_widget_value_tree (first_wv);