Repository: jeaye/ncurses-rs (language: rust)

Issue:
Invalid constant values with NCURSES_MOUSE_VERSION = 1
When `NCURSES_MOUSE_VERSION = 1` (happens on Ubuntu 18.04), some constants have different values than when `NCURSES_MOUSE_VERSION = 2` (happens on Archlinux, and seems to be what ncurses-rs expects).

Here is the code from `/usr/include/ncurses.h` on ubuntu (but this part is the same on Archlinux):

```c
/*
 * In 32 bits the version-1 scheme does not provide enough space for a 5th
 * button, unless we choose to change the ABI by omitting the reserved-events.
 */
#if NCURSES_MOUSE_VERSION > 1

#define BUTTON5_RELEASED        NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_RELEASED)
#define BUTTON5_PRESSED         NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_PRESSED)
#define BUTTON5_CLICKED         NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_CLICKED)
#define BUTTON5_DOUBLE_CLICKED  NCURSES_MOUSE_MASK(5, NCURSES_DOUBLE_CLICKED)
#define BUTTON5_TRIPLE_CLICKED  NCURSES_MOUSE_MASK(5, NCURSES_TRIPLE_CLICKED)

#define BUTTON_CTRL             NCURSES_MOUSE_MASK(6, 0001L)
#define BUTTON_SHIFT            NCURSES_MOUSE_MASK(6, 0002L)
#define BUTTON_ALT              NCURSES_MOUSE_MASK(6, 0004L)
#define REPORT_MOUSE_POSITION   NCURSES_MOUSE_MASK(6, 0010L)

#else

#define BUTTON1_RESERVED_EVENT  NCURSES_MOUSE_MASK(1, NCURSES_RESERVED_EVENT)
#define BUTTON2_RESERVED_EVENT  NCURSES_MOUSE_MASK(2, NCURSES_RESERVED_EVENT)
#define BUTTON3_RESERVED_EVENT  NCURSES_MOUSE_MASK(3, NCURSES_RESERVED_EVENT)
#define BUTTON4_RESERVED_EVENT  NCURSES_MOUSE_MASK(4, NCURSES_RESERVED_EVENT)

#define BUTTON_CTRL             NCURSES_MOUSE_MASK(5, 0001L)
#define BUTTON_SHIFT            NCURSES_MOUSE_MASK(5, 0002L)
#define BUTTON_ALT              NCURSES_MOUSE_MASK(5, 0004L)
#define REPORT_MOUSE_POSITION   NCURSES_MOUSE_MASK(5, 0010L)

#endif

#define ALL_MOUSE_EVENTS        (REPORT_MOUSE_POSITION - 1)
```

In ncurses-rs, these values are defined as constants (hard-coded to the case `NCURSES_MOUSE_VERSION = 2`), and do not reflect this. As a result, many mouse events are broken when using ncurses-rs on Ubuntu.


Discussion / hints:
A solution could be to detect this in `build.rs` and trigger a `ncurses-mouse-v1` feature, which would be used to set the value of these constants.

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 975877d3..7ba51639 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,6 +26,8 @@ menu = []
 # Uses a 64-bit type for `chtype` (otherwise a 32-bit type is used).
 # This should be set automagically (when needed) by build.rs
 wide_chtype = []
+# Uses legacy values for mouse-related constants.
+mouse_v1 = []
 extended_colors = ["wide"]
 
 [lib]
diff --git a/build.rs b/build.rs
index 656cf10b..77b98eca 100644
--- a/build.rs
+++ b/build.rs
@@ -69,6 +69,10 @@ int main(void)
         /* We only support 32-bit and 64-bit chtype. */
         assert(sizeof(chtype)*CHAR_BIT == 32 && \"unsupported size for chtype\");
     }
+
+    if (NCURSES_MOUSE_VERSION == 1) {
+        puts(\"cargo:rustc-cfg=feature=\\\"mouse_v1\\\"\");
+    }
     return 0;
 }
     ").expect(&format!("cannot write into {}", src));
diff --git a/src/constants.rs b/src/constants.rs
index 8ffda79e..cd5a9c4d 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -214,7 +214,12 @@ pub const KEY_EVENT: i32=	0x19b;		/* We were interrupted by an event */
 pub const KEY_MAX: i32=	0x1ff;		/* Maximum key value is 0633 */
 
 /* Mouse Support */
+#[cfg(feature="mouse_v1")]
+macro_rules! ncurses_mouse_mask( ($b:expr, $m:expr) => ($m << (($b - 1) * 6)); );
+
+#[cfg(not(feature="mouse_v1"))]
 macro_rules! ncurses_mouse_mask( ($b:expr, $m:expr) => ($m << (($b - 1) * 5)); );
+
 pub const NCURSES_BUTTON_RELEASED: i32=	0x001;
 pub const NCURSES_BUTTON_PRESSED: i32=		0x002;
 pub const NCURSES_BUTTON_CLICKED: i32=		0x004;
@@ -247,17 +252,46 @@ pub const BUTTON4_CLICKED: i32=        ncurses_mouse_mask!(4, NCURSES_BUTTON_CLI
 pub const BUTTON4_DOUBLE_CLICKED: i32= ncurses_mouse_mask!(4, NCURSES_DOUBLE_CLICKED);
 pub const BUTTON4_TRIPLE_CLICKED: i32= ncurses_mouse_mask!(4, NCURSES_TRIPLE_CLICKED);
 
+// These values depend on NCURSES_MOUSE_VERSION
+
+#[cfg(not(feature = "mouse_v1"))]
 pub const BUTTON5_RELEASED: i32=       ncurses_mouse_mask!(5, NCURSES_BUTTON_RELEASED);
+#[cfg(not(feature = "mouse_v1"))]
 pub const BUTTON5_PRESSED: i32=        ncurses_mouse_mask!(5, NCURSES_BUTTON_PRESSED);
+#[cfg(not(feature = "mouse_v1"))]
 pub const BUTTON5_CLICKED: i32=        ncurses_mouse_mask!(5, NCURSES_BUTTON_CLICKED);
+#[cfg(not(feature = "mouse_v1"))]
 pub const BUTTON5_DOUBLE_CLICKED: i32= ncurses_mouse_mask!(5, NCURSES_DOUBLE_CLICKED);
+#[cfg(not(feature = "mouse_v1"))]
 pub const BUTTON5_TRIPLE_CLICKED: i32= ncurses_mouse_mask!(5, NCURSES_TRIPLE_CLICKED);
 
+#[cfg(not(feature = "mouse_v1"))]
 pub const BUTTON_CTRL: i32=		ncurses_mouse_mask!(6, 0x001);
+#[cfg(not(feature = "mouse_v1"))]
 pub const BUTTON_SHIFT: i32=		ncurses_mouse_mask!(6, 0x002);
+#[cfg(not(feature = "mouse_v1"))]
 pub const BUTTON_ALT: i32=		ncurses_mouse_mask!(6, 0x004);
+#[cfg(not(feature = "mouse_v1"))]
 pub const REPORT_MOUSE_POSITION: i32=	ncurses_mouse_mask!(6, 0x008);
 
+#[cfg(feature = "mouse_v1")]
+pub const BUTTON1_RESERVED_EVENT: i32 = ncurses_mouse_mask!(1, NCURSES_RESERVED_EVENT);
+#[cfg(feature = "mouse_v1")]
+pub const BUTTON2_RESERVED_EVENT: i32 = ncurses_mouse_mask!(2, NCURSES_RESERVED_EVENT);
+#[cfg(feature = "mouse_v1")]
+pub const BUTTON3_RESERVED_EVENT: i32 = ncurses_mouse_mask!(3, NCURSES_RESERVED_EVENT);
+#[cfg(feature = "mouse_v1")]
+pub const BUTTON4_RESERVED_EVENT: i32 = ncurses_mouse_mask!(4, NCURSES_RESERVED_EVENT);
+#[cfg(feature = "mouse_v1")]
+pub const BUTTON_CTRL: i32=		ncurses_mouse_mask!(5, 0x001);
+#[cfg(feature = "mouse_v1")]
+pub const BUTTON_SHIFT: i32=		ncurses_mouse_mask!(5, 0x002);
+#[cfg(feature = "mouse_v1")]
+pub const BUTTON_ALT: i32=		ncurses_mouse_mask!(5, 0x004);
+#[cfg(feature = "mouse_v1")]
+pub const REPORT_MOUSE_POSITION: i32=	ncurses_mouse_mask!(5, 0x008);
+
+
 pub const ALL_MOUSE_EVENTS: i32=	REPORT_MOUSE_POSITION - 1;
 
 /* macros to extract single event-bits from masks */


Test patch: