tolga9009 / sidewinderd

Linux support for Microsoft SideWinder X4 / X6 and Logitech G103 / G105 / G710+.

Home Page:http://cevel.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

G105 support and a more generic approach to Logitech G-Series keyboards

hanetzer opened this issue · comments

Hello, been using/testing your program with my G710 (yes, not the G710+. The two devices are apparently identical except for which switches are used for the keys) and I must say I rather like it so far. Some tweaks I'd like to see, but other than that, very useable.

I also have a G105, which I've dumped enoug info on to probably be addable to this as well, but most of the code would be pretty much identical to logitech_g710p.{c,h}pp that it would perhaps be better to generalize it somehow, but I'm not terribly good enough of a programmer to figure out myself.

The specifics are:

  • a 7 byte report with id 0x08 to null out the gkeys (they send f1-6 by default)
  • the g/mkeys send a 3 byte report in the format 0x03 gg mm, but m1 for example is 0x01 instead of 0x10 like the G710
  • the leds are controlled on report 0x06, but again, 0x01 instead of 0x10 and so on.

Hi!

My brother also got the G105, so I will very likely have the opportunity to reverse engineer it myself. Your findings definitely sound good to me. It should be possible to get the G105 running in no time.

But I agree, this program needs major refactoring (that's what this kind of process is called). I already came up with some ideas, to simplify and generalize the code, as there is already lots of redundancy between the SideWinder and G710 drivers.

More specifically, I'm thinking about adding an LED class, where information like LED bits (in your example 0x01, or 0x10) are called in the constructor, e.g. LED ledM1(0x06, 0x01), LED ledM2(0x06, 0x02). This way, we could set up LEDs in the constructor of each keyboard and eliminate all the featureRequest() stuff. We could use stuff like ledM1.on() or ledMR.blink() instead. Also, we could define LED class once and use it in the same manner for all keyboards.

Other than that, there is a similar situation with the SideWinder X4 / X6. There are minimal differences between both devices (X4: 6 macro buttons, X6: 30 macro buttons, detachable numpad/macropad, game-center key) and they both work with the same drivers. We could do the same for similar Logitech keyboards. Like define a general Logitech G-Keyboard driver and attach similar devices to the same driver interface.

I think this issue will somehow take care of itself, once more devices are added and we can identify similarities. There is a project, which faced and solved similar problems, I think we can learn from them: https://github.com/xboxdrv/xboxdrv/.

Would you mind sharing all your findings in detail about the G105? I'm fine with either, uncommented raw USB traffic or some kind of a self-written documentation. It would save me some time.

Cheers,
Tolga

here you go
(and yeah, I do know enough jargon to know its called refactoring :P ) I'm pretty good at analyzing stuff to know what needs to be done, but the implementation escapes me at times :/

Thank you, looks very useful! It should do the job. Also, there is information about G510 and G602 aswell, nice stuff!

Hahaha, sorry about that 😄!

Yeah, I'm in contact with a handful of people with access to these devices, besides personally owning a G710, G105, G602, and G430 myself.

Awesome! I'm also planning to add support for the G700 - the G602 logs will definitely help me. I'm not entirely sure though, if it's 100% possible. The G700 has onboard memory and supports hardware macros. Not sure, whether hardware macros can be programmed via hidraw or we need more low-level USB access (which would make everything more difficult and complex).

At that point, having a GUI for editing / creating macros would be awesome. I really like Microsoft's GUI:
microsoft1
microsoft2
microsoft3

But that's something for the future. Let's tackle the G105 first ^_^.

G602 can be done with hidraw, it uses logitech's prop. hid++ protocol, I've done it using python and hidapi for testing purposes. I still need to reverse out the rest of the stuff, though. Also, apparently it has a 'software mode' setting that one can use to use the on-disk profiles for (it seems you can only map one 'button' or 'key' to each G602 button at a time using its onboard memory)

Yepp, just checked on my Windows machine, the G700 also seems to support a software-mode, nice! As long as it's possible to set it to software-mode using hidraw, I think we should be fine.

Reverse engineering all that proprietary stuff for programming macros in hardware-mode won't be easy, yes. But it's probably not a game-breaking problem, after successfully setting the device to software-mode and beeing able to use something under Linux.

On another note, I could very likely clone the Logitech Gaming Software macro gui (may take a bit to be as snazzy as theirs, though). All your macros are are xml files anyways, simple enough.

There are some features I want to add to the GUI (like keeping track of active desktop Window, so we can implement per-application auto profiles) and I also want to define a socket IPC, so the GUI and sidewinderd can communicate (setting / reading active profile (auto profile especially), LED settings etc.).

As I'm also planning to port this over to Mac OS X, having a GUI with excellent cross-platform support would be awesome.

Also, please keep in mind, that I'm planning to drop XML in favor of JSON in version 0.4.0. But that shouldn't be an issue to fix in the GUI.

Yeah. personally I was thinking yaml when I was contemplating how to go about this. On another note, I hacked in what should be working 105 support, but something's not right. I think its the logic where it checks between 710/105

logitech_g105.cpp
logitech_g105.hpp
Source files with the needed tweaks. Granted, its n+1 amounts of code duplication, but it should give you the general idea. I think the g/mkey logic (inside LogitechG105::getInput) needs work, though, because I'm not sure what that bitwise magic you're using is doing.

In order to get your G105 detected, you will need to add the device VID & PID to device_data.cpp and also add some code in sidewinderd.cpp line 326. Currently, the code only distinguishes between Logitech VID and Microsoft VID. Code needs to be added to distinguish between G710 PID and G105 PID. Depending on the PID, the code needs to create the correct object.

I'm having my last exam tomorrow, I will work on this on saturday.

Cheers,
Tolga

ah, missed the device_data.cpp

Ok, fiddled and figured it all out. if its all the same to you, I can submit a PR adding G105 support (once again, with horrid code duplication 👎 ) or I can see about the refactor myself. I also have access to the data on a G19 btw. Working on sorting it out right now to add to my above linked repo :D

Hi there and sorry for not coming back to you sooner. It was just, that I've never thought about receiving a PR and wanted to avoid any kind of issues in the future (mainly copyright issues, due to the reverse engineering nature of this project). So, I've looked at bigger projects, how they managed PRs and Docker's and Linux Kernel's approach looked good to me, so I'm adapting their workflow.

Now I'm prepared for PRs and will gladly take your help! Thank you!

Thanks for the pull request! Logitech G105 support added in d8a964e. Closing.

@hanetzer @tolga9009 Sorry to open an old issue, but I'm trying to find how to unlock the GKeys from the FKeys on a G815 as I'd like to add it to this library. Are you able to provide any insight into how you found how to unlock it? I have seen that on a G910 it's unlocked by sending data like this:
https://github.com/MatMoul/g810-led/blob/master/src/classes/Keyboard.cpp#L667

Once I get the gkeys unlocked I'm pretty sure I can fumble my way through the rest to detect the M/G keys.