Mouse scrolling in Linux Debian Wheezy

Status
Not open for further replies.
Hello everyone!

I'm working on creating a keyboard and mouse passthrough on the teensy, however I seem to be getting stuck when it comes to mouse scrolling. I can get it to move in the x and y directiions as expected, but when it comes to the Mouse.scroll, whatever I have under my mouse doesn't scroll.

I have attached my mostly complete code (note I am using a USB host 2.0). The USB Host 2.0 side is working just as expected, but when I try to pass a scroll value, I don't see any scrolling action (I even tried passing a -1 to Mouse.scroll, with no effect :/ )

Has anyone else successfully got scrolling working, or is there a driver that I need to update to in Linux?
Thanks for reading,
Dustin
 

Attachments

  • USBHIDBootKbdAndMouse.ino
    6.5 KB · Views: 208
Which USB Host 2.0 are you using? The reason I ask is because the one on the PJRC website doesn't have hidboot.h, and the one that I'm finding on github (https://github.com/felis/USB_Host_Shield_2.0/) doesn't seem to support the mouse wheel at all in hidboot for the mouse, because the scroll wheel itself isn't part of the standard boot-protocol section of the mouse report (it can be shoved into an extra byte, but that's not guaranteed). However I'm not sure that I'm finding the right "USB Host 2.0" library - neither seems to have the "wheel" field in MOUSEINFO that you've used in the OnMouseScroll function, so I suspect I'm looking at the wrong library.

If you are using that github library, there's nothing there that I can see that would trigger the use of your OnMouseScroll function - even if it's in the mouse's usb report, your code won't be being activated. I *think* what you'd need to do is customise the MouseReportParser::parse() function from hidboot.cpp to add handling for the scroll wheel - there's comments there that for logitech mice at least the wheel reports its changes in the 4th byte, and that's where I think you'd need to detect the change and trigger it into calling your scroll code. You'd also probably need a field to store the value inside the MOUSEINFO struct so that the value of that byte can be passed to your function, or to change your function to receive just the wheel byte itself and pass that byte directly instead of the full mouseinfo structure.
 
Last edited:
Which USB Host 2.0 are you using? The reason I ask is because the one on the PJRC website doesn't have hidboot.h, and the one that I'm finding on github (https://github.com/felis/USB_Host_Shield_2.0/) doesn't seem to support the mouse wheel at all in hidboot for the mouse, because the scroll wheel itself isn't part of the standard boot-protocol section of the mouse report (it can be shoved into an extra byte, but that's not guaranteed). However I'm not sure that I'm finding the right "USB Host 2.0" library - neither seems to have the "wheel" field in MOUSEINFO that you've used in the OnMouseScroll function, so I suspect I'm looking at the wrong library.

If you are using that github library, there's nothing there that I can see that would trigger the use of your OnMouseScroll function - even if it's in the mouse's usb report, your code won't be being activated. I *think* what you'd need to do is customise the MouseReportParser::parse() function from hidboot.cpp to add handling for the scroll wheel - there's comments there that for logitech mice at least the wheel reports its changes in the 4th byte, and that's where I think you'd need to detect the change and trigger it into calling your scroll code. You'd also probably need a field to store the value inside the MOUSEINFO struct so that the value of that byte can be passed to your function, or to change your function to receive just the wheel byte itself and pass that byte directly instead of the full mouseinfo structure.

I am indeed using the github library. After enabling the debugging mode in the settings.h, I discovered that my particular mouse was indeed sending the scrolling data as the last byte. It also sends the scroll left and right button, and all of that is working fine for my particular wireless mouse (a logitech mouse which supports the unifying dongle). I attempted to see if a corded mouse would work, but it doesn't. So far it works for the mouse, and a wireless trackball.

My current problem isn't dealing with the USB host library, but with the Teensy USB mouse emulation scrolling. I think my next debugging step will be to see if it scrolls in windows. I was hoping that there was something trivial that I forgot to do :)
 
Looks like I should update the USB Host Shield copy on the PJRC web page. It's pretty old.

My current problem isn't dealing with the USB host library, but with the Teensy USB mouse emulation scrolling.

Is Mouse.scroll(integer) not working? Please let me know which Teensy and which operating system you're using, and I'll give it a try here.
 
Looks like I should update the USB Host Shield copy on the PJRC web page. It's pretty old.



Is Mouse.scroll(integer) not working? Please let me know which Teensy and which operating system you're using, and I'll give it a try here.

Well it isn't working for me. This is with a Teensy 3.1, on Debian Wheezy 7.3, fully updated. The mouse buttons and movement works, just not the scrolling. With the above code, it technically should always be scrolling down when I trigger that function by scrolling the USB mouse. My serial debug shows that the teensy is correctly receiving the scrolling, just Mouse.scroll doesn't seem to be doing the actual scrolling.

I have the Teensy 3.1 configured with the "Serial + keyboard + mouse + joystick" USB option.
 
So I simplifed the code a bit, the attached example doesn't scroll the mouse as it should. Right now I suspect that the driver it automatically chooses doesn't support scrolling (I'm not sure if there is a special setup needed for linux).
 

Attachments

  • TriangleMoveScroll.ino
    546 bytes · Views: 200
I tested this earlier today, right before the 1.18 release.

I'm pretty sure this is a Linux bug. Or a bug somewhere in the software stack running on top of the Linux kernel.

I verified Teensy is sending correct data. I tested on Windows 7 Home Premium 64 bit and Macintosh OS-X 10.7.5 Lion. Both are able to recognize the scroll wheel data from Teensy 3.1. I tested on Ubuntu 12.04 with Gnome Panel, which does not recognize the scroll wheel.

Believe me, I was really surprised to find this. Usually devices that follow published HID standard in some way slightly off the well-worn path work great on Linux and have trouble on Windows. But in this case, it does seem that Windows has a correct HID parser and Linux does not.

Prior to Teensyduino 1.17, Teensy 3.0 & 3.1 had a very traditional USB mouse implementation. Teensy 2.0 still does. But traditional relative mouse movement is only useful when you can see where the pointer is on your screen. 1.17 added Mouse.moveTo(x, y) and Mouse.screenSize(width, height). You set the screen size, and then you can move the mouse to any pixel on the screen, because the mouse device uses high resolution absolute positioning data, rather than relative movement.

Of course, the scroll wheel is still relative movement. It's defined as a separate input within the same HID report. The HID standard specifically allows this. Windows and Mac support it. Linux obviously does recognize the absolute coordinates for the pointer, but it seems to have trouble with a relative input in the same HID report.

In my test code, I used to buttons connected to a Teensy 3.1 to send Mouse.move(1,1) and Mouse.scroll(1). The Teensy 3.1 mouse code will send the mouse to the center of your screen if you don't use Mouse.moveTo().

I noticed Mouse.scroll(1) does indeed move the pointer to the center, but only once. Thereafter, it is ignored. I'm almost certain this is a bug somewhere on the Linux system. I have no idea where to report this. I also don't have more time to dig further into what's going on, whether the Linux kernel is providing good data and it's being messed up in X11 or somewhere else?

Any idea how to pass this along to any Linux advocates who'd be interested to investigate further and ultimately report the bug to an upstream developer?

For now, your only hope on Linux would be to get the old code from Teensyduino 1.16 that doesn't use absolute mouse positioning. The 1.16 version is still on the server. Just use "copy link location" on the download link, copy to a text editor, and change "118" in the URL to "116".
 
I tested this earlier today, right before the 1.18 release.

I'm pretty sure this is a Linux bug. Or a bug somewhere in the software stack running on top of the Linux kernel.

I verified Teensy is sending correct data. I tested on Windows 7 Home Premium 64 bit and Macintosh OS-X 10.7.5 Lion. Both are able to recognize the scroll wheel data from Teensy 3.1. I tested on Ubuntu 12.04 with Gnome Panel, which does not recognize the scroll wheel.

Believe me, I was really surprised to find this. Usually devices that follow published HID standard in some way slightly off the well-worn path work great on Linux and have trouble on Windows. But in this case, it does seem that Windows has a correct HID parser and Linux does not.

Prior to Teensyduino 1.17, Teensy 3.0 & 3.1 had a very traditional USB mouse implementation. Teensy 2.0 still does. But traditional relative mouse movement is only useful when you can see where the pointer is on your screen. 1.17 added Mouse.moveTo(x, y) and Mouse.screenSize(width, height). You set the screen size, and then you can move the mouse to any pixel on the screen, because the mouse device uses high resolution absolute positioning data, rather than relative movement.

Of course, the scroll wheel is still relative movement. It's defined as a separate input within the same HID report. The HID standard specifically allows this. Windows and Mac support it. Linux obviously does recognize the absolute coordinates for the pointer, but it seems to have trouble with a relative input in the same HID report.

In my test code, I used to buttons connected to a Teensy 3.1 to send Mouse.move(1,1) and Mouse.scroll(1). The Teensy 3.1 mouse code will send the mouse to the center of your screen if you don't use Mouse.moveTo().

I noticed Mouse.scroll(1) does indeed move the pointer to the center, but only once. Thereafter, it is ignored. I'm almost certain this is a bug somewhere on the Linux system. I have no idea where to report this. I also don't have more time to dig further into what's going on, whether the Linux kernel is providing good data and it's being messed up in X11 or somewhere else?

Any idea how to pass this along to any Linux advocates who'd be interested to investigate further and ultimately report the bug to an upstream developer?

For now, your only hope on Linux would be to get the old code from Teensyduino 1.16 that doesn't use absolute mouse positioning. The 1.16 version is still on the server. Just use "copy link location" on the download link, copy to a text editor, and change "118" in the URL to "116".


Thanks I'll check out the 1.16 version. I think I'll also try to figure out pieces of what makes the USB HID protocol tick (descriptors and such), so that I could possibly figure out where the problem is in Linux. I guess loading up a bleeding edge version of debian or Arch would be a good idea since the problem may have been fixed.

I suspect that if I poke around the #Linux IRC channel on Freenode, I'd be able to find someone who knows what to check (or tell me which manual to read after telling me to RTFM :) ).

Thanks for your support, your active commitment to the community is why I chose to go with a Teensy.
 
Well I copied the MOUSE_INTERFACE portions of usb_desc.c from 1.16 to 1.18, and copied the complete usb_mouse.c and usb_mouse.h from 1.16 to 1.18, and now mouse movement and scrolling works. I think I will just add a quick syncronization command so that the X/Y of the screen can be determined. For example, I'd move the mouse to the lower left corner and hit a key so that the Teensy will know that was the bottom left, and everything recorded can be relative to that.
 
So another temporary solution I came up with, is to create another mouse HID for absolute positioning, and only use it for mouse movements. So now I've got the teensy as 2 mouses with absolute positioning and scrolling, in wheezy.
 
So another temporary solution I came up with, is to create another mouse HID for absolute positioning, and only use it for mouse movements. So now I've got the teensy as 2 mouses with absolute positioning and scrolling, in wheezy.

Hi,
Ive been trying to get my scroll wheel to work with my teensy 2.0 in Windows 7 & Ubuntu with no luck.
Ive been banging my head against a wall for the past 4 days trying to figure it out.

Could you please post the code you used to get yours to work.

Thank you,
Sam.
 
I'll post the code that I'm using when I get home from work later. The significant part is to take the relative mouse positioning from Teensiduno 1.16 and merge it with the latest version. I'm using a Teensy 3.1, so it may be different for you, but I'll post it so that you can perhaps figure it out.
 
I'll post the code that I'm using when I get home from work later. The significant part is to take the relative mouse positioning from Teensiduno 1.16 and merge it with the latest version. I'm using a Teensy 3.1, so it may be different for you, but I'll post it so that you can perhaps figure it out.

So what I figured out, was that in Linux, the scroll data for absolute mice is ignored. To add it to both Linux and Windows, I added a relative mouse in addition to my absolute mouse.

Another key thing you may need to do, is to increase the power that Teensy requests. Search for bMaxPower.

I discussed the changes that I made to Teensyduino in a blog post in my blog: http://mecharobotics.wordpress.com/2014/04/21/teensy-3-1-adding-mouse-scrolling-support-for-linux

I'll upload the patch here since it'll be easier to go through: View attachment 1848

Let me know if that helps...
 
Status
Not open for further replies.
Back
Top