* Called when we get a key press event on a menu window. */ ARGSUSED */
| 223 | */ |
| 224 | /* ARGSUSED */ |
| 225 | void |
| 226 | menu_key(Widget w, XEvent *event, String *params, Cardinal *num_params) |
| 227 | { |
| 228 | struct menu_info_t *menu_info; |
| 229 | x11_menu_item *curr; |
| 230 | struct xwindow *wp; |
| 231 | Widget hbar, vbar; |
| 232 | char ch; |
| 233 | int count; |
| 234 | boolean selected_something, |
| 235 | perminv_scrolling = (event == &fake_perminv_event); |
| 236 | |
| 237 | nhUse(params); |
| 238 | nhUse(num_params); |
| 239 | |
| 240 | wp = find_widget(w); |
| 241 | menu_info = wp->menu_information; |
| 242 | |
| 243 | if (!perminv_scrolling) |
| 244 | ch = key_event_to_char((XKeyEvent *) event); |
| 245 | else |
| 246 | ch = (char) fake_perminv_event.type; |
| 247 | |
| 248 | if (ch == '\0') { /* don't accept nul char/modifier event */ |
| 249 | /* don't beep */ |
| 250 | return; |
| 251 | } |
| 252 | |
| 253 | /* don't exclude PICK_NONE menus; doing so disables scrolling via keys */ |
| 254 | if (menu_info->is_active || perminv_scrolling) { /* handle the input */ |
| 255 | /* first check for an explicit selector match, so that it won't be |
| 256 | overridden if it happens to duplicate a mapped menu command (':' |
| 257 | to look inside a container vs ':' to select via search string); |
| 258 | check for group accelerator match too */ |
| 259 | for (curr = menu_info->curr_menu.base; curr; curr = curr->next) |
| 260 | if (curr->identifier.a_void != 0 |
| 261 | && (curr->selector == ch || curr->gselector == ch)) |
| 262 | goto make_selection; |
| 263 | |
| 264 | ch = map_menu_cmd(ch); |
| 265 | if (ch == '\033') { /* quit */ |
| 266 | if (menu_info->counting || perminv_scrolling) { |
| 267 | /* when there's a count in progress, ESC discards it |
| 268 | rather than dismissing the whole menu */ |
| 269 | reset_menu_count(menu_info); |
| 270 | return; |
| 271 | } |
| 272 | select_none(wp); |
| 273 | } else if (ch == '\n' || ch == '\r') { |
| 274 | if (perminv_scrolling) { |
| 275 | menu_unscroll(wp); |
| 276 | return; /* skip menu_popdown() */ |
| 277 | } |
| 278 | ; /* accept */ |
| 279 | } else if (digit(ch)) { |
| 280 | /* special case: '0' is also the default ball class; |
| 281 | some menus use digits as potential group accelerators |
| 282 | but their entries don't rely on counts */ |
no test coverage detected