Merge branch 'NetHack-3.6.2'
This commit is contained in:
2132
doc/Guidebook.mn
2132
doc/Guidebook.mn
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
4270
doc/Guidebook.txt
4270
doc/Guidebook.txt
File diff suppressed because it is too large
Load Diff
@@ -163,6 +163,14 @@ Elbereth hypocrisy penalty doesn't apply if attacking a monster which isn't
|
|||||||
Elbereth hypocrisy penalty reduced when alignment is already low
|
Elbereth hypocrisy penalty reduced when alignment is already low
|
||||||
during character creation, don't unset alternate weapon when a shield gets
|
during character creation, don't unset alternate weapon when a shield gets
|
||||||
worn (was preventing knight from having lance set up as uswapwep)
|
worn (was preventing knight from having lance set up as uswapwep)
|
||||||
|
preformatted Guidebook.txt split line in middle of "' '" for #wait command
|
||||||
|
prevent simiulated screenshot in Guidebook.txt from spanning page boundary
|
||||||
|
overview information for former hero was not being set properly when bones
|
||||||
|
file was saved, so current hero coming across a dead hero's grave
|
||||||
|
didn't have #overview feedback augmented with "final resting place"
|
||||||
|
in Guidebook.mn and Guidebook.txt, the 'I' command mis-described `IX' as
|
||||||
|
displaying inventory items whose bless/curse state is "known"
|
||||||
|
(Guidebook.tex correctly had "unknown")
|
||||||
|
|
||||||
|
|
||||||
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
|
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
|
||||||
@@ -231,6 +239,9 @@ X11: allow mouse wheel scrolling to work in menus by default
|
|||||||
X11: handle paged menu control keys
|
X11: handle paged menu control keys
|
||||||
X11: remember perm_invent window geometry
|
X11: remember perm_invent window geometry
|
||||||
X11: handle X errors via panic
|
X11: handle X errors via panic
|
||||||
|
X11: don't reuse perm_invent window for picking an object
|
||||||
|
X11: obey mouse_support and allow toggling it in game
|
||||||
|
X11: obey menu movement keys
|
||||||
|
|
||||||
|
|
||||||
General New Features
|
General New Features
|
||||||
|
|||||||
@@ -307,6 +307,7 @@ E void FDECL(highlight_yn, (BOOLEAN_P));
|
|||||||
E void FDECL(nh_XtPopup, (Widget, int, Widget));
|
E void FDECL(nh_XtPopup, (Widget, int, Widget));
|
||||||
E void FDECL(nh_XtPopdown, (Widget));
|
E void FDECL(nh_XtPopdown, (Widget));
|
||||||
E void FDECL(win_X11_init, (int));
|
E void FDECL(win_X11_init, (int));
|
||||||
|
E void FDECL(find_scrollbars, (Widget, Widget *, Widget *));
|
||||||
E void FDECL(nh_keyscroll, (Widget, XEvent *, String *, Cardinal *));
|
E void FDECL(nh_keyscroll, (Widget, XEvent *, String *, Cardinal *));
|
||||||
|
|
||||||
/* ### winmesg.c ### */
|
/* ### winmesg.c ### */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 bones.c $NHDT-Date: 1508827591 2017/10/24 06:46:31 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.71 $ */
|
/* NetHack 3.6 bones.c $NHDT-Date: 1539653203 2018/10/16 01:26:43 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.73 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
|
||||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -463,6 +463,7 @@ make_bones:
|
|||||||
resetobjs(level.buriedobjlist, FALSE);
|
resetobjs(level.buriedobjlist, FALSE);
|
||||||
|
|
||||||
/* Hero is no longer on the map. */
|
/* Hero is no longer on the map. */
|
||||||
|
u.ux0 = u.ux, u.uy0 = u.uy;
|
||||||
u.ux = u.uy = 0;
|
u.ux = u.uy = 0;
|
||||||
|
|
||||||
/* Clear all memory from the level. */
|
/* Clear all memory from the level. */
|
||||||
@@ -488,7 +489,7 @@ make_bones:
|
|||||||
formatkiller(newbones->how, sizeof newbones->how, how, TRUE);
|
formatkiller(newbones->how, sizeof newbones->how, how, TRUE);
|
||||||
Strcpy(newbones->when, yyyymmddhhmmss(when));
|
Strcpy(newbones->when, yyyymmddhhmmss(when));
|
||||||
/* final resting place, used to decide when bones are discovered */
|
/* final resting place, used to decide when bones are discovered */
|
||||||
newbones->frpx = u.ux, newbones->frpy = u.uy;
|
newbones->frpx = u.ux0, newbones->frpy = u.uy0;
|
||||||
newbones->bonesknown = FALSE;
|
newbones->bonesknown = FALSE;
|
||||||
/* if current character died on a bones level, the cemetery list
|
/* if current character died on a bones level, the cemetery list
|
||||||
will have multiple entries, most recent (this dead hero) first */
|
will have multiple entries, most recent (this dead hero) first */
|
||||||
|
|||||||
59
src/detect.c
59
src/detect.c
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 detect.c $NHDT-Date: 1522891623 2018/04/05 01:27:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.81 $ */
|
/* NetHack 3.6 detect.c $NHDT-Date: 1539908137 2018/10/19 00:15:37 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.83 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Robert Patrick Rankin, 2018. */
|
/*-Copyright (c) Robert Patrick Rankin, 2018. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -1539,44 +1539,41 @@ mfind0(mtmp, via_warning)
|
|||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
boolean via_warning;
|
boolean via_warning;
|
||||||
{
|
{
|
||||||
xchar x = mtmp->mx,
|
int x = mtmp->mx, y = mtmp->my;
|
||||||
y = mtmp->my;
|
boolean found_something = FALSE;
|
||||||
|
|
||||||
if (via_warning && !warning_of(mtmp))
|
if (via_warning && !warning_of(mtmp))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (mtmp->m_ap_type) {
|
if (mtmp->m_ap_type) {
|
||||||
seemimic(mtmp);
|
seemimic(mtmp);
|
||||||
find:
|
found_something = TRUE;
|
||||||
exercise(A_WIS, TRUE);
|
} else if (mtmp->mundetected
|
||||||
if (!canspotmon(mtmp)) {
|
&& (is_hider(mtmp->data) || mtmp->data->mlet == S_EEL)) {
|
||||||
if (glyph_is_invisible(levl[x][y].glyph)) {
|
if (via_warning) {
|
||||||
/* Found invisible monster in a square which already has
|
Your("warning senses cause you to take a second %s.",
|
||||||
* an 'I' in it. Logically, this should still take time
|
Blind ? "to check nearby" : "look close by");
|
||||||
* and lead to a return 1, but if we did that the player
|
display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */
|
||||||
* would keep finding the same monster every turn.
|
}
|
||||||
*/
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
You_feel("an unseen monster!");
|
|
||||||
map_invisible(x, y);
|
|
||||||
}
|
|
||||||
} else if (!sensemon(mtmp))
|
|
||||||
You("find %s.",
|
|
||||||
mtmp->mtame ? y_monnam(mtmp) : a_monnam(mtmp));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!canspotmon(mtmp)) {
|
|
||||||
if (mtmp->mundetected
|
|
||||||
&& (is_hider(mtmp->data) || mtmp->data->mlet == S_EEL))
|
|
||||||
if (via_warning) {
|
|
||||||
Your("warning senses cause you to take a second %s.",
|
|
||||||
Blind ? "to check nearby" : "look close by");
|
|
||||||
display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */
|
|
||||||
}
|
|
||||||
mtmp->mundetected = 0;
|
mtmp->mundetected = 0;
|
||||||
newsym(x, y);
|
newsym(x, y);
|
||||||
goto find;
|
found_something = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_something) {
|
||||||
|
if (!canspotmon(mtmp) && glyph_is_invisible(levl[x][y].glyph))
|
||||||
|
return -1; /* Found invisible monster in square which already has
|
||||||
|
* 'I' in it. Logically, this should still take time
|
||||||
|
* and lead to `return 1', but if we did that the hero
|
||||||
|
* would keep finding the same monster every turn. */
|
||||||
|
exercise(A_WIS, TRUE);
|
||||||
|
if (!canspotmon(mtmp)) {
|
||||||
|
map_invisible(x, y);
|
||||||
|
You_feel("an unseen monster!");
|
||||||
|
} else if (!sensemon(mtmp)) {
|
||||||
|
You("find %s.", mtmp->mtame ? y_monnam(mtmp) : a_monnam(mtmp));
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1307,6 +1307,7 @@ char **argv;
|
|||||||
|
|
||||||
/* add another option that can be set */
|
/* add another option that can be set */
|
||||||
set_wc_option_mod_status(WC_TILED_MAP, SET_IN_GAME);
|
set_wc_option_mod_status(WC_TILED_MAP, SET_IN_GAME);
|
||||||
|
set_option_mod_status("mouse_support", SET_IN_GAME);
|
||||||
|
|
||||||
load_default_resources(); /* create default_resource_data[] */
|
load_default_resources(); /* create default_resource_data[] */
|
||||||
|
|
||||||
@@ -2547,6 +2548,20 @@ int dir;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
find_scrollbars(w, horiz, vert)
|
||||||
|
Widget w;
|
||||||
|
Widget *horiz, *vert;
|
||||||
|
{
|
||||||
|
if (w) {
|
||||||
|
do {
|
||||||
|
*horiz = XtNameToWidget(w, "*horizontal");
|
||||||
|
*vert = XtNameToWidget(w, "*vertical");
|
||||||
|
w = XtParent(w);
|
||||||
|
} while (!*horiz && !*vert && w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Callback
|
/* Callback
|
||||||
* Scroll a viewport, using standard NH 1,2,3,4,6,7,8,9 directions.
|
* Scroll a viewport, using standard NH 1,2,3,4,6,7,8,9 directions.
|
||||||
*/
|
*/
|
||||||
@@ -2559,7 +2574,7 @@ String *params;
|
|||||||
Cardinal *num_params;
|
Cardinal *num_params;
|
||||||
{
|
{
|
||||||
Arg arg[2];
|
Arg arg[2];
|
||||||
Widget horiz_sb, vert_sb, scrollw;
|
Widget horiz_sb = (Widget) 0, vert_sb = (Widget) 0;
|
||||||
float top, shown;
|
float top, shown;
|
||||||
Boolean do_call;
|
Boolean do_call;
|
||||||
int direction;
|
int direction;
|
||||||
@@ -2572,12 +2587,7 @@ Cardinal *num_params;
|
|||||||
|
|
||||||
direction = atoi(params[0]);
|
direction = atoi(params[0]);
|
||||||
|
|
||||||
scrollw = viewport;
|
find_scrollbars(viewport, &horiz_sb, &vert_sb);
|
||||||
do {
|
|
||||||
horiz_sb = XtNameToWidget(scrollw, "*horizontal");
|
|
||||||
vert_sb = XtNameToWidget(scrollw, "*vertical");
|
|
||||||
scrollw = XtParent(scrollw);
|
|
||||||
} while (!horiz_sb && !vert_sb && scrollw);
|
|
||||||
|
|
||||||
#define H_DELTA 0.25 /* distance of horiz shift */
|
#define H_DELTA 0.25 /* distance of horiz shift */
|
||||||
/* vert shift is half of curr distance */
|
/* vert shift is half of curr distance */
|
||||||
|
|||||||
@@ -1029,6 +1029,9 @@ Cardinal *num_params;
|
|||||||
|
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
|
if (!iflags.wc_mouse_support)
|
||||||
|
return;
|
||||||
|
|
||||||
button = (XButtonEvent *) event;
|
button = (XButtonEvent *) event;
|
||||||
#ifdef VERBOSE_INPUT
|
#ifdef VERBOSE_INPUT
|
||||||
printf("button press\n");
|
printf("button press\n");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 winmenu.c $NHDT-Date: 1539216247 2018/10/11 00:04:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.18 $ */
|
/* NetHack 3.6 winmenu.c $NHDT-Date: 1539812601 2018/10/17 21:43:21 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.28 $ */
|
||||||
/* Copyright (c) Dean Luick, 1992 */
|
/* Copyright (c) Dean Luick, 1992 */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <X11/Xaw/Command.h>
|
#include <X11/Xaw/Command.h>
|
||||||
#include <X11/Xaw/Viewport.h>
|
#include <X11/Xaw/Viewport.h>
|
||||||
#include <X11/Xaw/Cardinals.h>
|
#include <X11/Xaw/Cardinals.h>
|
||||||
|
#include <X11/Xaw/Scrollbar.h>
|
||||||
#include <X11/Xaw/Box.h>
|
#include <X11/Xaw/Box.h>
|
||||||
#include <X11/Xos.h>
|
#include <X11/Xos.h>
|
||||||
|
|
||||||
@@ -37,7 +38,8 @@
|
|||||||
|
|
||||||
XColor FDECL(get_nhcolor, (struct xwindow *, int));
|
XColor FDECL(get_nhcolor, (struct xwindow *, int));
|
||||||
static void FDECL(init_menu_nhcolors, (struct xwindow *));
|
static void FDECL(init_menu_nhcolors, (struct xwindow *));
|
||||||
|
static void FDECL(menu_size_change_handler, (Widget, XtPointer,
|
||||||
|
XEvent *, Boolean *));
|
||||||
static void FDECL(menu_select, (Widget, XtPointer, XtPointer));
|
static void FDECL(menu_select, (Widget, XtPointer, XtPointer));
|
||||||
static void FDECL(invert_line, (struct xwindow *, x11_menu_item *, int, long));
|
static void FDECL(invert_line, (struct xwindow *, x11_menu_item *, int, long));
|
||||||
static void FDECL(menu_ok, (Widget, XtPointer, XtPointer));
|
static void FDECL(menu_ok, (Widget, XtPointer, XtPointer));
|
||||||
@@ -52,6 +54,11 @@ static void FDECL(select_match, (struct xwindow *, char *));
|
|||||||
static void FDECL(invert_all, (struct xwindow *));
|
static void FDECL(invert_all, (struct xwindow *));
|
||||||
static void FDECL(invert_match, (struct xwindow *, char *));
|
static void FDECL(invert_match, (struct xwindow *, char *));
|
||||||
static void FDECL(menu_popdown, (struct xwindow *));
|
static void FDECL(menu_popdown, (struct xwindow *));
|
||||||
|
static Widget FDECL(menu_create_buttons, (struct xwindow *, Widget, Widget));
|
||||||
|
static void FDECL(load_boldfont, (struct xwindow *, Widget));
|
||||||
|
static void FDECL(menu_create_entries, (struct xwindow *, struct menu *));
|
||||||
|
static void FDECL(destroy_menu_entry_widgets, (struct xwindow *));
|
||||||
|
static void NDECL(create_menu_translation_tables);
|
||||||
|
|
||||||
static void FDECL(move_menu, (struct menu *, struct menu *));
|
static void FDECL(move_menu, (struct menu *, struct menu *));
|
||||||
static void FDECL(free_menu_line_entries, (struct menu *));
|
static void FDECL(free_menu_line_entries, (struct menu *));
|
||||||
@@ -75,6 +82,49 @@ static const char menu_entry_translations[] = "#override\n\
|
|||||||
<Btn4Down>: scroll(8)\n\
|
<Btn4Down>: scroll(8)\n\
|
||||||
<Btn5Down>: scroll(2)";
|
<Btn5Down>: scroll(2)";
|
||||||
|
|
||||||
|
XtTranslations menu_entry_translation_table = (XtTranslations) 0;
|
||||||
|
XtTranslations menu_translation_table = (XtTranslations) 0;
|
||||||
|
XtTranslations menu_del_translation_table = (XtTranslations) 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_menu_translation_tables()
|
||||||
|
{
|
||||||
|
if (!menu_translation_table) {
|
||||||
|
menu_translation_table = XtParseTranslationTable(menu_translations);
|
||||||
|
menu_entry_translation_table
|
||||||
|
= XtParseTranslationTable(menu_entry_translations);
|
||||||
|
menu_del_translation_table
|
||||||
|
= XtParseTranslationTable("<Message>WM_PROTOCOLS: menu_delete()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static void
|
||||||
|
menu_size_change_handler(w, ptr, event, flag)
|
||||||
|
Widget w;
|
||||||
|
XtPointer ptr;
|
||||||
|
XEvent *event;
|
||||||
|
Boolean *flag;
|
||||||
|
{
|
||||||
|
struct xwindow *wp = (struct xwindow *) ptr;
|
||||||
|
|
||||||
|
nhUse(w);
|
||||||
|
nhUse(flag);
|
||||||
|
|
||||||
|
if (!wp || !event)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (iflags.perm_invent && wp == &window_list[WIN_INVEN]
|
||||||
|
&& wp->menu_information->how == PICK_NONE) {
|
||||||
|
get_widget_window_geometry(wp->popup,
|
||||||
|
&wp->menu_information->permi_x,
|
||||||
|
&wp->menu_information->permi_y,
|
||||||
|
&wp->menu_information->permi_w,
|
||||||
|
&wp->menu_information->permi_h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Menu callback.
|
* Menu callback.
|
||||||
*/
|
*/
|
||||||
@@ -275,6 +325,27 @@ Cardinal *num_params;
|
|||||||
else
|
else
|
||||||
X11_nhbell();
|
X11_nhbell();
|
||||||
return;
|
return;
|
||||||
|
} else if (ch == MENU_FIRST_PAGE || ch == MENU_LAST_PAGE) {
|
||||||
|
Widget hbar = (Widget) 0, vbar = (Widget) 0;
|
||||||
|
float top = (ch == MENU_FIRST_PAGE) ? 0.0 : 1.0;
|
||||||
|
find_scrollbars(wp->w, &hbar, &vbar);
|
||||||
|
if (vbar)
|
||||||
|
XtCallCallbacks(vbar, XtNjumpProc, &top);
|
||||||
|
return;
|
||||||
|
} else if (ch == MENU_NEXT_PAGE || ch == MENU_PREVIOUS_PAGE) {
|
||||||
|
Widget hbar = (Widget) 0, vbar = (Widget) 0;
|
||||||
|
find_scrollbars(wp->w, &hbar, &vbar);
|
||||||
|
if (vbar) {
|
||||||
|
float shown, top;
|
||||||
|
Arg arg[2];
|
||||||
|
XtSetArg(arg[0], nhStr(XtNshown), &shown);
|
||||||
|
XtSetArg(arg[1], nhStr(XtNtopOfThumb), &top);
|
||||||
|
XtGetValues(vbar, arg, TWO);
|
||||||
|
top += ((ch == MENU_NEXT_PAGE) ? shown : -shown);
|
||||||
|
if (vbar)
|
||||||
|
XtCallCallbacks(vbar, XtNjumpProc, &top);
|
||||||
|
}
|
||||||
|
return;
|
||||||
} else if (index(menu_info->curr_menu.gacc, ch)) {
|
} else if (index(menu_info->curr_menu.gacc, ch)) {
|
||||||
group_accel:
|
group_accel:
|
||||||
/* matched a group accelerator */
|
/* matched a group accelerator */
|
||||||
@@ -521,15 +592,6 @@ static void
|
|||||||
menu_popdown(wp)
|
menu_popdown(wp)
|
||||||
struct xwindow *wp;
|
struct xwindow *wp;
|
||||||
{
|
{
|
||||||
if (iflags.perm_invent && wp == &window_list[WIN_INVEN]
|
|
||||||
&& wp->menu_information->how == PICK_NONE) {
|
|
||||||
get_widget_window_geometry(wp->popup,
|
|
||||||
&wp->menu_information->permi_x,
|
|
||||||
&wp->menu_information->permi_y,
|
|
||||||
&wp->menu_information->permi_w,
|
|
||||||
&wp->menu_information->permi_h);
|
|
||||||
}
|
|
||||||
|
|
||||||
nh_XtPopdown(wp->popup); /* remove the event grab */
|
nh_XtPopdown(wp->popup); /* remove the event grab */
|
||||||
XtDestroyWidget(wp->popup);
|
XtDestroyWidget(wp->popup);
|
||||||
wp->w = wp->popup = (Widget) 0;
|
wp->w = wp->popup = (Widget) 0;
|
||||||
@@ -538,8 +600,7 @@ struct xwindow *wp;
|
|||||||
wp->menu_information->is_up = FALSE; /* menu is down */
|
wp->menu_information->is_up = FALSE; /* menu is down */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global functions ========================================================
|
/* Global functions ======================================================= */
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
X11_start_menu(window)
|
X11_start_menu(window)
|
||||||
@@ -653,10 +714,292 @@ const char *query;
|
|||||||
menu_info->new_menu.query = copy_of(query);
|
menu_info->new_menu.query = copy_of(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
X11_select_menu(window, how, menu_list)
|
||||||
|
winid window;
|
||||||
|
int how;
|
||||||
|
menu_item **menu_list;
|
||||||
|
{
|
||||||
|
x11_menu_item *curr;
|
||||||
|
struct xwindow *wp;
|
||||||
|
struct menu_info_t *menu_info;
|
||||||
|
Arg args[10];
|
||||||
|
Cardinal num_args;
|
||||||
|
int retval;
|
||||||
|
Dimension v_pixel_width, v_pixel_height;
|
||||||
|
boolean labeled;
|
||||||
|
Widget viewport_widget, form, label, all;
|
||||||
|
char gacc[QBUFSZ], *ap;
|
||||||
|
boolean permi;
|
||||||
|
|
||||||
|
*menu_list = (menu_item *) 0;
|
||||||
|
check_winid(window);
|
||||||
|
wp = &window_list[window];
|
||||||
|
menu_info = wp->menu_information;
|
||||||
|
if (!menu_info->is_menu) {
|
||||||
|
impossible("select_menu: called before start_menu");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
debugpline2("X11_select_menu(%i, %i)", window, how);
|
||||||
|
|
||||||
|
create_menu_translation_tables();
|
||||||
|
|
||||||
|
if (menu_info->permi && how != PICK_NONE) {
|
||||||
|
/* Core is reusing perm_invent window for picking an item.
|
||||||
|
But it could be even on a different screen!
|
||||||
|
Create a new temp window for it instead. */
|
||||||
|
winid newwin = X11_create_nhwindow(NHW_MENU);
|
||||||
|
struct xwindow *nwp = &window_list[newwin];
|
||||||
|
|
||||||
|
X11_start_menu(newwin);
|
||||||
|
move_menu(&menu_info->new_menu, &nwp->menu_information->new_menu);
|
||||||
|
for (curr = nwp->menu_information->new_menu.base; curr;
|
||||||
|
curr = curr->next)
|
||||||
|
curr->window = newwin;
|
||||||
|
nwp->menu_information->permi = FALSE;
|
||||||
|
retval = X11_select_menu(newwin, how, menu_list);
|
||||||
|
destroy_menu_entry_widgets(nwp);
|
||||||
|
X11_destroy_nhwindow(newwin);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_info->how = (short) how;
|
||||||
|
|
||||||
|
/* collect group accelerators; for PICK_NONE, they're ignored;
|
||||||
|
for PICK_ONE, only those which match exactly one entry will be
|
||||||
|
accepted; for PICK_ANY, those which match any entry are okay */
|
||||||
|
gacc[0] = '\0';
|
||||||
|
if (menu_info->how != PICK_NONE) {
|
||||||
|
int i, n, gcnt[128];
|
||||||
|
#define GSELIDX(c) ((c) & 127) /* guard against `signed char' */
|
||||||
|
|
||||||
|
for (i = 0; i < SIZE(gcnt); i++)
|
||||||
|
gcnt[i] = 0;
|
||||||
|
for (n = 0, curr = menu_info->new_menu.base; curr; curr = curr->next)
|
||||||
|
if (curr->gselector && curr->gselector != curr->selector) {
|
||||||
|
++n;
|
||||||
|
++gcnt[GSELIDX(curr->gselector)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n > 0) /* at least one group accelerator found */
|
||||||
|
for (ap = gacc, curr = menu_info->new_menu.base; curr;
|
||||||
|
curr = curr->next)
|
||||||
|
if (curr->gselector && !index(gacc, curr->gselector)
|
||||||
|
&& (menu_info->how == PICK_ANY
|
||||||
|
|| gcnt[GSELIDX(curr->gselector)] == 1)) {
|
||||||
|
*ap++ = curr->gselector;
|
||||||
|
*ap = '\0'; /* re-terminate for index() */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
menu_info->new_menu.gacc = copy_of(gacc);
|
||||||
|
reset_menu_count(menu_info);
|
||||||
|
|
||||||
|
labeled = (menu_info->new_menu.query && *(menu_info->new_menu.query))
|
||||||
|
? TRUE
|
||||||
|
: FALSE;
|
||||||
|
|
||||||
|
permi = (window == WIN_INVEN && iflags.perm_invent && how == PICK_NONE);
|
||||||
|
|
||||||
|
if (menu_info->is_up) {
|
||||||
|
if (!menu_info->permi) {
|
||||||
|
destroy_menu_entry_widgets(wp);
|
||||||
|
nh_XtPopdown(wp->popup);
|
||||||
|
XtDestroyWidget(wp->popup);
|
||||||
|
wp->w = wp->popup = (Widget) 0;
|
||||||
|
menu_info->is_up = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!menu_info->is_up) {
|
||||||
|
menu_info->permi = permi;
|
||||||
|
|
||||||
|
num_args = 0;
|
||||||
|
XtSetArg(args[num_args], XtNallowShellResize, True);
|
||||||
|
num_args++;
|
||||||
|
if (permi && menu_info->permi_x != -1) {
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNwidth), menu_info->permi_w);
|
||||||
|
num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNheight), menu_info->permi_h);
|
||||||
|
num_args++;
|
||||||
|
}
|
||||||
|
wp->popup = XtCreatePopupShell((window == WIN_INVEN)
|
||||||
|
? "inventory" : "menu",
|
||||||
|
(how == PICK_NONE)
|
||||||
|
? topLevelShellWidgetClass
|
||||||
|
: transientShellWidgetClass,
|
||||||
|
toplevel, args, num_args);
|
||||||
|
XtOverrideTranslations(wp->popup, menu_del_translation_table);
|
||||||
|
|
||||||
|
if (permi)
|
||||||
|
XtAddEventHandler(wp->popup, StructureNotifyMask, False,
|
||||||
|
menu_size_change_handler, (XtPointer) wp);
|
||||||
|
|
||||||
|
num_args = 0;
|
||||||
|
XtSetArg(args[num_args], XtNtranslations,
|
||||||
|
menu_translation_table); num_args++;
|
||||||
|
form = XtCreateManagedWidget("mform", formWidgetClass, wp->popup,
|
||||||
|
args, num_args);
|
||||||
|
|
||||||
|
num_args = 0;
|
||||||
|
XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++;
|
||||||
|
|
||||||
|
label = labeled ? XtCreateManagedWidget(menu_info->new_menu.query,
|
||||||
|
labelWidgetClass, form,
|
||||||
|
args, num_args)
|
||||||
|
: (Widget) 0;
|
||||||
|
|
||||||
|
all = menu_create_buttons(wp, form, label);
|
||||||
|
|
||||||
|
num_args = 0;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNallowVert), True); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNallowHoriz), False); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNuseBottom), True); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNuseRight), True); num_args++;
|
||||||
|
#if 0
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNforceBars), True); num_args++;
|
||||||
|
#endif
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNfromVert), all); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNbottom), XtChainBottom); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNright), XtChainRight); num_args++;
|
||||||
|
XtSetArg(args[num_args], XtNtranslations,
|
||||||
|
menu_translation_table); num_args++;
|
||||||
|
viewport_widget = XtCreateManagedWidget(
|
||||||
|
"menu_viewport", /* name */
|
||||||
|
viewportWidgetClass, form, /* parent widget */
|
||||||
|
args, num_args); /* values, and number of values */
|
||||||
|
|
||||||
|
num_args = 0;
|
||||||
|
XtSetArg(args[num_args], XtNwidth, 100);
|
||||||
|
num_args++;
|
||||||
|
XtSetArg(args[num_args], XtNheight, 500);
|
||||||
|
num_args++;
|
||||||
|
|
||||||
|
wp->w = XtCreateManagedWidget("menu_list", formWidgetClass,
|
||||||
|
viewport_widget, args, num_args);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (menu_info->is_up && permi && menu_info->curr_menu.base) {
|
||||||
|
/* perm_invent window - explicitly destroy old menu entry widgets,
|
||||||
|
without recreating whole window */
|
||||||
|
destroy_menu_entry_widgets(wp);
|
||||||
|
free_menu_line_entries(&menu_info->curr_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make new menu the current menu */
|
||||||
|
move_menu(&menu_info->new_menu, &menu_info->curr_menu);
|
||||||
|
menu_create_entries(wp, &menu_info->curr_menu);
|
||||||
|
|
||||||
|
/* if viewport will be bigger than the screen, limit its height */
|
||||||
|
num_args = 0;
|
||||||
|
XtSetArg(args[num_args], XtNwidth, &v_pixel_width); num_args++;
|
||||||
|
XtSetArg(args[num_args], XtNheight, &v_pixel_height); num_args++;
|
||||||
|
XtGetValues(wp->w, args, num_args);
|
||||||
|
if ((Dimension) XtScreen(wp->w)->height * 5 / 6 < v_pixel_height) {
|
||||||
|
/* scrollbar is 14 pixels wide. Widen the form to accommodate it. */
|
||||||
|
v_pixel_width += 14;
|
||||||
|
|
||||||
|
/* shrink to fit vertically */
|
||||||
|
v_pixel_height = XtScreen(wp->w)->height * 5 / 6;
|
||||||
|
|
||||||
|
num_args = 0;
|
||||||
|
XtSetArg(args[num_args], XtNwidth, v_pixel_width); num_args++;
|
||||||
|
XtSetArg(args[num_args], XtNheight, v_pixel_height); num_args++;
|
||||||
|
XtSetValues(wp->w, args, num_args);
|
||||||
|
}
|
||||||
|
XtRealizeWidget(wp->popup); /* need to realize before we position */
|
||||||
|
|
||||||
|
/* if menu is not up, position it */
|
||||||
|
if (!menu_info->is_up) {
|
||||||
|
positionpopup(wp->popup, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_info->is_up = TRUE;
|
||||||
|
if (permi) {
|
||||||
|
if (permi && menu_info->permi_x != -1) {
|
||||||
|
/* Cannot set window x,y at creation time,
|
||||||
|
we must move the window now instead */
|
||||||
|
XMoveWindow(XtDisplay(wp->popup), XtWindow(wp->popup),
|
||||||
|
menu_info->permi_x, menu_info->permi_y);
|
||||||
|
}
|
||||||
|
/* cant use nh_XtPopup() because it may try to grab the focus */
|
||||||
|
XtPopup(wp->popup, (int) XtGrabNone);
|
||||||
|
if (permi && menu_info->permi_x == -1) {
|
||||||
|
/* remember perm_invent window geometry the first time */
|
||||||
|
get_widget_window_geometry(wp->popup,
|
||||||
|
&menu_info->permi_x,
|
||||||
|
&menu_info->permi_y,
|
||||||
|
&menu_info->permi_w,
|
||||||
|
&menu_info->permi_h);
|
||||||
|
}
|
||||||
|
if (!updated_inventory) {
|
||||||
|
XMapRaised(XtDisplay(wp->popup), XtWindow(wp->popup));
|
||||||
|
}
|
||||||
|
XSetWMProtocols(XtDisplay(wp->popup), XtWindow(wp->popup),
|
||||||
|
&wm_delete_window, 1);
|
||||||
|
retval = 0;
|
||||||
|
} else {
|
||||||
|
menu_info->is_active = TRUE; /* waiting for user response */
|
||||||
|
menu_info->cancelled = FALSE;
|
||||||
|
nh_XtPopup(wp->popup, (int) XtGrabExclusive, wp->w);
|
||||||
|
(void) x_event(EXIT_ON_EXIT);
|
||||||
|
menu_info->is_active = FALSE;
|
||||||
|
if (menu_info->cancelled)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
for (curr = menu_info->curr_menu.base; curr; curr = curr->next)
|
||||||
|
if (curr->selected)
|
||||||
|
retval++;
|
||||||
|
|
||||||
|
if (retval) {
|
||||||
|
menu_item *mi;
|
||||||
|
boolean toomany = (how == PICK_ONE && retval > 1);
|
||||||
|
|
||||||
|
if (toomany)
|
||||||
|
retval = 1;
|
||||||
|
*menu_list = mi = (menu_item *) alloc(retval * sizeof(menu_item));
|
||||||
|
for (curr = menu_info->curr_menu.base; curr; curr = curr->next)
|
||||||
|
if (curr->selected) {
|
||||||
|
mi->item = curr->identifier;
|
||||||
|
mi->count = curr->pick_count;
|
||||||
|
if (!toomany)
|
||||||
|
mi++;
|
||||||
|
if (how == PICK_ONE && !curr->preselected)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /* ?(WIN_INVEN && PICK_NONE) */
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End global functions =================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a copy of the given string. If null, return a string of
|
||||||
|
* zero length.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
copy_of(s)
|
||||||
|
const char *s;
|
||||||
|
{
|
||||||
|
if (!s)
|
||||||
|
s = "";
|
||||||
|
return dupstr(s);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create ok, cancel, all, none, invert, and search buttons.
|
* Create ok, cancel, all, none, invert, and search buttons.
|
||||||
*/
|
*/
|
||||||
Widget
|
static Widget
|
||||||
menu_create_buttons(wp, form, under)
|
menu_create_buttons(wp, form, under)
|
||||||
struct xwindow *wp;
|
struct xwindow *wp;
|
||||||
Widget form,under;
|
Widget form,under;
|
||||||
@@ -778,7 +1121,7 @@ Widget form,under;
|
|||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
load_boldfont(wp, w)
|
load_boldfont(wp, w)
|
||||||
struct xwindow *wp;
|
struct xwindow *wp;
|
||||||
Widget w;
|
Widget w;
|
||||||
@@ -803,7 +1146,7 @@ Widget w;
|
|||||||
wp->menu_information->boldfs = XLoadQueryFont(dpy, fontname);
|
wp->menu_information->boldfs = XLoadQueryFont(dpy, fontname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
menu_create_entries(wp, curr_menu)
|
menu_create_entries(wp, curr_menu)
|
||||||
struct xwindow *wp;
|
struct xwindow *wp;
|
||||||
struct menu *curr_menu;
|
struct menu *curr_menu;
|
||||||
@@ -858,20 +1201,21 @@ struct menu *curr_menu;
|
|||||||
}
|
}
|
||||||
|
|
||||||
XtSetArg(args[num_args], XtNtranslations,
|
XtSetArg(args[num_args], XtNtranslations,
|
||||||
XtParseTranslationTable(menu_entry_translations)); num_args++;
|
menu_entry_translation_table); num_args++;
|
||||||
|
|
||||||
menulineidx++;
|
menulineidx++;
|
||||||
Sprintf(tmpbuf, "menuline_%s", (canpick) ? "command" : "label");
|
Sprintf(tmpbuf, "menuline_%s", (canpick) ? "command" : "label");
|
||||||
curr->w = linewidget
|
curr->w = linewidget = XtCreateManagedWidget(tmpbuf,
|
||||||
= XtCreateManagedWidget(tmpbuf,
|
canpick
|
||||||
canpick ? commandWidgetClass
|
? commandWidgetClass
|
||||||
: labelWidgetClass,
|
: labelWidgetClass,
|
||||||
wp->w, args, num_args);
|
wp->w, args, num_args);
|
||||||
|
|
||||||
if (attr == ATR_BOLD) {
|
if (attr == ATR_BOLD) {
|
||||||
load_boldfont(wp, curr->w);
|
load_boldfont(wp, curr->w);
|
||||||
num_args = 0;
|
num_args = 0;
|
||||||
XtSetArg(args[num_args], nhStr(XtNfont), wp->menu_information->boldfs); num_args++;
|
XtSetArg(args[num_args], nhStr(XtNfont),
|
||||||
|
wp->menu_information->boldfs); num_args++;
|
||||||
XtSetValues(curr->w, args, num_args);
|
XtSetValues(curr->w, args, num_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,272 +1226,29 @@ struct menu *curr_menu;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static void
|
||||||
X11_select_menu(window, how, menu_list)
|
destroy_menu_entry_widgets(wp)
|
||||||
winid window;
|
struct xwindow *wp;
|
||||||
int how;
|
|
||||||
menu_item **menu_list;
|
|
||||||
{
|
{
|
||||||
x11_menu_item *curr;
|
WidgetList wlist;
|
||||||
struct xwindow *wp;
|
Cardinal numchild;
|
||||||
struct menu_info_t *menu_info;
|
Arg args[5];
|
||||||
Arg args[10];
|
|
||||||
Cardinal num_args;
|
Cardinal num_args;
|
||||||
int retval;
|
x11_menu_item *curr;
|
||||||
Dimension v_pixel_width, v_pixel_height;
|
struct menu_info_t *menu_info;
|
||||||
boolean labeled;
|
|
||||||
Widget viewport_widget, form, label, all;
|
if (!wp || !wp->w)
|
||||||
char gacc[QBUFSZ], *ap;
|
return;
|
||||||
boolean permi;
|
|
||||||
|
|
||||||
*menu_list = (menu_item *) 0;
|
|
||||||
check_winid(window);
|
|
||||||
wp = &window_list[window];
|
|
||||||
menu_info = wp->menu_information;
|
menu_info = wp->menu_information;
|
||||||
if (!menu_info->is_menu) {
|
|
||||||
impossible("select_menu: called before start_menu");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
debugpline2("X11_select_menu(%i, %i)", window, how);
|
|
||||||
|
|
||||||
menu_info->how = (short) how;
|
|
||||||
|
|
||||||
/* collect group accelerators; for PICK_NONE, they're ignored;
|
|
||||||
for PICK_ONE, only those which match exactly one entry will be
|
|
||||||
accepted; for PICK_ANY, those which match any entry are okay */
|
|
||||||
gacc[0] = '\0';
|
|
||||||
if (menu_info->how != PICK_NONE) {
|
|
||||||
int i, n, gcnt[128];
|
|
||||||
#define GSELIDX(c) ((c) & 127) /* guard against `signed char' */
|
|
||||||
|
|
||||||
for (i = 0; i < SIZE(gcnt); i++)
|
|
||||||
gcnt[i] = 0;
|
|
||||||
for (n = 0, curr = menu_info->new_menu.base; curr; curr = curr->next)
|
|
||||||
if (curr->gselector && curr->gselector != curr->selector) {
|
|
||||||
++n;
|
|
||||||
++gcnt[GSELIDX(curr->gselector)];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n > 0) /* at least one group accelerator found */
|
|
||||||
for (ap = gacc, curr = menu_info->new_menu.base; curr;
|
|
||||||
curr = curr->next)
|
|
||||||
if (curr->gselector && !index(gacc, curr->gselector)
|
|
||||||
&& (menu_info->how == PICK_ANY
|
|
||||||
|| gcnt[GSELIDX(curr->gselector)] == 1)) {
|
|
||||||
*ap++ = curr->gselector;
|
|
||||||
*ap = '\0'; /* re-terminate for index() */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
menu_info->new_menu.gacc = copy_of(gacc);
|
|
||||||
reset_menu_count(menu_info);
|
|
||||||
|
|
||||||
labeled = (menu_info->new_menu.query && *(menu_info->new_menu.query))
|
|
||||||
? TRUE
|
|
||||||
: FALSE;
|
|
||||||
|
|
||||||
permi = (window == WIN_INVEN && iflags.perm_invent && how == PICK_NONE);
|
|
||||||
|
|
||||||
if (menu_info->is_up) {
|
|
||||||
if (!menu_info->permi) {
|
|
||||||
nh_XtPopdown(wp->popup);
|
|
||||||
XtDestroyWidget(wp->popup);
|
|
||||||
wp->w = wp->popup = (Widget) 0;
|
|
||||||
menu_info->is_up = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!menu_info->is_up) {
|
|
||||||
menu_info->permi = permi;
|
|
||||||
|
|
||||||
num_args = 0;
|
|
||||||
XtSetArg(args[num_args], XtNallowShellResize, True);
|
|
||||||
num_args++;
|
|
||||||
if (permi && menu_info->permi_x != -1) {
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNwidth), menu_info->permi_w);
|
|
||||||
num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNheight), menu_info->permi_h);
|
|
||||||
num_args++;
|
|
||||||
}
|
|
||||||
wp->popup = XtCreatePopupShell((window == WIN_INVEN)
|
|
||||||
? "inventory" : "menu",
|
|
||||||
(how == PICK_NONE)
|
|
||||||
? topLevelShellWidgetClass
|
|
||||||
: transientShellWidgetClass,
|
|
||||||
toplevel, args, num_args);
|
|
||||||
XtOverrideTranslations(wp->popup,
|
|
||||||
XtParseTranslationTable(
|
|
||||||
"<Message>WM_PROTOCOLS: menu_delete()"));
|
|
||||||
|
|
||||||
num_args = 0;
|
|
||||||
XtSetArg(args[num_args], XtNtranslations,
|
|
||||||
XtParseTranslationTable(menu_translations)); num_args++;
|
|
||||||
form = XtCreateManagedWidget("mform", formWidgetClass, wp->popup,
|
|
||||||
args, num_args);
|
|
||||||
|
|
||||||
num_args = 0;
|
|
||||||
XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++;
|
|
||||||
|
|
||||||
label = labeled ? XtCreateManagedWidget(menu_info->new_menu.query,
|
|
||||||
labelWidgetClass, form,
|
|
||||||
args, num_args)
|
|
||||||
: (Widget) 0;
|
|
||||||
|
|
||||||
all = menu_create_buttons(wp, form, label);
|
|
||||||
|
|
||||||
num_args = 0;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNallowVert), True); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNallowHoriz), False); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNuseBottom), True); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNuseRight), True); num_args++;
|
|
||||||
#if 0
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNforceBars), True); num_args++;
|
|
||||||
#endif
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNfromVert), all); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNbottom), XtChainBottom); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++;
|
|
||||||
XtSetArg(args[num_args], nhStr(XtNright), XtChainRight); num_args++;
|
|
||||||
XtSetArg(args[num_args], XtNtranslations,
|
|
||||||
XtParseTranslationTable(menu_translations)); num_args++;
|
|
||||||
viewport_widget = XtCreateManagedWidget(
|
|
||||||
"menu_viewport", /* name */
|
|
||||||
viewportWidgetClass, form, /* parent widget */
|
|
||||||
args, num_args); /* values, and number of values */
|
|
||||||
|
|
||||||
num_args = 0;
|
|
||||||
XtSetArg(args[num_args], XtNwidth, 100);
|
|
||||||
num_args++;
|
|
||||||
XtSetArg(args[num_args], XtNheight, 500);
|
|
||||||
num_args++;
|
|
||||||
|
|
||||||
wp->w = XtCreateManagedWidget("menu_list", formWidgetClass,
|
|
||||||
viewport_widget, args, num_args);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menu_info->is_up && permi && menu_info->curr_menu.base) {
|
|
||||||
/* perm_invent window - explicitly destroy old menu entry widgets,
|
|
||||||
without recreating whole window */
|
|
||||||
WidgetList wlist;
|
|
||||||
Cardinal numchild;
|
|
||||||
num_args = 0;
|
|
||||||
XtSetArg(args[num_args], XtNchildren, &wlist); num_args++;
|
|
||||||
XtSetArg(args[num_args], XtNnumChildren, &numchild); num_args++;
|
|
||||||
XtGetValues(wp->w, args, num_args);
|
|
||||||
XtUnmanageChildren(wlist, numchild);
|
|
||||||
for (curr = menu_info->curr_menu.base; curr; curr = curr->next)
|
|
||||||
if (curr->w)
|
|
||||||
XtDestroyWidget(curr->w);
|
|
||||||
free_menu_line_entries(&menu_info->curr_menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make new menu the current menu */
|
|
||||||
move_menu(&menu_info->new_menu, &menu_info->curr_menu);
|
|
||||||
menu_create_entries(wp, &menu_info->curr_menu);
|
|
||||||
|
|
||||||
/* if viewport will be bigger than the screen, limit its height */
|
|
||||||
num_args = 0;
|
num_args = 0;
|
||||||
XtSetArg(args[num_args], XtNwidth, &v_pixel_width); num_args++;
|
XtSetArg(args[num_args], XtNchildren, &wlist); num_args++;
|
||||||
XtSetArg(args[num_args], XtNheight, &v_pixel_height); num_args++;
|
XtSetArg(args[num_args], XtNnumChildren, &numchild); num_args++;
|
||||||
XtGetValues(wp->w, args, num_args);
|
XtGetValues(wp->w, args, num_args);
|
||||||
if ((Dimension) XtScreen(wp->w)->height * 5 / 6 < v_pixel_height) {
|
XtUnmanageChildren(wlist, numchild);
|
||||||
/* scrollbar is 14 pixels wide. Widen the form to accommodate it. */
|
for (curr = menu_info->curr_menu.base; curr; curr = curr->next)
|
||||||
v_pixel_width += 14;
|
if (curr->w)
|
||||||
|
XtDestroyWidget(curr->w);
|
||||||
/* shrink to fit vertically */
|
|
||||||
v_pixel_height = XtScreen(wp->w)->height * 5 / 6;
|
|
||||||
|
|
||||||
num_args = 0;
|
|
||||||
XtSetArg(args[num_args], XtNwidth, v_pixel_width); num_args++;
|
|
||||||
XtSetArg(args[num_args], XtNheight, v_pixel_height); num_args++;
|
|
||||||
XtSetValues(wp->w, args, num_args);
|
|
||||||
}
|
|
||||||
XtRealizeWidget(wp->popup); /* need to realize before we position */
|
|
||||||
|
|
||||||
/* if menu is not up, position it */
|
|
||||||
if (!menu_info->is_up) {
|
|
||||||
positionpopup(wp->popup, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
menu_info->is_up = TRUE;
|
|
||||||
if (permi) {
|
|
||||||
if (permi && menu_info->permi_x != -1) {
|
|
||||||
/* Cannot set window x,y at creation time,
|
|
||||||
we must move the window now instead */
|
|
||||||
XMoveWindow(XtDisplay(wp->popup), XtWindow(wp->popup),
|
|
||||||
menu_info->permi_x, menu_info->permi_y);
|
|
||||||
}
|
|
||||||
/* cant use nh_XtPopup() because it may try to grab the focus */
|
|
||||||
XtPopup(wp->popup, (int) XtGrabNone);
|
|
||||||
if (permi && menu_info->permi_x == -1) {
|
|
||||||
/* remember perm_invent window geometry the first time */
|
|
||||||
get_widget_window_geometry(wp->popup,
|
|
||||||
&menu_info->permi_x,
|
|
||||||
&menu_info->permi_y,
|
|
||||||
&menu_info->permi_w,
|
|
||||||
&menu_info->permi_h);
|
|
||||||
}
|
|
||||||
if (!updated_inventory) {
|
|
||||||
XMapRaised(XtDisplay(wp->popup), XtWindow(wp->popup));
|
|
||||||
}
|
|
||||||
XSetWMProtocols(XtDisplay(wp->popup), XtWindow(wp->popup),
|
|
||||||
&wm_delete_window, 1);
|
|
||||||
retval = 0;
|
|
||||||
} else {
|
|
||||||
menu_info->is_active = TRUE; /* waiting for user response */
|
|
||||||
menu_info->cancelled = FALSE;
|
|
||||||
nh_XtPopup(wp->popup, (int) XtGrabExclusive, wp->w);
|
|
||||||
(void) x_event(EXIT_ON_EXIT);
|
|
||||||
menu_info->is_active = FALSE;
|
|
||||||
if (menu_info->cancelled)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
retval = 0;
|
|
||||||
for (curr = menu_info->curr_menu.base; curr; curr = curr->next)
|
|
||||||
if (curr->selected)
|
|
||||||
retval++;
|
|
||||||
|
|
||||||
if (retval) {
|
|
||||||
menu_item *mi;
|
|
||||||
boolean toomany = (how == PICK_ONE && retval > 1);
|
|
||||||
|
|
||||||
if (toomany)
|
|
||||||
retval = 1;
|
|
||||||
*menu_list = mi = (menu_item *) alloc(retval * sizeof(menu_item));
|
|
||||||
for (curr = menu_info->curr_menu.base; curr; curr = curr->next)
|
|
||||||
if (curr->selected) {
|
|
||||||
mi->item = curr->identifier;
|
|
||||||
mi->count = curr->pick_count;
|
|
||||||
if (!toomany)
|
|
||||||
mi++;
|
|
||||||
if (how == PICK_ONE && !curr->preselected)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* ?(WIN_INVEN && PICK_NONE) */
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* End global functions ====================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a copy of the given string. If null, return a string of
|
|
||||||
* zero length.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
copy_of(s)
|
|
||||||
const char *s;
|
|
||||||
{
|
|
||||||
if (!s)
|
|
||||||
s = "";
|
|
||||||
return dupstr(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1325,7 +1426,8 @@ struct xwindow *wp;
|
|||||||
{
|
{
|
||||||
clear_old_menu(wp); /* this will also destroy the widgets */
|
clear_old_menu(wp); /* this will also destroy the widgets */
|
||||||
if (wp->menu_information->boldfs)
|
if (wp->menu_information->boldfs)
|
||||||
XFreeFont(wp->menu_information->boldfs_dpy, wp->menu_information->boldfs);
|
XFreeFont(wp->menu_information->boldfs_dpy,
|
||||||
|
wp->menu_information->boldfs);
|
||||||
free((genericptr_t) wp->menu_information);
|
free((genericptr_t) wp->menu_information);
|
||||||
wp->menu_information = (struct menu_info_t *) 0;
|
wp->menu_information = (struct menu_info_t *) 0;
|
||||||
wp->type = NHW_NONE; /* allow re-use */
|
wp->type = NHW_NONE; /* allow re-use */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 winmisc.c $NHDT-Date: 1457079197 2016/03/04 08:13:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.25 $ */
|
/* NetHack 3.6 winmisc.c $NHDT-Date: 1539892610 2018/10/18 19:56:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.39 $ */
|
||||||
/* Copyright (c) Dean Luick, 1992 */
|
/* Copyright (c) Dean Luick, 1992 */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -71,6 +71,8 @@ static const char extended_command_translations[] = "#override\n\
|
|||||||
<Key>Right: scroll(6)\n\
|
<Key>Right: scroll(6)\n\
|
||||||
<Key>Up: scroll(8)\n\
|
<Key>Up: scroll(8)\n\
|
||||||
<Key>Down: scroll(2)\n\
|
<Key>Down: scroll(2)\n\
|
||||||
|
<Btn4Down>: scroll(8)\n\
|
||||||
|
<Btn5Down>: scroll(2)\n\
|
||||||
<Key>: ec_key()";
|
<Key>: ec_key()";
|
||||||
|
|
||||||
static const char player_select_translations[] = "#override\n\
|
static const char player_select_translations[] = "#override\n\
|
||||||
@@ -82,6 +84,10 @@ static const char gend_select_translations[] = "#override\n\
|
|||||||
static const char algn_select_translations[] = "#override\n\
|
static const char algn_select_translations[] = "#override\n\
|
||||||
<Key>: algn_key()";
|
<Key>: algn_key()";
|
||||||
|
|
||||||
|
static const char popup_entry_translations[] = "#override\n\
|
||||||
|
<Btn4Down>: scroll(8)\n\
|
||||||
|
<Btn5Down>: scroll(2)";
|
||||||
|
|
||||||
static void FDECL(ps_quit, (Widget, XtPointer, XtPointer));
|
static void FDECL(ps_quit, (Widget, XtPointer, XtPointer));
|
||||||
static void FDECL(ps_random, (Widget, XtPointer, XtPointer));
|
static void FDECL(ps_random, (Widget, XtPointer, XtPointer));
|
||||||
static void FDECL(ps_select, (Widget, XtPointer, XtPointer));
|
static void FDECL(ps_select, (Widget, XtPointer, XtPointer));
|
||||||
@@ -114,8 +120,7 @@ XtPointer x;
|
|||||||
return (long)x;
|
return (long)x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Player Selection --------------------------------------------------------
|
/* Player Selection ------------------------------------------------------- */
|
||||||
*/
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
ps_quit(w, client_data, call_data)
|
ps_quit(w, client_data, call_data)
|
||||||
@@ -1237,12 +1242,15 @@ X11_player_selection_dialog()
|
|||||||
XtRealizeWidget(popup);
|
XtRealizeWidget(popup);
|
||||||
X11_player_selection_randomize();
|
X11_player_selection_randomize();
|
||||||
|
|
||||||
ps_selected = -1;
|
if (flags.randomall) {
|
||||||
|
plsel_dialog_acceptvalues();
|
||||||
nh_XtPopup(popup, (int) XtGrabExclusive, form);
|
} else {
|
||||||
|
ps_selected = -1;
|
||||||
|
nh_XtPopup(popup, (int) XtGrabExclusive, form);
|
||||||
|
}
|
||||||
|
|
||||||
/* The callback will enable the event loop exit. */
|
/* The callback will enable the event loop exit. */
|
||||||
(void) x_event(EXIT_ON_EXIT);
|
(void) x_event(flags.randomall ? EXIT_ON_SENT_EVENT : EXIT_ON_EXIT);
|
||||||
|
|
||||||
nh_XtPopdown(popup);
|
nh_XtPopdown(popup);
|
||||||
XtDestroyWidget(popup);
|
XtDestroyWidget(popup);
|
||||||
@@ -1266,8 +1274,7 @@ X11_player_selection_dialog()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global functions =========================================================
|
/* Global functions ======================================================== */
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
X11_player_selection_prompts()
|
X11_player_selection_prompts()
|
||||||
{
|
{
|
||||||
@@ -1603,11 +1610,9 @@ release_extended_cmds()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End global functions =====================================================
|
/* End global functions =================================================== */
|
||||||
*/
|
|
||||||
|
|
||||||
/* Extended Command --------------------------------------------------------
|
/* Extended Command ------------------------------------------------------- */
|
||||||
*/
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
extend_select(w, client_data, call_data)
|
extend_select(w, client_data, call_data)
|
||||||
@@ -1948,8 +1953,7 @@ init_extended_commands_popup()
|
|||||||
free((char *) command_list);
|
free((char *) command_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------ */
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a popup widget of the following form:
|
* Create a popup widget of the following form:
|
||||||
@@ -1987,7 +1991,7 @@ Widget **command_widgets;
|
|||||||
XtCallbackProc name_callback;
|
XtCallbackProc name_callback;
|
||||||
Widget *formp; /* return */
|
Widget *formp; /* return */
|
||||||
{
|
{
|
||||||
Widget popup, form, label, above, left, right, view;
|
Widget popup, popform, form, label, above, left, right, view;
|
||||||
Widget *commands, *curr;
|
Widget *commands, *curr;
|
||||||
int i;
|
int i;
|
||||||
Arg args[8];
|
Arg args[8];
|
||||||
@@ -2000,22 +2004,41 @@ Widget *formp; /* return */
|
|||||||
|
|
||||||
num_args = 0;
|
num_args = 0;
|
||||||
XtSetArg(args[num_args], XtNallowShellResize, True); num_args++;
|
XtSetArg(args[num_args], XtNallowShellResize, True); num_args++;
|
||||||
|
XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
|
||||||
popup = XtCreatePopupShell(popup_name, transientShellWidgetClass,
|
popup = XtCreatePopupShell(popup_name, transientShellWidgetClass,
|
||||||
toplevel, args, num_args);
|
toplevel, args, num_args);
|
||||||
XtOverrideTranslations(
|
XtOverrideTranslations(
|
||||||
popup, XtParseTranslationTable("<Message>WM_PROTOCOLS: ec_delete()"));
|
popup, XtParseTranslationTable("<Message>WM_PROTOCOLS: ec_delete()"));
|
||||||
|
|
||||||
num_args = 0;
|
num_args = 0;
|
||||||
XtSetArg(args[num_args], XtNforceBars, False); num_args++;
|
|
||||||
XtSetArg(args[num_args], XtNallowVert, True); num_args++;
|
|
||||||
XtSetArg(args[num_args], XtNtranslations,
|
XtSetArg(args[num_args], XtNtranslations,
|
||||||
XtParseTranslationTable(popup_translations)); num_args++;
|
XtParseTranslationTable(popup_translations)); num_args++;
|
||||||
view = XtCreateManagedWidget("menuformview", viewportWidgetClass, popup,
|
XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNdefaultDistance), 0); num_args++;
|
||||||
|
popform = XtCreateManagedWidget("topmenuform", formWidgetClass, popup,
|
||||||
|
args, num_args);
|
||||||
|
|
||||||
|
|
||||||
|
num_args = 0;
|
||||||
|
XtSetArg(args[num_args], XtNforceBars, False); num_args++;
|
||||||
|
XtSetArg(args[num_args], XtNallowVert, True); num_args++;
|
||||||
|
/*XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;*/
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNuseBottom), True); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNuseRight), True); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNbottom), XtChainBottom); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNright), XtChainRight); num_args++;
|
||||||
|
XtSetArg(args[num_args], XtNtranslations,
|
||||||
|
XtParseTranslationTable(popup_translations)); num_args++;
|
||||||
|
view = XtCreateManagedWidget("menuformview", viewportWidgetClass, popform,
|
||||||
args, num_args);
|
args, num_args);
|
||||||
|
|
||||||
num_args = 0;
|
num_args = 0;
|
||||||
XtSetArg(args[num_args], XtNtranslations,
|
XtSetArg(args[num_args], XtNtranslations,
|
||||||
XtParseTranslationTable(popup_translations)); num_args++;
|
XtParseTranslationTable(popup_translations)); num_args++;
|
||||||
|
XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
|
||||||
|
XtSetArg(args[num_args], nhStr(XtNdefaultDistance), 0); num_args++;
|
||||||
*formp = form = XtCreateManagedWidget("menuform", formWidgetClass, view,
|
*formp = form = XtCreateManagedWidget("menuform", formWidgetClass, view,
|
||||||
args, num_args);
|
args, num_args);
|
||||||
|
|
||||||
@@ -2089,6 +2112,8 @@ Widget *formp; /* return */
|
|||||||
if (!widget_names[i])
|
if (!widget_names[i])
|
||||||
continue;
|
continue;
|
||||||
num_args = 0;
|
num_args = 0;
|
||||||
|
XtSetArg(args[num_args], XtNtranslations,
|
||||||
|
XtParseTranslationTable(popup_entry_translations)); num_args++;
|
||||||
XtSetArg(args[num_args], nhStr(XtNfromVert), above); num_args++;
|
XtSetArg(args[num_args], nhStr(XtNfromVert), above); num_args++;
|
||||||
if (above == left) {
|
if (above == left) {
|
||||||
/* if first, we are farther apart */
|
/* if first, we are farther apart */
|
||||||
|
|||||||
Reference in New Issue
Block a user