seife / marble_fx

Arduino leonardo as USB converter for Logitech Trackman MarbleFX
3 stars 2 forks source link

2D scrolling #1

Open sobukus opened 2 months ago

sobukus commented 2 months ago

I was able to test the code now on a 32u4 Arduino Pro Micro with the T-CJ12. It seems to need a reinsertion when combined with usbguard after allow-device (maybe some hook to re-init hardware when the kernel driver is allowed to work is needed, normal devices work right away after lifting the software block).

But to come to the issue: I see that the red button is directly translated to scroll events in the Arduino. This spares any extra software setup on the PC, but it prevents the full experience: two-dimensional scrolling in both axes! How can you live without? ;-)

[Edit: Was misled by debugging output to serial port.]

I see https://www.arduino.cc/reference/en/language/functions/usb/mouse/mousemove/ being used

Mouse.move(xVal, yVal, wheel)

So this API doesn't allow for 2D scrolling.

The solution is to just pass through the red button and use xinput to configure things? Maybe we can use some idle pins to provide a switch for hardware of software scrolling mode. Hacking up the red button passthrough should be easy enough, actually easier than handling scrolling directly.

(Also: A custom device string would be nice if software scrolling needs to be configured …)

sobukus commented 2 months ago

Wait … there is only MOUSE_LEFT, MOUSE_RIGHT and MOUSE_MIDDLE available for https://www.arduino.cc/reference/en/language/functions/usb/mouse/mousepress/ ?! That is rather limiting. The HID protocol allows for a larger number of buttons, I presume.

Edit: Reading the actual API header, it looks to me like we can truly use all 8 bits of the button integer for 8 buttons. I imagine I can hack up the Arduino to report so that I can copy my PS/2 xinput config:

# 4-button TrackMan Marble FX
# Buttons 1,2,3 are normal, button 8 is the red one.
# Lets use the red one only for scrolling, not for clicks.
name='PS2++ Logitech TrackMan'
if [[ $(xinput list) =~ "$name" ]]; then
        xinput set-int-prop "$name" "Evdev Wheel Emulation" 8 1
        # Only button 8 (back) triggers wheel mode.
        xinput set-int-prop "$name" "Evdev Wheel Emulation Button" 8 8 
        xinput set-int-prop "$name" "Evdev Wheel Emulation Axes" 8 6 7 4 5 
        xinput set-ptr-feedback "$name" 5 6 1
        # libinput default kinda works, just need different button
        xinput --set-prop "$name" 'libinput Button Scrolling Button' 8
        xinput set-button-map "$name" 1 2 3 4 5 6 7 0
fi

In the end, that's the most flexible way. I see value in handling scrolling internally, but without extending the HID API, this only works for one axis. A control pin it should be, then, to switch internal scrolling on and off, don't you think?

sobukus commented 2 months ago

See pull request #2.