From aada9e270652489d0fa7b08e341489bc16cfca91 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 26 Jun 2019 15:46:44 -0700 Subject: [PATCH 1/4] 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 */ From 56387dccb6f4865e083ebe2b1375e315655a5b7e Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 27 Jun 2019 15:02:49 -0700 Subject: [PATCH 2/4] curses mouse right-click Right button is button3 rather than button2. Accept either and treat both as "not left" to pass CLICK_2 back to the core. Treat +left-click as "not left" too, to simplify usage with Mac one-button mouse (where +left-click can be configured to send "secondary click" but might not be set do so) or one-button laptop trackpad (where having two fingers on the scrolling portion of the pad while clicking the button is necessary to send "secondary click"). --- win/curses/cursinit.c | 4 +++- win/curses/cursmisc.c | 25 ++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 728f1e8ea..de8730fb5 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -838,8 +838,10 @@ curses_init_options() #ifdef NCURSES_MOUSE_VERSION if (iflags.wc_mouse_support) { - mousemask(BUTTON1_CLICKED, NULL); + curses_mouse_support(iflags.wc_mouse_support); } +#else + iflags.wc_mouse_support = 0; #endif } diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 51bd70208..0d477a0a1 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -870,6 +870,13 @@ curses_convert_keys(int key) return ret; } +/* we treat buttons 2 and 3 as equivalent so that it doesn't matter which + one is for right-click and which for middle-click; the core uses CLICK_2 + for right-click ("not left" click) even though 2 might be middle button; + we also support Ctrl+left-click as another way to get "not left" click + since Mac is traditionally saddled with a one button mouse or trackpad */ +#define MOUSEBUTTONS ((BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED) \ + | BUTTON_CTRL) /* Process mouse events. Mouse movement is processed until no further mouse movement events are available. Returns 0 for a mouse click @@ -884,8 +891,8 @@ curses_get_mouse(int *mousex, int *mousey, int *mod) #ifdef NCURSES_MOUSE_VERSION MEVENT event; - if (getmouse(&event) == OK) { /* When the user clicks left mouse button */ - if (event.bstate & (BUTTON1_CLICKED | BUTTON2_CLICKED)) { + if (getmouse(&event) == OK) { /* True if user has clicked */ + if ((event.bstate & MOUSEBUTTONS) != 0) { /* * The ncurses man page documents wmouse_trafo() incorrectly. * It says that last argument 'TRUE' translates from screen @@ -903,17 +910,16 @@ curses_get_mouse(int *mousex, int *mousey, int *mod) * 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.] + * avoiding align_status:top or left) so that the subset of the + * screen corresponding to the map needs no translation. Adding + * instead of subtracting makes no difference when amount is 0.] */ TRUE #else FALSE #endif )) { - key = 0; /* Flag mouse click */ + key = '\0'; /* core uses this to detect a mouse click */ *mousex = event.x + 1; /* +1: screen 0..78 is map 1..79 */ *mousey = event.y; @@ -922,7 +928,8 @@ curses_get_mouse(int *mousex, int *mousey, int *mod) (*mousey)--; } - *mod = (event.bstate & BUTTON1_CLICKED) ? CLICK_1 : CLICK_2; + *mod = ((event.bstate & (BUTTON1_CLICKED | BUTTON_CTRL)) + == BUTTON1_CLICKED) ? CLICK_1 : CLICK_2; } } } @@ -941,7 +948,7 @@ int mode; /* 0: off, 1: on, 2: alternate on */ if (!mode) newmask = 0; else - newmask = BUTTON1_CLICKED | BUTTON2_CLICKED; + newmask = MOUSEBUTTONS; /* buttons 1, 2, and 3 */ result = mousemask(newmask, &oldmask); nhUse(result); From bd2cd75f7a8b3d9e1a77b5aa1be0cc587abb9846 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 27 Jun 2019 23:12:06 -0400 Subject: [PATCH 3/4] PDCurses requires PDC_NCMOUSE for compatibility with ncurses The PDC_NCMOUSE has to be defined on the command line or above the #include entries in win/curses/cursmisc.c. This does the former command line change. --- include/wincurs.h | 6 ------ sys/winnt/Makefile.msc | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index 79122430d..127cd0faf 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -38,12 +38,6 @@ extern WINDOW *mapwin, *statuswin, *messagewin; /* Main windows */ #endif /* !__APPLE__ && !PDCURSES */ #define CURSES_DARK_GRAY 17 #define MAP_SCROLLBARS -#ifdef PDCURSES -# define getmouse nc_getmouse -# ifndef NCURSES_MOUSE_VERSION -# define NCURSES_MOUSE_VERSION -# endif -#endif #if !defined(A_LEFTLINE) && defined(A_LEFT) #define A_LEFTLINE A_LEFT diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index d2dd88414..fb8cd9b7e 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -634,7 +634,7 @@ DLB = #========================================== {$(WCURSES)}.c{$(OBJ)}.o: - @$(cc) $(PDCINCL) $(cflagsBuild) -Fo$@ $< + @$(cc) -DPDC_NCMOUSE $(PDCINCL) $(cflagsBuild) -Fo$@ $< #{$(WCURSES)}.txt{$(DAT)}.txt: # @copy $< $@ From 39eed81aa2cb5823fb3ea4603828817e46a12339 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 27 Jun 2019 23:22:34 -0400 Subject: [PATCH 4/4] PDCurses behaves the same as ncurses --- win/curses/cursmisc.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 0d477a0a1..5dcbe6d92 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -903,22 +903,7 @@ curses_get_mouse(int *mousex, int *mousey, int *mod) * is describing it wrong. */ /* See if coords are in map window & convert coords */ - 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:top or left) so that the subset of the - * screen corresponding to the map needs no translation. Adding - * instead of subtracting makes no difference when amount is 0.] - */ - TRUE -#else - FALSE -#endif - )) { + if (wmouse_trafo(mapwin, &event.y, &event.x, FALSE)) { key = '\0'; /* core uses this to detect a mouse click */ *mousex = event.x + 1; /* +1: screen 0..78 is map 1..79 */ *mousey = event.y;