From aada9e270652489d0fa7b08e341489bc16cfca91 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 26 Jun 2019 15:46:44 -0700 Subject: [PATCH] mouse_support for win/curses using ncurses --- doc/fixes36.3 | 1 + include/wincurs.h | 1 + win/curses/cursmain.c | 5 +++++ win/curses/cursmisc.c | 51 +++++++++++++++++++++++++++++++++++++++---- win/curses/cursmisc.h | 1 + 5 files changed, 55 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 8d778b1c9..0d01a0bd6 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -185,6 +185,7 @@ classify sources as released, beta, or work-in-progress via NH_DEVEL_STATUS if you reach the edge of a level (relatively uncommon) and try to move off, report that you can't go farther if the 'mention_walls' option is set wizard-mode: display effect to show where an unseen wished-for monster landed +curses: enable latent mouse support for ncurses; status for PDCurses unknown curses+'perm_invent': since persistent inventory is narrow, strip off "a", "an", or "the" prefix on inventory entries shown there so that a tiny bit more of the interesting portion is visible diff --git a/include/wincurs.h b/include/wincurs.h index 18b3be289..79122430d 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -169,6 +169,7 @@ extern int curses_read_attrs(const char *attrs); extern char *curses_fmt_attrs(char *); extern int curses_convert_keys(int key); extern int curses_get_mouse(int *mousex, int *mousey, int *mod); +extern void curses_mouse_support(int); /* cursdial.c */ diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 0b36d5622..7094d316d 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -17,6 +17,9 @@ extern long curs_mesg_suppress_turn; /* from cursmesg.c */ struct window_procs curses_procs = { "curses", (WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR | WC_HILITE_PET +#ifdef NCURSES_MOUSE_VERSION /* (this macro name works for PDCURSES too) */ + | WC_MOUSE_SUPPORT +#endif | WC_PERM_INVENT | WC_POPUP_DIALOG | WC_SPLASH_SCREEN), (WC2_DARKGRAY | WC2_HITPOINTBAR #if defined(STATUS_HILITES) @@ -893,6 +896,8 @@ curses_preference_update(const char *pref) redo_status = TRUE; else if (!strcmp(pref, "align_message")) redo_main = TRUE; + else if (!strcmp(pref, "mouse_support")) + curses_mouse_support(iflags.wc_mouse_support); if (redo_main || redo_status) curs_reset_windows(redo_main, redo_status); diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index f7f08913b..51bd70208 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -885,11 +885,36 @@ curses_get_mouse(int *mousex, int *mousey, int *mod) MEVENT event; if (getmouse(&event) == OK) { /* When the user clicks left mouse button */ - if (event.bstate & BUTTON1_CLICKED) { + if (event.bstate & (BUTTON1_CLICKED | BUTTON2_CLICKED)) { + /* + * The ncurses man page documents wmouse_trafo() incorrectly. + * It says that last argument 'TRUE' translates from screen + * to window and 'FALSE' translates from window to screen, + * but those are backwards. The mouse_trafo() macro calls + * last argument 'to_screen', suggesting that the backwards + * implementation is the intended behavior and the man page + * is describing it wrong. + */ /* See if coords are in map window & convert coords */ - if (wmouse_trafo(mapwin, &event.y, &event.x, TRUE)) { + if (wmouse_trafo(mapwin, &event.y, &event.x, +#ifdef PDCURSES + /* + * Not sure whether PDCurses matches the ncurses implementation + * or the ncurses documentation, so keep the 'bad' argument for + * it until we find out. [Mouse can be used successfully with + * 'bad' coordinate translation via align_message:bottom (and + * avoiding align_status:left) so that the subset of the screen + * corresponding to the map needs no translation. Adding instead + * of subtracting or vice versa makes no difference when amount + * involved is 0.] + */ + TRUE +#else + FALSE +#endif + )) { key = 0; /* Flag mouse click */ - *mousex = event.x; + *mousex = event.x + 1; /* +1: screen 0..78 is map 1..79 */ *mousey = event.y; if (curses_window_has_border(MAP_WIN)) { @@ -897,7 +922,7 @@ curses_get_mouse(int *mousex, int *mousey, int *mod) (*mousey)--; } - *mod = CLICK_1; + *mod = (event.bstate & BUTTON1_CLICKED) ? CLICK_1 : CLICK_2; } } } @@ -906,6 +931,24 @@ curses_get_mouse(int *mousex, int *mousey, int *mod) return key; } +void +curses_mouse_support(mode) +int mode; /* 0: off, 1: on, 2: alternate on */ +{ +#ifdef NCURSES_MOUSE_VERSION + mmask_t result, oldmask, newmask; + + if (!mode) + newmask = 0; + else + newmask = BUTTON1_CLICKED | BUTTON2_CLICKED; + + result = mousemask(newmask, &oldmask); + nhUse(result); +#else + nhUse(mode); +#endif +} static int parse_escape_sequence(void) diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index c964878af..0c871e35f 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -30,5 +30,6 @@ int curses_read_attrs(const char *attrs); char *curses_fmt_attrs(char *); int curses_convert_keys(int key); int curses_get_mouse(int *mousex, int *mousey, int *mod); +void curses_mouse_support(int); #endif /* CURSMISC_H */