diff options
-rw-r--r-- | README.md | 17 | ||||
-rw-r--r-- | mousetsr.c | 39 | ||||
-rw-r--r-- | mousetsr.h | 7 |
3 files changed, 51 insertions, 12 deletions
@@ -85,8 +85,10 @@ the following additional features: Note *wheel support is broken when running under 386-enhanced mode Windows*, since it will not let PS/2 wheel data reach the DOS driver. -* Sending fake keys on wheel movements, i.e. faking wheel scroll support using arrow up/down keys. - You can scroll with the mouse wheel inside MS-DOS Edit! +* **Sending scroll keys on wheel movements**, + i.e. faking wheel scroll support on programs that don't support the CuteMouse API + by using arrow up/down keys. + You can now scroll with the mouse wheel inside MS-DOS Edit! This is not enabled by default, see `wheelkey` below. * The current version uses about 10KiB of memory (when logging is disabled), @@ -96,7 +98,7 @@ the following additional features: * A companion driver for Windows 3.x (_VBMOUSE.DRV_) that uses this driver (via int33h) instead of accessing the mouse directly, so that Windows 3.x gains some of the features of this driver - (like mouse integration in VirtualBox). + (like mouse integration in VirtualBox/VMware). There is some preliminary mouse wheel support based on the ideas from [vmwmouse](https://github.com/NattyNarwhal/vmwmouse/issues/5), but it only works under real-mode Windows. @@ -433,6 +435,15 @@ to obtain mouse button presses (and wheel movement) is still through the PS/2 co * Get the scroll wheel to work under 386-enhanced Windows, but this requires looking into VKD.386 (or a replacement of it). +* Investigate whether it makes sense to configure the PS/2 BIOS in "1 packet mode" + like the [Microsoft Mouse driver does](https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/97883) + to aid scroll wheel compatibility. Currently we set it to either 3 packet + or 4 packet depending on whether we detect a wheel mouse or not. + +* The VirtualBox BIOS can crash on warm-boot (e.g. Ctrl+Alt+Del) if the mouse + was in the middle of sending a packet. A VM reboot fixes it. + We probably need to hook Ctrl+Alt+Del and turn off the mouse. + * VMware shared folders support is interesting, but there is very little documentation that I can find, no sample code, and no open source implementation. Also, unlike VBMOUSE, where most of the code is common to all virtualizers, @@ -679,7 +679,7 @@ static void handle_mouse_event(uint16_t buttons, bool absolute, int x, int y, in for (; z < 0; z++) { int16_store_keystroke(data.wheel_up_key); } - } else if (z > 0 && data.wheel_up_key) { + } else if (z > 0 && data.wheel_down_key) { for (; z > 0; z--) { int16_store_keystroke(data.wheel_down_key); } @@ -751,6 +751,8 @@ static void ps2_mouse_handler(uint16_t word1, uint16_t word2, uint16_t word3, ui #endif /* TRACE_EVENTS */ // Decode the PS2 event args + +#if USE_WHEEL // In a normal IBM PS/2 BIOS (incl. VirtualBox/Bochs/qemu/SeaBIOS): // word1 low byte = status (following PS2M_STATUS_*) // word2 low byte = x @@ -763,18 +765,40 @@ static void ps2_mouse_handler(uint16_t word1, uint16_t word2, uint16_t word3, ui // word2 low byte = y // word3 low byte = z // word4 = always zero - // VirtualBox/Bochs/qemu/SeaBIOS behave like a normal one, - // but they also store the raw contents of all mouse packets in the EBDA (starting 0x28 = packet 0). + // Real hardware seems to be of either type. + // VirtualBox/Bochs/qemu/SeaBIOS also store the raw contents of all mouse + // packets in the EBDA reserved area (starting 0x28 = packet 0). // Other BIOSes don't do that so it is not a reliable option either. // So, how to detect which BIOS we have? - // For now we are always assuming "normal" PS/2 BIOS. - // But with VirtualBox integration on we'll get the wheel packet from the EBDA, - // and with VMWare integration on we'll get it from the VMware protocol. + + // First, we'll only read the EBDA if we have confirmed VirtualBox (see USE_VIRTUALBOX below) + // For VirtualBox VMs this is mandatory since we have no other way of getting wheel data + // For qemu VMs, we can still get to wheel data via the vmmouse interface (and we'll do that). + // Second, the moment we see that the high byte of word1 is not 0, + // we'll assume the BIOS is of the second type, and remember that. + // (since when there is no movement, x would be 0 anyway!) + + if (word1 & 0xFF00) data.bios_x_on_status = true; + + if (data.haswheel && data.bios_x_on_status) { + status = (uint8_t) word1; + x = (uint8_t) (word1 >> 8); + y = (uint8_t) word2; + z = (int8_t) word3; // Sign-extend z packet + } else { + status = (uint8_t) word1; + x = (uint8_t) word2; + y = (uint8_t) word3; + z = 0; + } +#else status = (uint8_t) word1; x = (uint8_t) word2; y = (uint8_t) word3; z = 0; - (void) word4; +#endif + + (void) word4; // This appears to be never used on either type of BIOS // Sign-extend X, Y as per the status byte x = status & PS2M_STATUS_X_NEG ? 0xFF00 | x : x; @@ -946,6 +970,7 @@ static void reset_mouse_hardware() ps2m_enable(false); #if USE_WHEEL + data.bios_x_on_status = false; if (data.usewheel && ps2m_detect_wheel()) { dlog_puts("PS/2 wheel detected"); data.haswheel = true; @@ -37,7 +37,7 @@ /** Enable the wheel. */ #define USE_WHEEL 1 /** Trace events verbosily */ -#define TRACE_EVENTS 1 +#define TRACE_EVENTS 0 #define VERSION_MAJOR 0 #define VERSION_MINOR 5 @@ -102,7 +102,10 @@ typedef struct tsrdata { // Detected mouse hardware #if USE_WHEEL /** Whether the current mouse has a wheel (and support is enabled). */ - bool haswheel; + bool haswheel : 1; + /** Whether the current PS/2 BIOS seems to be putting the first packet + * on the high byte of the first word when we use wheel mouse. */ + bool bios_x_on_status : 1; #endif // Current mouse settings |