diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 293447b3e..bf9cc0be9 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -164,6 +164,7 @@ MacOSX: force TIMED_DELAY build option on so that 'runmode' run-time option X11: core bug for '`' (backtick) and #terrain commands was only noticed by X11 interface: impossible "add_menu: called before start_menu" X11: enable a scroll bar in menu windows +X11: support pre-selected entries in menu windows X11: make the extended command menu be easier to use and look a little nicer X11: make the getline text entry widget display a bigger text entry area diff --git a/include/winX.h b/include/winX.h index e462dfe94..dcd588d6f 100644 --- a/include/winX.h +++ b/include/winX.h @@ -1,5 +1,5 @@ /* NetHack 3.6 winX.h $NHDT-Date: 1453447524 2016/01/22 07:25:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.19 $ */ -/* Copyright (c) Dean Luick, 1992 */ +/* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ /* @@ -52,7 +52,7 @@ struct text_map_info_t { int square_width, /* Saved font information so */ square_height, /* we can calculate the correct */ - square_ascent, /* placement of changes. */ + square_ascent, /* placement of changes. */ square_lbearing; }; @@ -70,7 +70,7 @@ struct tile_map_info_t { int square_width, /* Saved tile information so */ square_height, /* we can calculate the correct */ - square_ascent, /* placement of changes. */ + square_ascent, /* placement of changes. */ square_lbearing; }; @@ -101,16 +101,16 @@ struct mesg_info_t { struct line_element *head; /* head of circular line queue */ struct line_element *line_here; /* current drawn line position */ struct line_element *last_pause; /* point to the line after the prev */ - /* bottom of screen */ + /* bottom of screen */ struct line_element *last_pause_head; /* pointer to head of previous */ - /* turn */ + /* turn */ GC gc; /* GC for text drawing */ int char_width, /* Saved font information so we can */ char_height, /* calculate the correct placement */ - char_ascent, /* of changes. */ + char_ascent, /* of changes. */ char_lbearing; - Dimension viewport_width, /* Saved viewport size, so we can adjust */ - viewport_height; /* the slider on a resize. */ + Dimension viewport_width, /* Saved viewport size, so we can adjust */ + viewport_height; /* the slider on a resize. */ Boolean dirty; /* Lines have been added to the window. */ }; @@ -132,6 +132,7 @@ typedef struct x11_mi { char *str; /* The text of the item. */ int attr; /* Attribute for the line. */ boolean selected; /* Been selected? */ + boolean preselected; /* in advance? */ char selector; /* Char used to select this entry. */ char gselector; /* Group selector. */ } x11_menu_item; @@ -145,7 +146,7 @@ struct menu { String *list_pointer; /* String list. */ Boolean *sensitive; /* Active list. */ char curr_selector; /* Next keyboard accelerator to assign, */ - /* if 0, then we're out. */ + /* if 0, then we're out. */ }; struct menu_info_t { @@ -213,19 +214,19 @@ struct xwindow { #define MAX_WINDOWS 20 /* max number of open windows */ -#define NHW_NONE 0 /* Unallocated window type. Must be */ -/* different from any other NHW_* type. */ +#define NHW_NONE 0 /* Unallocated window type. Must be */ + /* different from any other NHW_* type. */ #define NO_CLICK 0 /* No click occurred on the map window. Must */ -/* be different than CLICK_1 and CLICK_2. */ + /* be different than CLICK_1 and CLICK_2. */ #define DEFAULT_MESSAGE_WIDTH 60 /* width in chars of the message window */ -#define DISPLAY_FILE_SIZE 35 /* Max number of lines in the default */ -/* file display window. */ +#define DISPLAY_FILE_SIZE 35 /* Max number of lines in the default */ + /* file display window. */ #define MAX_KEY_STRING 64 /* String size for converting a keypress */ -/* event into a character(s) */ + /* event into a character(s) */ #define DEFAULT_LINES_DISPLAYED 12 /* # of lines displayed message window */ #define MAX_HISTORY 60 /* max history saved on message window */ diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 8fe7baec3..97f8592a4 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -41,8 +41,7 @@ #include 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_cancel, (Widget, XtPointer, XtPointer)); static void FDECL(menu_all, (Widget, XtPointer, XtPointer)); @@ -130,7 +129,9 @@ XtPointer client_data, call_data; } /* if we've reached here, we've found our selected item */ - curr->selected = !curr->selected; + if (menu_info->how != PICK_ONE || !curr->preselected) + curr->selected = !curr->selected; + curr->preselected = FALSE; if (curr->selected) { curr->str[2] = (how_many != -1L) ? '#' : '+'; curr->pick_count = how_many; @@ -178,7 +179,11 @@ long how_many; nhUse(which); #endif reset_menu_count(wp->menu_information); - curr->selected = !curr->selected; + /* invert selection unless explicitly choosing the preselected + entry of a PICK_ONE menu */ + if (wp->menu_information->how != PICK_ONE || !curr->preselected) + curr->selected = !curr->selected; + curr->preselected = FALSE; if (curr->selected) { #ifdef USE_FWF XfwfMultiListHighlightItem((XfwfMultiListWidget) wp->w, which); @@ -326,9 +331,8 @@ Cardinal *num_params; break; if (curr) { - invert_line(wp, curr, count, menu_info->counting - ? menu_info->menu_count - : -1L); + invert_line(wp, curr, count, + menu_info->counting ? menu_info->menu_count : -1L); #ifndef USE_FWF XawListChange(wp->w, menu_info->curr_menu.list_pointer, 0, 0, True); @@ -468,8 +472,8 @@ struct xwindow *wp; #ifndef USE_FWF if (changed) - XawListChange(wp->w, wp->menu_information->curr_menu.list_pointer, 0, - 0, True); + XawListChange(wp->w, wp->menu_information->curr_menu.list_pointer, + 0, 0, True); #endif } @@ -492,8 +496,8 @@ struct xwindow *wp; #ifndef USE_FWF if (changed) - XawListChange(wp->w, wp->menu_information->curr_menu.list_pointer, 0, - 0, True); + XawListChange(wp->w, wp->menu_information->curr_menu.list_pointer, + 0, 0, True); #endif } @@ -511,8 +515,8 @@ struct xwindow *wp; invert_line(wp, curr, count, -1L); #ifndef USE_FWF - XawListChange(wp->w, wp->menu_information->curr_menu.list_pointer, 0, 0, - True); + XawListChange(wp->w, wp->menu_information->curr_menu.list_pointer, + 0, 0, True); #endif } @@ -528,15 +532,18 @@ char *match; /* wildcard pattern for pmatch() */ reset_menu_count(wp->menu_information); for (count = 0, curr = wp->menu_information->curr_menu.base; curr; curr = curr->next, count++) - if (curr->identifier.a_void != 0 && pmatchi(match, curr->str)) { - invert_line(wp, curr, count, -1L); - changed = TRUE; + if (curr->identifier.a_void != 0) { + if (pmatchi(match, curr->str)) { + invert_line(wp, curr, count, -1L); + changed = TRUE; + } + curr->preselected = FALSE; } #ifndef USE_FWF if (changed) - XawListChange(wp->w, wp->menu_information->curr_menu.list_pointer, 0, - 0, True); + XawListChange(wp->w, wp->menu_information->curr_menu.list_pointer, + 0, 0, True); #endif } @@ -545,26 +552,30 @@ select_match(wp, match) struct xwindow *wp; char *match; /* wildcard pattern for pmatch() */ { - x11_menu_item *curr; + x11_menu_item *curr, *found = 0; int count; reset_menu_count(wp->menu_information); for (count = 0, curr = wp->menu_information->curr_menu.base; curr; curr = curr->next, count++) - if (curr->identifier.a_void != 0 && pmatchi(match, curr->str)) { - if (!curr->selected) { - invert_line(wp, curr, count, -1L); -#ifndef USE_FWF - XawListChange(wp->w, - wp->menu_information->curr_menu.list_pointer, 0, - 0, True); -#endif - } - return; + if (curr->identifier.a_void != 0) { + if (!found && pmatchi(match, curr->str)) + found = curr; + curr->preselected = FALSE; } - /* no match */ - X11_nhbell(); + if (found) { + if (!found->selected) { + invert_line(wp, found, count, -1L); +#ifndef USE_FWF + XawListChange(wp->w, wp->menu_information->curr_menu.list_pointer, + 0, 0, True); +#endif + } + } else { + /* no match */ + X11_nhbell(); + } } static void @@ -610,6 +621,8 @@ int *items; printf("sync: selecting %s\n", curr->str); #endif curr->selected = found ? TRUE : FALSE; + /* once active selection takes place, preselection becomes history */ + curr->preselected = FALSE; } } #endif /* USE_FWF */ @@ -650,7 +663,6 @@ boolean preselected; struct menu_info_t *menu_info; nhUse(glyph); - nhUse(preselected); /*FIXME*/ check_winid(window); menu_info = window_list[window].menu_information; @@ -663,8 +675,7 @@ boolean preselected; item->next = (x11_menu_item *) 0; item->identifier = *identifier; item->attr = attr; - /* item->selected = preselected; */ - item->selected = FALSE; + item->selected = item->preselected = preselected; item->pick_count = -1L; if (identifier->a_void) { @@ -688,7 +699,7 @@ boolean preselected; impossible("Menu item too long (%d).", len); len = BUFSZ - 1; } - Sprintf(buf, "%c - ", ch ? ch : ' '); + Sprintf(buf, "%c %c ", ch ? ch : ' ', preselected ? '+' : '-'); (void) strncpy(buf + 4, str, len); buf[4 + len] = '\0'; item->str = copy_of(buf); @@ -828,58 +839,46 @@ menu_item **menu_list; num_args = 0; XtSetArg(args[num_args], XtNallowShellResize, True); num_args++; - wp->popup = - XtCreatePopupShell(window == WIN_INVEN ? "inventory" : "menu", - how == PICK_NONE ? topLevelShellWidgetClass - : transientShellWidgetClass, - toplevel, args, num_args); - XtOverrideTranslations( - wp->popup, - XtParseTranslationTable("WM_PROTOCOLS: menu_delete()")); + wp->popup = XtCreatePopupShell((window == WIN_INVEN) + ? "inventory" : "menu", + (how == PICK_NONE) + ? topLevelShellWidgetClass + : transientShellWidgetClass, + toplevel, args, num_args); + XtOverrideTranslations(wp->popup, + XtParseTranslationTable( + "WM_PROTOCOLS: menu_delete()")); num_args = 0; XtSetArg(args[num_args], XtNtranslations, - XtParseTranslationTable(menu_translations)); - num_args++; + 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++; + 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++; - if (labeled) - label = - XtCreateManagedWidget(menu_info->new_menu.query, - labelWidgetClass, form, args, num_args); - else - label = NULL; + label = labeled ? XtCreateManagedWidget(menu_info->new_menu.query, + labelWidgetClass, form, + args, num_args) + : (Widget) 0; /* * Create ok, cancel, all, none, invert, and search buttons.. */ maxlblwidth = 0; num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfromVert), label); - 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++; - ok = XtCreateManagedWidget("OK", commandWidgetClass, form, args, - num_args); + XtSetArg(args[num_args], nhStr(XtNfromVert), label); 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++; + ok = XtCreateManagedWidget("OK", commandWidgetClass, form, + args, num_args); XtAddCallback(ok, XtNcallback, menu_ok, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[0]); XtGetValues(lblwidget[0] = ok, args, ONE); @@ -887,20 +886,14 @@ menu_item **menu_list; maxlblwidth = lblwidth[0]; num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfromVert), label); - num_args++; - XtSetArg(args[num_args], nhStr(XtNfromHoriz), ok); - num_args++; + XtSetArg(args[num_args], nhStr(XtNfromVert), label); num_args++; + XtSetArg(args[num_args], nhStr(XtNfromHoriz), ok); num_args++; XtSetArg(args[num_args], nhStr(XtNsensitive), how != PICK_NONE); - 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++; + 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++; cancel = XtCreateManagedWidget("cancel", commandWidgetClass, form, args, num_args); XtAddCallback(cancel, XtNcallback, menu_cancel, (XtPointer) wp); @@ -911,22 +904,15 @@ menu_item **menu_list; sens = (how == PICK_ANY); num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfromVert), label); - num_args++; - XtSetArg(args[num_args], nhStr(XtNfromHoriz), cancel); - num_args++; - XtSetArg(args[num_args], nhStr(XtNsensitive), sens); - 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++; - all = XtCreateManagedWidget("all", commandWidgetClass, form, args, - num_args); + XtSetArg(args[num_args], nhStr(XtNfromVert), label); num_args++; + XtSetArg(args[num_args], nhStr(XtNfromHoriz), cancel); num_args++; + XtSetArg(args[num_args], nhStr(XtNsensitive), sens); 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++; + all = XtCreateManagedWidget("all", commandWidgetClass, form, + args, num_args); XtAddCallback(all, XtNcallback, menu_all, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[2]); XtGetValues(lblwidget[2] = all, args, ONE); @@ -934,22 +920,15 @@ menu_item **menu_list; maxlblwidth = lblwidth[2]; num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfromVert), label); - num_args++; - XtSetArg(args[num_args], nhStr(XtNfromHoriz), all); - num_args++; - XtSetArg(args[num_args], nhStr(XtNsensitive), sens); - 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++; - none = XtCreateManagedWidget("none", commandWidgetClass, form, args, - num_args); + XtSetArg(args[num_args], nhStr(XtNfromVert), label); num_args++; + XtSetArg(args[num_args], nhStr(XtNfromHoriz), all); num_args++; + XtSetArg(args[num_args], nhStr(XtNsensitive), sens); 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++; + none = XtCreateManagedWidget("none", commandWidgetClass, form, + args, num_args); XtAddCallback(none, XtNcallback, menu_none, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[3]); XtGetValues(lblwidget[3] = none, args, ONE); @@ -957,20 +936,13 @@ menu_item **menu_list; maxlblwidth = lblwidth[3]; num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfromVert), label); - num_args++; - XtSetArg(args[num_args], nhStr(XtNfromHoriz), none); - num_args++; - XtSetArg(args[num_args], nhStr(XtNsensitive), sens); - 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++; + XtSetArg(args[num_args], nhStr(XtNfromVert), label); num_args++; + XtSetArg(args[num_args], nhStr(XtNfromHoriz), none); num_args++; + XtSetArg(args[num_args], nhStr(XtNsensitive), sens); 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++; invert = XtCreateManagedWidget("invert", commandWidgetClass, form, args, num_args); XtAddCallback(invert, XtNcallback, menu_invert, (XtPointer) wp); @@ -980,20 +952,14 @@ menu_item **menu_list; maxlblwidth = lblwidth[4]; num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfromVert), label); - num_args++; - XtSetArg(args[num_args], nhStr(XtNfromHoriz), invert); - num_args++; + XtSetArg(args[num_args], nhStr(XtNfromVert), label); num_args++; + XtSetArg(args[num_args], nhStr(XtNfromHoriz), invert); num_args++; XtSetArg(args[num_args], nhStr(XtNsensitive), how != PICK_NONE); - 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++; + 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++; search = XtCreateManagedWidget("search", commandWidgetClass, form, args, num_args); XtAddCallback(search, XtNcallback, menu_search, (XtPointer) wp); @@ -1013,27 +979,18 @@ menu_item **menu_list; } 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++; + 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], 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++; viewport_widget = XtCreateManagedWidget( "menu_viewport", /* name */ viewportWidgetClass, form, /* parent widget */ @@ -1043,22 +1000,16 @@ menu_item **menu_list; move_menu(&menu_info->new_menu, &menu_info->curr_menu); num_args = 0; - XtSetArg(args[num_args], nhStr(XtNforceColumns), True); - num_args++; - XtSetArg(args[num_args], nhStr(XtNcolumnSpacing), 1); - num_args++; - XtSetArg(args[num_args], nhStr(XtNdefaultColumns), 1); - num_args++; + XtSetArg(args[num_args], nhStr(XtNforceColumns), True); num_args++; + XtSetArg(args[num_args], nhStr(XtNcolumnSpacing), 1); num_args++; + XtSetArg(args[num_args], nhStr(XtNdefaultColumns), 1); num_args++; XtSetArg(args[num_args], nhStr(XtNlist), - menu_info->curr_menu.list_pointer); - num_args++; + menu_info->curr_menu.list_pointer); num_args++; #ifdef USE_FWF XtSetArg(args[num_args], nhStr(XtNsensitiveArray), - menu_info->curr_menu.sensitive); - num_args++; + menu_info->curr_menu.sensitive); num_args++; XtSetArg(args[num_args], nhStr(XtNmaxSelectable), - menu_info->curr_menu.count); - num_args++; + menu_info->curr_menu.count); num_args++; #endif wp->w = XtCreateManagedWidget("menu_list", /* name */ #ifdef USE_FWF @@ -1074,16 +1025,13 @@ menu_item **menu_list; /* Get the font and margin information. */ num_args = 0; - XtSetArg(args[num_args], XtNfont, &menu_info->fs); - num_args++; + XtSetArg(args[num_args], XtNfont, &menu_info->fs); num_args++; XtSetArg(args[num_args], XtNinternalHeight, - &menu_info->internal_height); - num_args++; + &menu_info->internal_height); num_args++; XtSetArg(args[num_args], XtNinternalWidth, - &menu_info->internal_width); - num_args++; + &menu_info->internal_width); num_args++; XtSetArg(args[num_args], nhStr(XtNrowSpacing), &row_spacing); - num_args++; + num_args++; XtGetValues(wp->w, args, num_args); /* font height is ascent + descent */ @@ -1094,10 +1042,8 @@ menu_item **menu_list; menu_info->valid_widgets = TRUE; num_args = 0; - XtSetArg(args[num_args], XtNwidth, &v_pixel_width); - num_args++; - XtSetArg(args[num_args], XtNheight, &v_pixel_height); - num_args++; + 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); } else { Dimension len; @@ -1114,9 +1060,8 @@ menu_item **menu_list; /* add viewport internal border */ v_pixel_width += 2 * menu_info->internal_width; - v_pixel_height = - (2 * menu_info->internal_height) - + (menu_info->new_menu.count * menu_info->line_height); + v_pixel_height = (2 * menu_info->internal_height) + + (menu_info->new_menu.count * menu_info->line_height); /* make new menu the current menu */ move_menu(&menu_info->new_menu, &menu_info->curr_menu); @@ -1131,10 +1076,8 @@ menu_item **menu_list; /* 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++; + 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. */ @@ -1144,10 +1087,8 @@ menu_item **menu_list; 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++; + 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 */ @@ -1181,16 +1122,22 @@ menu_item **menu_list; 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; - mi++; + if (!toomany) + mi++; + if (how == PICK_ONE && !curr->preselected) + break; } } - } + } /* ?(WIN_INVEN && PICK_NONE) */ return retval; } @@ -1201,8 +1148,6 @@ menu_item **menu_list; /* * Allocate a copy of the given string. If null, return a string of * zero length. - * - * This is an exact duplicate of copy_of() in tty/wintty.c. */ static char * copy_of(s) @@ -1210,7 +1155,7 @@ const char *s; { if (!s) s = ""; - return strcpy((char *) alloc((unsigned) (strlen(s) + 1)), s); + return dupstr(s); } static void diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index d1d44d906..960577e14 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -38,11 +38,12 @@ static Widget extended_command_popup = 0; static Widget extended_command_form; static Widget *extended_commands = 0; -static int extended_command_selected; /* index of the selected command; */ +static int extended_cmd_selected; /* index of the selected command; */ static int ps_selected; /* index of selected role */ #define PS_RANDOM (-50) #define PS_QUIT (-75) -static const char ps_randchars[] = "*@"; +/* 'r' for random won't work for role but will for race, gender, alignment */ +static const char ps_randchars[] = "*@\n\rrR"; static const char ps_quitchars[] = "\033qQ"; #define EC_NCHARS 32 @@ -591,7 +592,7 @@ X11_get_ext_cmd() initialized = True; } - extended_command_selected = -1; /* reset selected value */ + extended_cmd_selected = -1; /* reset selected value */ positionpopup(extended_command_popup, FALSE); /* center on cursor */ nh_XtPopup(extended_command_popup, (int) XtGrabExclusive, @@ -600,7 +601,7 @@ X11_get_ext_cmd() /* The callbacks will enable the event loop exit. */ (void) x_event(EXIT_ON_EXIT); - return extended_command_selected; + return extended_cmd_selected; } /* End global functions ===================================================== @@ -619,19 +620,19 @@ XtPointer client_data, call_data; nhUse(w); nhUse(call_data); - if (extended_command_selected != selected) { + if (extended_cmd_selected != selected) { /* visibly deselect old one */ - if (extended_command_selected >= 0) - swap_fg_bg(extended_commands[extended_command_selected]); + if (extended_cmd_selected >= 0) + swap_fg_bg(extended_commands[extended_cmd_selected]); /* select new one */ swap_fg_bg(extended_commands[selected]); - extended_command_selected = selected; + extended_cmd_selected = selected; } nh_XtPopdown(extended_command_popup); /* reset colors while popped down */ - swap_fg_bg(extended_commands[extended_command_selected]); + swap_fg_bg(extended_commands[extended_cmd_selected]); ec_active = FALSE; exit_x_event = TRUE; /* leave event loop */ } @@ -699,9 +700,9 @@ static void ec_dismiss() { /* unselect while still visible */ - if (extended_command_selected >= 0) - swap_fg_bg(extended_commands[extended_command_selected]); - extended_command_selected = -1; /* dismiss */ + if (extended_cmd_selected >= 0) + swap_fg_bg(extended_commands[extended_cmd_selected]); + extended_cmd_selected = -1; /* dismiss */ nh_XtPopdown(extended_command_popup); ec_active = FALSE; exit_x_event = TRUE; /* leave event loop */ @@ -718,17 +719,17 @@ ec_scroll_to_view() float s_min, s_max; Position vh; /* viewport height */ - if (extended_command_selected < 0) + if (extended_cmd_selected < 0) return; /* get selected ext command label y position and height */ num_args = 0; XtSetArg(args[num_args], XtNy, &y); num_args++; XtSetArg(args[num_args], XtNheight, &h); num_args++; - XtGetValues(extended_commands[extended_command_selected], args, num_args); + XtGetValues(extended_commands[extended_cmd_selected], args, num_args); /* get viewport and scrollbar widgets */ - tmpw = extended_commands[extended_command_selected]; + tmpw = extended_commands[extended_cmd_selected]; viewport = XtParent(tmpw); do { tmpw = XtParent(tmpw); @@ -744,7 +745,7 @@ ec_scroll_to_view() /* get scrollbar "height" and "top" position; floats between 0-1 */ num_args = 0; XtSetArg(args[num_args], XtNshown, &s_shown); num_args++; - XtSetArg(args[num_args], XtNtopOfThumb, &s_top); num_args++; + XtSetArg(args[num_args], nhStr(XtNtopOfThumb), &s_top); num_args++; XtGetValues(scrollbar, args, num_args); s_min = s_top * vh; @@ -789,15 +790,15 @@ Cardinal *num_params; } else if (index("\033\n\r", ch)) { if (ch == '\033') { /* unselect while still visible */ - if (extended_command_selected >= 0) - swap_fg_bg(extended_commands[extended_command_selected]); - extended_command_selected = -1; /* dismiss */ + if (extended_cmd_selected >= 0) + swap_fg_bg(extended_commands[extended_cmd_selected]); + extended_cmd_selected = -1; /* dismiss */ } nh_XtPopdown(extended_command_popup); /* unselect while invisible */ - if (extended_command_selected >= 0) - swap_fg_bg(extended_commands[extended_command_selected]); + if (extended_cmd_selected >= 0) + swap_fg_bg(extended_commands[extended_cmd_selected]); exit_x_event = TRUE; /* leave event loop */ ec_active = FALSE; @@ -811,7 +812,7 @@ Cardinal *num_params; * ("ride" vs "rub", for instance), or player may just be typing in * the whole word. */ - if ((xkey->time - ec_time) > 2500) /* 2.5 seconds */ + if (ec_active && (xkey->time - ec_time) > 2500) /* 2.5 seconds */ ec_active = FALSE; if (!ec_active) { @@ -828,9 +829,9 @@ Cardinal *num_params; if (pass == 1) { /* first pass finished, but no matching command was found */ /* start a new one with the last char entered */ - if (extended_command_selected >= 0) - swap_fg_bg(extended_commands[extended_command_selected]); - extended_command_selected = -1; /* dismiss */ + 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_nchars = 1; } @@ -839,13 +840,13 @@ Cardinal *num_params; continue; if (!strncmp(ec_chars, extcmdlist[i].ef_txt, ec_nchars)) { - if (extended_command_selected != i) { + if (extended_cmd_selected != i) { /* I should use set() and unset() actions, but how do */ /* I send the an action to the widget? */ - if (extended_command_selected >= 0) - swap_fg_bg(extended_commands[extended_command_selected]); - extended_command_selected = i; - swap_fg_bg(extended_commands[extended_command_selected]); + if (extended_cmd_selected >= 0) + swap_fg_bg(extended_commands[extended_cmd_selected]); + extended_cmd_selected = i; + swap_fg_bg(extended_commands[extended_cmd_selected]); } ec_scroll_to_view(); return; @@ -1154,5 +1155,9 @@ Widget *formp; /* return */ XtRealizeWidget(popup); XSetWMProtocols(XtDisplay(popup), XtWindow(popup), &wm_delete_window, 1); + /* during role selection, highlight "random" as pre-selected choice */ + if (right_callback == ps_random && index(ps_randchars, '\n')) + swap_fg_bg(right); + return popup; }