I was looking at backporting an X11 build fix to 3.6 and decided
that the hangup handling wasn't correct if SAFERHANGUP is defined
(which it is by default). It didn't attempt to perform a hangup
save. Also, the handler might return when the X code calling it
expected it to not do so.
I don't know how to force a hangup within X11 so haven't tested
this properly. It works fine when there's no hangup. :-/
From the newsgroup: identifying by menu pops up multiple menus in
succession if the player picks fewer invent entries than are being
granted, but the second and subsequent ones could cover up the
message window and hide the feedback from prior ones.
If multiple popup menus are needed when identifying, issue --More--
before each menu after the first. The code seemed to be trying to
do this already, but it should have used wait_synch() rather than
mark_synch(), or perhaps used display_nhwindow(WIN_MESSAGE, TRUE)
instead of either one of those. For curses, both mark_synch() and
wait_synch() were no-ops. Now they do something. X11's behavior
wasn't right either; it seemed to be lagging one message behind
(something I had noticed recently and then forgotten about; I still
don't remember the context then so don't know whether this fixes
that earlier situation).
The consolidation of global variables from scattered source
files into decl.c and declared in decl.h was begun in 3.7.0.
Their placement in common files was done for centralized
initialization and potential re-initialization during a
"play again" scenario.
It wasn't really necessary for all of them to be housed in a
single huge structure to meet the "play again" requirement,
and the single huge structure has been a little unwieldy when
it comes to maintenance.
Following this commit, instead of one single extremely large structure
named 'g' to house all of the relocated global variables, they
are distributed into several ga through gz.
To make things easy for the developer, each variable is placed
into the struct corresponding to the starting letter of the variable.
That way, no lookup is required in order to know which struct houses
a particular variable, it is a simple match to the starting letter
for all the centralized global variables.
A global variable named 'amulets', would be found in ga.
ga.amulets
^ ^
A global varable named 'move', would be found in gm.
gm.moves
^ ^
A global variable named 'val_for_n_or_more' would be found in gv.
gv.val_for_n_or_more
^ ^
A global variable named 'youmonst' would be found in gy.
gy.youmonst
^ ^
Reset 'x_inited' after the various widgets have been released
during shutdown.
This might prevent the second panic ('X11_mark_synch()' during
emergency save) in the double panic reported in a later comment of
github issue #569. It definitely doesn't address whatever caused
the first panic, nor the poor handling of missing fonts that was
apparently responsible for #569's initial report.
Instead of using index() macro defined to strchr, use C99 strchr.
Instead of using rindex() macro defined to strrchr, use C99 strrchr.
If you want to try building on a platform that doesn't offer those
two functions, these are available:
define NOT_C99 /* to make some non-C99 code available */
define NEED_INDEX /* to define a macro for index() */
define NEED_RINDX /* to define a macro for rindex() */
Reissuing getlin() with a different prompt wasn't reliably resizing the
X11 prompt widget. After a lot of hacking away at win/X11/dialogs.c I
eventually tried setting the response portion of the widget first and
got much better results, enough to throw away the tentative changes to
dialogs.c.
There's still a lot of room from improvement but I think it would need
to replace the ghostview prompting instead of trying to massage that.
Change the inner workings of the experimental TTY_PERM_INVENT.
Switch to delivering the content to tty for the experimental perm_invent
via the existing window port interface (start_menu(), add_menu(), end_menu).
This also adds a new window port interface call ctrl_nhwindow() for
delivering information to the window port, and/or obtaining specific
information from the window port. The information and requests can
be extended as required. To be documented later once the changes settle
down.
Due to the intrusive nature of these changes and the possibility of
some bugs in the new code, I'm going to leave TTY_PERM_INVENT commented
out in the repository for a day or two. Anyone wishing to test it out
can do so by uncommenting TTY_PERM_INVENT in config.h.
Add a non-string identifier to window_procs for use in runtime
identification of the current window port being used.
Use a macro WPID to add the identification at the top of the
various existing window_procs declarations. It expands to the
existing text string, as well as the newly added field wp_id
with a wp_ identifier.
For example, WPID(tty) expands to: "tty", wp_tty
The generated wp_tty must be present in the wp_ids enum at
the top of include/winprocs.h.
The WINDOWPORT(x) macro has been updated to expand to a simple
value comparison (port.wp_id == wp_x), instead of a
string comparison.
(user-side decisions really, but as it stands right now
user-side decisions/options are made and processed by the core)
add a parameter to add_menu so color can be passed
Add a new window-port interface function
perminvent_info *
update_invent_slot(winid window, int slot, perminvent_info *);
That should be nice and flexible and allow exchanges of useful
information between the core and the window port. Information
to be exchange can be easily modified in include/wintype.h as
things evolve.
Information useful to the core can be exchanged from the
window-port in struct to_core.
Information useful from the core to the window-port can be
passed in struct from_core.
I'm not going to update any docs until much later after things
are fully working and settled.
This also doesn't fix or have anything to do with existing
TTY_PERM_INVENT issues.
Make the same change as was done for Qt three or so weeks ago: force
the 'toptenwin' option on in X11_init_nhwdinows() so that scores (or
wizard mode "your score is ignored") are shown in a popup text window
instead of being sent to stdout.
Fix the warnings issued when compiling win/X11/. The error handler
one is presumeably due to a change in /usr/include/X11/Intrinsic.h
between different releases of X11 and is inconsequential. The
indentation ones represented real bugs. The X11 convention of using
'foo(); argcount++;' requires braces when preceded by 'if' or 'else'.
I don't know why the convention doesn't use comma instead of semi-colon
between the function that adds an entry to an argument list and the
accumulating count of the number of those arguments.
A few years ago I added code to zero out various argument lists prior
to their use, which shouldn't have been necessary. The wrong argument
count being used when the 'if (whatever)' check fails could possibly
have been the reason that pre-zeroing solved mystery problems. I don't
remember enough details to attempt to go back and retest with this fix
in place.
Change the '|'/#perminv final positioning for X11 to be the same
as for curses: finishing with <escape> leaves the current view,
with <return> resets to unscrolled.
Actually getting ESC and RET to the right place wasn't trivial;
down the rabbit hole and out the other side. Using yn_function()
to get the #perminv keystrokes is less than ideal. (curses also
started that way but switched to raw character input for this.)
Add new '|' command, aka #perminv, which allows the player to
send menu scrolling keystrokes to the persistent inventory window.
Implemented for X11, where its usefulness is limited, and for
curses, where it is more needed and also more fully functional.
The interface can either prompt for one keystroke, act upon it,
and return to normal play, or it can loop for multiple keystrokes
until player types <return> or <escape>. X11 does the former if
the 'slow' application resource is False so that prompting uses
popups, and the latter when 'slow' is True where prompting is in
a fixed spot and doesn't end up causing the persistent inventory
window to be stacked behind the map window. curses always does
the loop-until-done approach. It also accepts up and down arrow
keys to scroll one line at a time.
Also adds two new menu scrolling commands, menu_shift_right (key
'}' by default) and menu_shift_left ('{') if wincap2 flags contain
WC2_MENU_SHIFT. Shifting allows different substrings of too-long
lines to be seen.
For X11, neither works because their handling requires a horizontal
scrollbar and for some reason that escapes me our menus don't have
one of those. If they did, shifts could work for all menus but a
shifted window would hide the selection letters. So shifting would
be most usefully done as: pan right, read more of any long lines,
immediately pan back to the left.
For curses, they only apply to the persistent inventory window.
Shift right redraws it with class headers and inventory letters
shown normally but the item descriptions omit their leftmost
portion, showing more text towards the end. Shift left reverses
that and does nothing if the beginning is already in view. Forward
and backward scrolling while shifted leave the shift in place.
Give the window-port side of *_update_inventory() an argument.
Calls in the core still omit that; invent.c's update_inventory()
is the only place that cares.
Looking up scrollbars did not work as intended. The code wanted an
ancestor widget that had both horizontal and vertical scrollbars,
but menus either have none or just vertical. The lookup code found
some top level widget and returned bad data.
Widget widths should have type 'Dimension' rather than plain 'int'.
Perform a couple of things once during popup widget creation rather
than every time it gets popped up.
When X11_yn_function() re-uses a popup widget to issue a prompt
and get the player's response, make it resize properly. I'm not
sure why the old hack for that apparently worked for some folks
and not for me, or why this does work for me. At least it does.
Also, make the minimum popup width be 25 characters so that
really short prompts don't result in tiny popups. Since the
popup appears at whatever spot the pointer happens to be sitting,
it isn't always immediately noticeable when the player is using
the keyboard rather than the pointer.
X11_getlin() echoing its prompt and response to message window
truncates combined value to maximum allowed pline (rather than
having pline truncate it). But it was truncating the response
as if the prompt was maximum allowed length instead of its actual
length, so possibly hiding some of the user's text unnecessarily.
After player has responded to a getline prompt, echo the prompt
and the line of text response to the message window. Uses pline()
so also gets put into core's message history for dumplog.
X11_yn_function() issues a pline() to put the prompt and player's
response into the message window. Change it to use visctrl() to
make sure that the response character is ledgible when something
like the '&' command allows an arbitrary answer.
This patch adds a leading space and two extra trailing spaces
to the prompt when it's being issued via popup, but that hasn't
affected the issue mentioned next....
The popup prompting when the 'slow' resource is False doesn't
always resize properly. I saw both too wide and too narrow
[What do you want to throw? [abc] ]b
[ In what direction? ]
and
[Really quit? [yn] (n) ]y
[Dump core? [ynq] (q) ]n (size seemed right, but hard to tell)
[Do you want your posses] (might have shown one more letter;
resize doodad in window's bottom right
corner on OSX oscures the rightmost
column--which is ordinarily a space)
The truncated one did accept responses. If I answered 'n' then
the next question was truncated too, but for 'y' (plus ensuing
feedback) it would be sized correctly for the question after that.
To be clear: the popup width issue was present before this change
and is still present after it. The code already has a hack that's
intended to deal with this but it doesn't do the job for me.
If 'perm_invent' is preset in player's options, have X11 show the
persistent inventory window from the start instead of waiting for
an 'i' command. moveloop() prolog needed a tweak do deal with it
cleanly.
Require WC_PERM_INVENT in order to honor the perm_invent option.
X11 and curses already set that, tty and curses don't support it,
so only Windows GUI needed to be updated for it.
When persistent inventory window is up, remove it if 'perm_invent'
option gets set to False. This has a side-effect of fixing the
end-of-game prompting problem it caused.
This hack prevents the perm_invent window for X11 on OSX from
creeping every time it gets updated. It is far from perfect and
at the very least ought be handled via user settable X resources
rather than hardcoded values, but it's as much effort as I'm likely
to spend.
Add a new file containing a list of issues that ought to be fixed.
The initial entries are things I noticed while experimenting with
perm_invent; there is lots of older stuff that could/should be
there too. I'm not sure whether the first one is OSX-specific; the
others aren't.
Prevent the "X Error (bad Atom)" situation that causes an
"X Error" panic.
The issue isn't fixed. This fails to implement the intended
functionality of having the X server remember the persistent
inventory window's location across games (until the next time
that the X server restarts). Worse, on OSX the window creeps
each time it is updated (visually it seems to be moving down by
the height of the window's title bar).
That's not as bad as having it move to the pointer's location as
it did in 3.6.1, but prior to the commit which introduced this
code that had been fixed and it stayed put during the current
game, so more work is definitely needed.
Implement the 'selectsaved' option for X11. Requires that
SELECTSAVED be defined at compile time.
Behaves the same as for tty and curses except that if you
choose 'quit', the intended "until next time..." message doesn't
get delivered anywhere.
further adjustments to the window port interface to pass a pointer
to a glyph_info struct which describes not just the glyph number
itself, but also the ttychar, the color, the glyphflags, and the
symset index.
This affects two existing window port calls that get passed glyphs
and does the parameter consistently for both of them using the
glyph_info struct pointer:
print_glyph()
add_menu().
The recently added glyphmod parameter is now unnecessary and has been
removed.
Add support for black&white ice (3.7.0 feature) similar to already
supported black&white lava: show in inverse video if it uses the
same character as floor (in the ice case; as water in the lava case).
Inverse for monster detection, black&white lava, and now black&white
ice was being done unconditionally but has been changed so that the
user can disable it by toggling the 'use_inverse' run-time option.
[Bug noticed in the process: if you move an inverse video cursor
onto inverse video detected monster/lava/ice (when doing farlook, for
instance), the cursor disappears. I'm not sure how to address that.]
I started out adding a few new status conditions to X11's "fancy status"
(the default) to gauge how difficult it was going to be. In the process
I found several latent bugs. After fixing those, I decided that the same
status conditions should be added to the alternate "tty-style status".
Lots more latent bugs, some of the same nature, others different. Things
spiraled until the code change is very substantial.
Code for the old two-line status is still present but I don't know how
to activate it. Unlike tty-style status, it composes and displays two
lines of text and isn't capable of highlighting portions of that text,
so it would be considered deprecated anyway.
All testing was done with the default NetHack.ad (except when turning
'fancy_status' off) so I don't know whether the new code might override
previously customizable status settings. I'm not sure whether this list
covers all the fixes....
both tty-style and fancy
add new status conditions 'grabbed' (by eel), 'held', 'trapped', and
'sinking-into-lava' (others will eventually follow); grab and lava
are on by default, the others have to be enabled via options
both tty-style (not handled) and fancy (faulty boolean logic)
polymorphing didn't change Xp to HD (silver lining: rehumanizing
didn't need to reverse it)
tty-style only; fancy was ok
force white text (on black background) instead of settling for gray
turning on optional showexp, showscore, and/or time worked but turning
them back off again didn't remove the relevant fields
polymorphing when showexp was on didn't suppress Exp-points
tty-style only; fancy uses different layout
condense conditions into simple left-to-right space separated list
instead of giving them specific locations and having gaps of blank
space for conditions that aren't in effect
tty-style only; not applicable for fancy (status_hilites not implemented)
all highlights stuck if 'statushilites' was reset to 0 to disable them
displaying anything with bold attribute stuck; it wouldn't revert to
normal text if a different highlight rule without bold was used for
subsequent updates
avoid inverting leading space that separates from preceding field when
highlighting with inverse video attribute
add support for 'dim' attribute using gray foreground (only viable
after the fix for white foreground)
fancy only
reorganize the field layout so that things line up nicely instead of
having columns with six, seven, or eight lines be spread over same
amount of vertical space
line up the values of the six characteristics, similar to how vertical
status works in curses: all two digits; when exceptional strength is
present, the '18' lines up and rest goes past implicit right margin
use status conditions as provided by core instead of duplicating them
(other fields still duplicate stuff done in botl.c); doing this
required forcing 'VIA_WINDOWPORT()' if built without STATUS_HILITES
combine boolean and compound options into a single allopt[] array for
processing in options.c.
move the definitions of the options into new include/optlist.h file which
uses a set of macros to define them appropriately.
during compile of options.c each option described in include/optlist.h:
1. automatically results in a function prototype for an optfn called
optfn_xxxx (xxxx is the option name).
2. automatically results in an opt_xxxx enum value for referencing
its index throughout options.c (xxxx is the option name).
3. is used to initialize an element of the allopt[] array at index
opt_xxxx (xxxx is the option name) based on the settings in the
NHOPTB, NHOPTC, NHOPTP macros. Those macros only live during the
compilation of include/optlist.h.
each optfn_xxxx() function can be called with a req id of: do_init, do_set,
get_val or do_handler.
req do_init is called from options_init, and if initialization or memory
allocation or other initialization for that particular option is needed,
it can be done in response to the init req.
req do_set is called from parseoptions() for each option it encounters
and the optfn_xxxx() function is expected to react and set the option
based on the string values that parseoptions() passes to it.
req get_val expects each optfn_xxxx() function to write the current
option value into the buffer it is passed.
req do_handler is called during doset() operations in response to player
selections most likely from the 'O' option-setting menu, but only if the
option is identified as having do_handler support in the allopts[]
'has_handler' boolean flag. Not every optfn_xxxx() does.
function special_handling() is eliminated. It's code has been redistributed
to individual handler functions for the option or purpose that they serve.
moved reglyph_darkroom() function from options.c to display.c
Provide a way to communicate additional behaviors and/or appearances
desired from NetHack window port menus.
This is foundation work for changes to follow at a future date.