mbuesch / razer

Razer device library and tools
http://bues.ch/h/razercfg
GNU General Public License v2.0
251 stars 50 forks source link

Missing Tilt Button support in Razer Naga #44

Open OvermindDL1 opened 9 years ago

OvermindDL1 commented 9 years ago

Synapse currently defines these buttons of:

    SYNAPSE_PHYSBUT_LEFT = 0x01,    /* Left button */
    SYNAPSE_PHYSBUT_RIGHT,      /* Right button */
    SYNAPSE_PHYSBUT_MIDDLE,     /* Middle button */
    SYNAPSE_PHYSBUT_LFRONT,     /* Left side, front button */
    SYNAPSE_PHYSBUT_LREAR,      /* Left side, rear button */
    SYNAPSE_PHYSBUT_RFRONT,     /* Right side, front button */
    SYNAPSE_PHYSBUT_RREAR,      /* Right side, rear button */
    SYNAPSE_PHYSBUT_TFRONT,     /* Top side, front button */
    SYNAPSE_PHYSBUT_TREAR,      /* Top side, rear button */
    SYNAPSE_PHYSBUT_SCROLLUP,   /* Scroll wheel up */
    SYNAPSE_PHYSBUT_SCROLLDWN,  /* Scroll wheel down */

However it is also missing the HSCROLL Tilt buttons, which by default map to scroll up/down on most(all?) Razer mice and the mouse needs to receive configuration information to remap them to something decent, however the synapse driver does not expose this information, nor how to configure it.

mbuesch commented 9 years ago

Working patches are welcome. I don't have any device that supports this.

benoit-pierre commented 9 years ago

I have looked at this for my Razer Naga, and apparently it's not handled by the firmware: I did not see any USB calls when changing what tilting the scroll wheel left/right does with Synapse on Windows. So the handling must be done on the PC side.

By default (and so on Linux), each tilt the wheel will generate scroll wheel events, with no way to configure it. And since tilt left/right don't act as specific buttons, remapping them with 'xinput set-button-map' is not possible. I guess Synapse filters those events based on time when changing the default actions.

mbuesch commented 9 years ago

Yes, the naga does not have such a razer specific event. It emits standard HID messages. You can check these with the xev utility on Linux. You should also be able to remap these with standard tools like xinput.

In fact, naga is not a synapse mouse (even if Razer claims that). The naga has its own proprietary protocol.

benoit-pierre commented 9 years ago

OK. How do you remap those events with xinput? I did not find a way to do so last time I looked at it.

mbuesch commented 9 years ago

Your favourite search engine brings up lots of answers on that topic. For instance this http://marian.schedenig.name/2012/06/07/mapping-kde-actions-to-extra-mouse-buttons/

benoit-pierre commented 9 years ago

This does not use xinput. Just to be clear, from X point of view, there is not difference between scrolling up the wheel and tilting the scroll wheel left (I also get the same output with usbmon). Tilting continously generate scroll wheel events until release. So I can't filter solely based on button number (or I will change the behavior of the scroll wheel scroll up/down events). And again, I could not find a way to change the button mapping with xinput.

mbuesch commented 9 years ago

Yes, well. However razercfg cannot do anything about that. If there's no way to remap certain HID events, you need to contact X and kernel HID people. The mouse events do not go through razercfg. So it cannot remap anything, even if it would want to. The button remapping thing in razercfg is an entirely different thing. It will remap the buttons internally in the mouse firmware. The naga does not support this firmware remapping. And even if it would, it could not remap anything to keyboard keys. The key binding that the windows driver does is just eye candy over Windows specific remappings.

Thanks a lot for your contribution to razercfg.

Closing this issue, because it's not really razercfg related.

benoit-pierre commented 9 years ago

I know, that what I was saying all along.

OvermindDL1 commented 9 years ago

For note, I already started working on the protocol a few days ago, figure out a way to 'clear' the Tilt setting so it sends nothing, trying to figure out how to get it to send something else, I am thinking it remaps to the keyboard interface. Just need to figure out how to set it...

Regardless though, this is not an X or kernel HID issue, this is something that has to be set on the naga itself, just need to figure out the protocol part of it... Any chance on re-opening as this is not an X or HID issue but rather a firmware naga configuration issue, which is, I think anyway, what razercfg is for?

OvermindDL1 commented 9 years ago

I am trying to get a hold of a Windows laptop from someone in the next week or so to capture the packets, so will see then...

OvermindDL1 commented 9 years ago

And yes, I did confirm on Windows remotely that changing the Naga 2014 Tilt to send a keyboard key does cause the mouse to send a keyboard event, so it does seem to be something on the mouse.

OvermindDL1 commented 9 years ago

I have also somehow accidentally got it sending data over the USB interface that does not correspond to key presses now...

Scrollwheel Up:  00 00 00 01 00 00 00 00
Scrollwheel Dn:  00 00 00 FF 00 00 00 00
Tilt Button Left Dn:  20 00 00 00 00 00 00 00
Tilt Button Left Up: 00 00 00 00 00 00 00 00
Tilt Button Right Dn:  40 00 00 00 00 00 00 00
Tilt Button Right Up:  00 00 00 00 00 00 00 00

That is from the USB packets themselves, I am not quite sure how I caused that, but it is new and useful information instead of the mouse sending the same data for Tilt as for scroll, the data USB packet I fed the mouse was:

0030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
0040  00 00 00 00 00 01 00 04  03 00 00 00 00 00 00 00
0050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
0060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
0070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
0080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
0090  00 00 00 00 00 00 00 00  06 00

Using the SET_REPORT byte of 0x09 to setup the request, a value of 0x0300, and an index of 2. I am fairly sure this clears the existing mapping data and the mouse seems to work fine otherwise except the Tilt not working as scroll now (and is not mapped by evdev as anything, I think this is 'new' data specific to the naga/razer for Tilt? Perhaps for the windows-side mapping program). At this point I could make a USB listener to listen for those data chunks specifically and handle them to do my own key mapping, too much work for tonight though, and it would be great to get it in to razerd anyway.

OvermindDL1 commented 9 years ago

And yes, to confirm, if I reset the mouse (unplug then plug back in) it maps the Tilt back to scrolling again, which in the USB capture spams the scrolling up/down packets identical to the scrollwheel, but rapid-fire, and when I send that packet again that I detailed above, then the Tilt changes to being the new data I documented above. It seems quite reliable, tested a multitude of times now and the mouse still functions properly. So, I think I found it...

mbuesch commented 9 years ago

At this point I could make a USB listener to listen for those data chunks specifically and handle them to do my own key mapping, too much work for tonight though, and it would be great to get it in to razerd anyway.

razerd will never listen to data packets from any razer device. That is not what razerd is supposed to do. It is the task of the kernel and X HID drivers to handle the data stream.

It seems quite reliable, tested a multitude of times now and the mouse still functions properly. So, I think I found it...

Well, please send me a Wireshark USB dump of the configuration sequence that does the reconfiguration. Make sure to keep the amount of HID data low in that dump.

benoit-pierre commented 9 years ago

That's great, I'm glad I got it wrong.

OvermindDL1 commented 9 years ago

razerd will never listen to data packets from any razer device. That is not what razerd is supposed to do. It is the task of the kernel and X HID drivers to handle the data stream.

Understandable yeah. Do you have any ideas for how to get the linux HID interface to see those as tilt then as it apparently does not? The mouse does not seem to report the mapping for the tilt buttons at all. I think it was designed only to be read by the synapse software nonsense... Easy to read, just nothing does it by default as the mouse is not reporting it...

Well, please send me a Wireshark USB dump of the configuration sequence that does the reconfiguration. Make sure to keep the amount of HID data low in that dump.

Done: http://overminddl1.com/Razer/RazerNaga-0.3-0.5-Init-6TiltLeftDn-7TiltLeftUp-9TiltRightDn-10TiltRightUp.pcapng Basically this:

<0.1s:  Wireshark USB Init, ignore, kept for completion
0.3s-0.54s:  This is when I sent the packet that converts the tilt mode from scroll to a unique button press
6s:  Tilt Left Pressed Down
7s:  Tilt Left Released Up
9s:  Tilt Right Pressed Down
10s:  Tilt Right Released Up

Before the command if I press tilt it just spams the identical packet as scrolling, but instead of once per click like the scroll wheel it spams it continuously and rapidly while the tilt is held down. By the end of the command I can watch the Tilt having new data come down as shown in the dump, its bit pattern does not match anything else that I have seen come down from the mouse. I do not know the HID or evdev systems well enough to be able to tell them to requery it or so, and as stated before, if the mouse is reset then it returns to the tilt-rapid-scrolling again, so this setting is definitely temporary as it seems with Synapse as well, so it needs to be set every time.

I uploaded the compiled program that should work on linux 64-bit generic systems to: LINK TO BINARY ONLY PROGRAM REMOVED. Please provide sources. --mb It links to:

$ ldd InitRazerNaga2024
        linux-vdso.so.1 =>  (0x00007fffe0a42000)
        libusb-1.0.so.0 => /lib/x86_64-linux-gnu/libusb-1.0.so.0 (0x00007f57b93df000)
        libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007f57b915f000)
        libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007f57b8f57000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f57b8c4f000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f57b8a47000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f57b8843000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f57b8625000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f57b825b000)
        libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007f57b8048000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f57b95f7000)

So it should work about anywhere with the right libs if someone wants to try my hacked together test, compiled from haskell so excuse the size, make sure your user has write access to the proper usb device as it scans for 1532-0040 specifically (Razer Naga 2014 that I have), or run as sudo'd (never recommended, but eh...). All it does is send the packet sequence to the device/mouse then exit.

That's great, I'm glad I got it wrong.

@benoit-pierre If you have an idea on how to remap its HID button signature, which is completely ignored by the linux HID and evdev systems as the mouse does not tell it about its existence in the first place, I would love to hear it.

OvermindDL1 commented 9 years ago

The mouse interface reported does not appear to have changed any between when the tilt is acting as a scrollwheel and when it has its own buttons (no diff result), it is always this:

    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      2 Mouse
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      94
          Report Descriptor: (length is 94)
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x02 ] 2
                            Mouse
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Local ): Usage, data= [ 0x01 ] 1
                            Pointer
            Item(Main  ): Collection, data= [ 0x00 ] 0
                            Physical
            Item(Global): Usage Page, data= [ 0x09 ] 9
                            Buttons
            Item(Local ): Usage Minimum, data= [ 0x01 ] 1
                            Button 1 (Primary)
            Item(Local ): Usage Maximum, data= [ 0x05 ] 5
                            Button 5
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x01 ] 1
            Item(Global): Report Size, data= [ 0x01 ] 1
            Item(Global): Report Count, data= [ 0x05 ] 5
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Report Size, data= [ 0x01 ] 1
            Item(Global): Report Count, data= [ 0x03 ] 3
            Item(Main  ): Input, data= [ 0x03 ] 3
                            Constant Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
                            (null)
            Item(Local ): Usage, data= [ 0x40 ] 64
                            (null)
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Global): Logical Minimum, data= [ 0x81 ] 129
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x38 ] 56
                            Wheel
            Item(Global): Logical Minimum, data= [ 0x81 ] 129
            Item(Global): Logical Maximum, data= [ 0x7f ] 127
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x01 ] 1
            Item(Main  ): Input, data= [ 0x06 ] 6
                            Data Variable Relative No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x30 ] 48
                            Direction-X
            Item(Local ): Usage, data= [ 0x31 ] 49
                            Direction-Y
            Item(Global): Logical Minimum, data= [ 0x00 0x80 ] 32768
            Item(Global): Logical Maximum, data= [ 0xff 0x7f ] 32767
            Item(Global): Report Size, data= [ 0x10 ] 16
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Main  ): Input, data= [ 0x06 ] 6
                            Data Variable Relative No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
                            (null)
            Item(Local ): Usage, data= [ 0x02 ] 2
                            (null)
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x01 ] 1
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x5a ] 90
            Item(Main  ): Feature, data= [ 0x01 ] 1
                            Constant Array Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               1
OvermindDL1 commented 9 years ago

Yeah I cannot seem to figure out how to get the HID interface to pass those on. I see them fine when I cat /dev/usbmon5 but they are not passed through cat /dev/input/mouse0, so the linux HID is ignoring it, gotta be something not getting set, but as stated before, I do not know HID terribly well... >.> Probably need to re-init it or something, but doing that resets the mouse, defeating the point.

mbuesch commented 9 years ago

Ok, well. I always accept patches, as long as they adhere to the contribution rules http://bues.ch/cms/resources/contribute.html

However, the interpretation of the button event message is not solvable in razerd. That must be done in the driver. The kernel HID provides interfaces for device specific packet interpreters. So a razerd patch can only be half of the solution.

mbuesch commented 9 years ago

OvermindDL1: If you want to provide proof of concept code or such, please show the sources. Binary only blobs are not helping the development of razercfg and we are not going to distribute and execute large binary-only blobs in the Open Source community. I removed your link for this reason. Thanks!

mbuesch commented 8 years ago

Is somebody working on a patch/pull request with an initial implementation for this?

emilas44 commented 2 years ago

I love the razer naga trinity because of this feature (the side wheel click/tilt) Normally I use this mouse on Linux Ubuntu. By default when you buy the mouse those tilt buttons scroll up and down (fast, like rapid fire) With my first naga when I connected it to the Windows and installed razer synapse software, this default behavior was wiped out and some default profile was created... I could never get that behavior back... I don't have any macros I tried to reset the mouse to factory settings but nothing helps... I then bought the new Razer Naga Trinity which has this behavior (rapid scroll up/down) on wheel tilt buttons.

Maybe someone knows how to reset my old mouse so that it behaves like out of the box??? All the buttons are working on it, even the tilt buttons do work, but they are reversed and slugish/slow!