hardware – Disabling or Remapping Logitech G400 Mouse DPI Buttons

hardwaremouseusb-drive

I had the Logitech MX-518 mouse, but it had been having issues with responsiveness, causing me to call support for a replacement. Instead of another 518, they sent me a Logitech G400 mouse because the 518 has been discontinued. This causes issues because, while the MX518 was supported by lomoco, the G400 mouse is unsupported. Running $ lomoco -s shows 001.003: 046d:c245 Unsupported Logitech device: Unknown.

What I would like to do is lock the DPI of my mouse to a single value and remap the DPI+ and DPI- buttons to PgUp and PgDn on my keyboard.

How would I accomplish this?

Logitech G400

The buttons are, in order:

  1. Button 1: Left-click
  2. Button 2: Middle-click
  3. Button 3: Right-click
  4. Button 4: Mouse Wheel Up
  5. Button 5: Mouse Wheel Down
  6. Button 6: None
  7. Button 7: None
  8. Button 8: Thumb Button #1
  9. Button 9: Thumb Button #2
  10. Button 10: Task Switcher Button
  11. Button 11: None
  12. Button 12: None

On the previous mouse (MX 518), buttons 11 and 12 were the DPI keys. One of the things that makes these buttons different than the rest is that applications such as xev do not recognize pressing them as an event, by default. On the MX 518 mouse, in order to make those buttons able to be altered / binded, they had to first be disabled. I believe that lomoco called it "Logitech SmartScroll / Cruise Control." On the G400, lomoco doesn't work and I am unaware of an alternative.

Also, here is some output from xinput, in case it is helpful.

user@localhost:~$ xinput list
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Logitech Gaming Mouse G400                id=8    [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Power Button                              id=7    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=9    [slave  keyboard (3)]
user@localhost:~$ xinput list-props 8
Device 'Logitech Gaming Mouse G400':
    Device Enabled (121):   1
    Coordinate Transformation Matrix (123): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
    Device Accel Profile (248): 0
    Device Accel Constant Deceleration (249):   2.000000
    Device Accel Adaptive Deceleration (250):   1.000000
    Device Accel Velocity Scaling (251):    1.000000
    Device Product ID (238):    1133, 49733
    Device Node (239):  "/dev/input/event4"
    Evdev Axis Inversion (252): 0, 0
    Evdev Axes Swap (254):  0
    Axis Labels (255):  "Rel X" (131), "Rel Y" (132), "Rel Vert Wheel" (247)
    Button Labels (256):    "Button Left" (124), "Button Middle" (125), "Button Right" (126), "Button Wheel Up" (127), "Button Wheel Down" (128), "Button Horiz Wheel Left" (129), "Button Horiz Wheel Right" (130), "Button Side" (242), "Button Extra" (243), "Button Forward" (244), "Button Back" (245), "Button Task" (246), "Button Unknown" (241), "Button Unknown" (241), "Button Unknown" (241), "Button Unknown" (241)
    Evdev Middle Button Emulation (257):    0
    Evdev Middle Button Timeout (258):  50
    Evdev Third Button Emulation (259): 0
    Evdev Third Button Emulation Timeout (260): 1000
    Evdev Third Button Emulation Button (261):  3
    Evdev Third Button Emulation Threshold (262):   20
    Evdev Wheel Emulation (263):    0
    Evdev Wheel Emulation Axes (264):   0, 0, 4, 5
    Evdev Wheel Emulation Inertia (265):    10
    Evdev Wheel Emulation Timeout (266):    200
    Evdev Wheel Emulation Button (267): 4
    Evdev Drag Lock Buttons (268):  0

Best Answer

@Koviko - I have a similar mouse - a Logitech MX1100 - that also has DPI buttons that aren't sent to the USB when pressed in default mode. I did some testing on my own, and eventually was able to figure out the codes to send the signal to switch the mouse into "Driver Mode", which then allowed me to use easygestures/xev to reassign the buttons.

If you want, I can walk you through the steps I used to determine how to switch it off (I now have a script that I simply need to run on startup, as a very hack-y workaround, but it's working at least), but it involves setting up a VM and having a secondary mouse and sniffing the raw USB traffic, and unfortunately seems likely to be very mouse-specific.

My steps (better ones almost certainly exist):

1) Have a Windows VM (with the Logitech SetPoint software installed; I used VirtualBox, because that's what I already had set up with WinXP for work), Wireshark, and gcc installed on your system. 2) Then I ran the following steps in a terminal:

sudo modprobe usbmon
sudo wireshark &
sudo /usr/lib/virtualbox/VirtualBox &

3) Within Wireshark, choose to 'List the available capture interfaces...', and make a note of which USB bus number generates a ton of packets when you move your mouse around (mine was usbmon3, but I imagine that's purely based on which USB port your receiver is plugged in to).

3) From within VirtualBox (I needed to run as sudo in order to share the USB Controller), I edited the settings of the XP VM, and enabled both the USB Controller and the USB 2.0 (EHCI) Controller. Then I added a new USB Filter populated from an existing device, and selected my Logitech mouse's receiver (Vendor ID 046d, Product c245, for you) and then started up the VM.

(Note: After this point, I needed a second mouse plugged in, because I had to give control over my regular mouse to the Windows VM so that the SetPoint software could see that it existed as something more than a generic mouse.)

4) In the VM, I then launched the SetPoint software, and went to the screen that lets you set custom actions for various buttons. Then back in Wireshark, I started a capture on the USB bus for the mouse, then immediately went in to the VM/SetPoint, and changed the button assignment from DPI +/- to Keystroke Assignment, then immediately went back to Wireshark and stopped the capture. (I repeated this about 10-15 more times, changing the settings to different modes, mostly because I wasn't sure how much data I'd need, but after reviewing, I really only needed the first 1-2 captures.)

Assuming your mouse works vaguely similar to mine, which I'd guess it would, your capture would likely have a total of 16 frames, 4x GET DESCRIPTOR, then 3x(2xURB_CONTROL out + 2xURB_INTERRUPT in). What you're looking for are the 3 longer URB_CONTROL out frames. An example of one of my captured frames is:

0000  c0 80 64 36 00 88 ff ff  53 02 00 03 03 00 00 00
0010  5e 4b 25 50 00 00 00 00  f4 d9 08 00 8d ff ff ff
0020  07 00 00 00 07 00 00 00  21 09 10 02 01 00 07 00
0030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
0040  10 01 80 65 82 85 ff

What we're looking for are the last 7 bytes from the response (in the above, the '10 01 80 65 82 85 ff'), from each of the longer 'URB_CONTROL out' frames. Finally, I downloaded the source of the "g_hack" from Git, and cobbled in both my mouse product code at the top, and a new option (I set it to 0/1 with an if statement within them since it was just a very crude proof of concept) which would switch my mouse into "driver mode" or "DPI mode".

After that, all that was required was to set up the newly available mouse buttons in your choice of remapping programs (I used easygestures because that was the first thing with a UI I found - it may or may not have a superior replacement).

Related Question