From 0cad96042842d70bf050c1b67ea9ec3f5cd401b6 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 1 Apr 2019 08:58:49 -0700 Subject: [PATCH] X11 extended command selection The expansion of the extended commands list to include every command has made picking extended commands out of X11's menu become tedious. This uses the existing 'extmenu' option (previously tty-only) to control whether all the commands are present or just the traditional subset not bound to non-meta keystrokes ('adjust', 'chat', 'loot', &c). --- dat/opthelp | 5 +-- doc/Guidebook.mn | 10 ++++-- doc/Guidebook.tex | 9 ++++-- doc/fixes36.2 | 4 ++- win/X11/winmisc.c | 78 ++++++++++++++++++++++++++++++----------------- 5 files changed, 70 insertions(+), 36 deletions(-) diff --git a/dat/opthelp b/dat/opthelp index dd379be79..560acc463 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -1,6 +1,6 @@ Boolean options not under specific compile flags (with default values in []): (You can learn which options exist in your version by checking your current -option setting, which is reached via the 'O' cmd.) +option setting, which is reached via the 'O' command.) acoustics can your character hear anything [TRUE] autodescribe describe the terrain under cursor [FALSE] @@ -17,7 +17,8 @@ cmdassist give help for errors on direction & other commands [TRUE] confirm ask before hitting tame or peaceful monsters [TRUE] dark_room show floor not in sight in different color [TRUE] eight_bit_tty send 8-bit characters straight to terminal [FALSE] -extmenu use a menu for selecting extended commands (#) [FALSE] +extmenu tty: use a menu for selecting extended commands (#)[FALSE] + X11: menu has all commands (T) or traditional subset (F) fixinv try to retain the same letter for the same object [TRUE] force_invmenu commands asking for inventory item show a menu [FALSE] goldX when filtering objects by bless/curse state, [FALSE] diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 956ba2aa1..5992a75c0 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.302 $ $NHDT-Date: 1553858473 2019/03/29 11:21:13 $ +.\" $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.303 $ $NHDT-Date: 1554134322 2019/04/01 15:58:42 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines. @@ -2972,8 +2972,12 @@ Changes the extended commands interface to pop-up a menu of available commands. It is keystroke compatible with the traditional interface except that it does not require that you hit \fIEnter\fP. -It is implemented only by the tty port -(default off), when the game has been compiled to support tty graphics. +It is implemented for the tty interface (default off). +.lp "" +For the X11 interface, which always uses a menu for choosing an extended +command, it controls whether the menu shows all available commands (on) +or just the subset of commands which have traditionally been considered +extended ones (off). .lp female An obsolete synonym for \(lqgender:female\(rq. Cannot be set with the \(oqO\(cq command. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 151bed238..9230ac309 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3266,8 +3266,13 @@ Cannot be set with the `{\tt O}' command. \item[\ib{extmenu}] Changes the extended commands interface to pop-up a menu of available commands. It is keystroke compatible with the traditional interface except that it does -not require that you hit Enter. It is implemented only by the tty port -(default off), when the game has been compiled to support tty graphics. +not require that you hit Enter. +It is implemented for the tty interface (default off). +.lp "" +For the X11 interface, which always uses a menu for choosing an extended +command, it controls whether the menu shows all available commands (on) +or just the subset of commands which have traditionally been considered +extended ones (off). %.lp \item[\ib{female}] An obsolete synonym for ``{\tt gender:female}''. Cannot be set with the diff --git a/doc/fixes36.2 b/doc/fixes36.2 index c1490f5fc..fcf4c17e6 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.294 $ $NHDT-Date: 1554071680 2019/03/31 22:34:40 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.295 $ $NHDT-Date: 1554134321 2019/04/01 15:58:41 $ This fixes36.2 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.1 in April 2018. Please note, however, @@ -499,6 +499,8 @@ tty: when clipping was used to show a subset of the map on a small display, X11: its use of genl_status_update exposed a negative index use that could lead to a segfault X11: rollback disabling of keystroke input for PICK_NONE menus (for scrolling) +X11: make use of the 'extmenu' option: On to choose among all commands, Off + to choose among the traditional extended command subset curses: catch up with tty to not put dolook/whatis autodescribe feedback into ^P message recall (multi-digit count feedback was already handled) curses: if the interface code ran out of memory, it would crash rather than diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index 59883cdaf..13740a99b 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 winmisc.c $NHDT-Date: 1543830350 2018/12/03 09:45:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.42 $ */ +/* NetHack 3.6 winmisc.c $NHDT-Date: 1554134316 2019/04/01 15:58:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.43 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -41,6 +41,8 @@ static Widget extended_command_popup = 0; static Widget extended_command_form; static Widget *extended_commands = 0; +static const char **command_list; +static short *command_indx; static int extended_cmd_selected; /* index of the selected command; */ static int ps_selected; /* index of selected role */ #define PS_RANDOM (-50) @@ -50,6 +52,7 @@ static const char ps_randchars[] = "*@\n\rrR"; static const char ps_quitchars[] = "\033qQ"; #define EC_NCHARS 32 +static boolean ec_full_list = FALSE; static boolean ec_active = FALSE; static int ec_nchars = 0; static char ec_chars[EC_NCHARS]; @@ -111,13 +114,14 @@ XtPointer i2xtp(i) int i; { - return (XtPointer)(long)i; + return (XtPointer) (ptrdiff_t) i; } + int xtp2i(x) XtPointer x; { - return (long)x; + return (int) (ptrdiff_t) x; } /* Player Selection ------------------------------------------------------- */ @@ -1581,9 +1585,16 @@ X11_player_selection() } } +/* called by core to have the player pick an extended command */ int X11_get_ext_cmd() { + if (iflags.extmenu != ec_full_list) { + /* player has toggled the 'extmenu' option, toss the old widgets */ + if (extended_commands) + release_extended_cmds(); /* will set extended_commands to Null */ + ec_full_list = iflags.extmenu; + } if (!extended_commands) init_extended_commands_popup(); @@ -1597,15 +1608,19 @@ X11_get_ext_cmd() /* The callbacks will enable the event loop exit. */ (void) x_event(EXIT_ON_EXIT); - return extended_cmd_selected; + if (extended_cmd_selected < 0) + return -1; + return command_indx[extended_cmd_selected]; } void release_extended_cmds() { if (extended_commands) { - XtDestroyWidget(extended_command_popup); + XtDestroyWidget(extended_command_popup), extended_command_popup = 0; free((genericptr_t) extended_commands), extended_commands = 0; + free((genericptr_t) command_list), command_list = (const char **) 0; + free((genericptr_t) command_indx), command_indx = (short *) 0; } } @@ -1816,6 +1831,22 @@ int ec_indx; /* might be greater than extended_cmd_selected */ } } +/* decide whether extcmdlist[idx] should be part of extended commands menu */ +static boolean +ignore_extcmd(idx) +int idx; +{ + /* #shell or #suspect might not be available; + 'extmenu' option controls whether we show full list + or just the traditional extended commands */ + if ((extcmdlist[idx].flags & CMD_NOT_AVAILABLE) != 0 + || ((extcmdlist[idx].flags & AUTOCOMPLETE) == 0 && !ec_full_list) + || strlen(extcmdlist[idx].ef_txt) < 2) /* ignore "#" and "?" */ + return TRUE; + + return FALSE; +} + /* ARGSUSED */ void ec_key(w, event, params, num_params) @@ -1886,19 +1917,14 @@ Cardinal *num_params; if (extended_cmd_selected >= 0) swap_fg_bg(extended_commands[extended_cmd_selected]); extended_cmd_selected = -1; /* dismiss */ - ec_chars[0] = ec_chars[ec_nchars-1]; + ec_chars[0] = ec_chars[ec_nchars - 1]; ec_nchars = 1; } - for (i = 0; extcmdlist[i].ef_txt; i++) { - if (extcmdlist[i].flags & CMD_NOT_AVAILABLE) - continue; - if (extcmdlist[i].ef_txt[0] == '?') - continue; - - if (!strncmp(ec_chars, extcmdlist[i].ef_txt, ec_nchars)) { + for (i = 0; command_list[i]; ++i) { + if (!strncmp(ec_chars, command_list[i], ec_nchars)) { if (extended_cmd_selected != i) { - /* I should use set() and unset() actions, but how do */ - /* I send the an action to the widget? */ + /* I should use set() and unset() actions, but how do + I send the an action to the widget? */ if (extended_cmd_selected >= 0) swap_fg_bg(extended_commands[extended_cmd_selected]); extended_cmd_selected = i; @@ -1908,11 +1934,10 @@ Cardinal *num_params; ambiguous choices, plus one to show thare aren't any more such, will scroll into view */ do { - if (!extcmdlist[i + 1].ef_txt - || *extcmdlist[i + 1].ef_txt == '?') + if (!command_list[i + 1]) break; /* end of list */ ++i; - } while (!strncmp(ec_chars, extcmdlist[i].ef_txt, ec_nchars)); + } while (!strncmp(ec_chars, command_list[i], ec_nchars)); ec_scroll_to_view(i); return; @@ -1929,25 +1954,24 @@ static void init_extended_commands_popup() { int i, j, num_commands, ignore_cmds = 0; - const char **command_list; /* count commands */ for (num_commands = 0; extcmdlist[num_commands].ef_txt; num_commands++) - if (extcmdlist[num_commands].flags & CMD_NOT_AVAILABLE) + if (ignore_extcmd(num_commands)) ++ignore_cmds; - /* If the last entry is "help", don't use it. */ - if (strcmp(extcmdlist[num_commands - 1].ef_txt, "?") == 0) - --num_commands; - j = num_commands - ignore_cmds; - command_list = (const char **) alloc((unsigned) j * sizeof (char *)); + command_list = (const char **) alloc((unsigned) (j * sizeof (char *) + 1)); + command_indx = (short *) alloc((unsigned) (j * sizeof (short) + 1)); for (i = j = 0; i < num_commands; i++) { - if (extcmdlist[i].flags & CMD_NOT_AVAILABLE) + if (ignore_extcmd(i)) continue; + command_indx[j] = (short) i; command_list[j++] = extcmdlist[i].ef_txt; } + command_list[j] = (char *) 0; + command_indx[j] = -1; num_commands = j; extended_command_popup = @@ -1955,8 +1979,6 @@ init_extended_commands_popup() extended_command_translations, "dismiss", extend_dismiss, "help", extend_help, num_commands, command_list, &extended_commands, extend_select, &extended_command_form); - - free((char *) command_list); } /* ------------------------------------------------------------------------ */