Skip to content

Instantly share code, notes, and snippets.

@HexF
Created July 18, 2021 15:26
Show Gist options
  • Save HexF/e8a94446315889d2f0a2917e14330565 to your computer and use it in GitHub Desktop.
Save HexF/e8a94446315889d2f0a2917e14330565 to your computer and use it in GitHub Desktop.
Logitech G105 Macro Keys on Linux

Logitech G105 Macro Keys on Linux

Through experimentation, and browsing the code of sidewinderd, I come to a conclustion as to how the keyboard communicates to the system.

Put simply, the keyboard uses HID Feature Reports, which we can manipulate with ioctl in c, or the python module hidapi.

Attached is example code, but this serves as documentation on the values of feature reports.

Macro Keys

The macro keys have 2 forms of operation - mimicing a scancode, or reporting the key press seperately in a report.

Either way, report #8 is used for this. It contains 6 bytes, which should be scancodes for the key, or 0 if you want no key mimicing.

A full list of scan codes can be found here.

To use polling, one should be reading packets from the device. These packets can be decoded, with the first byte being the packet ID. In the summary, there is a table explaining each one, but for macro polling we are interesting in packet id 3.

Packet #3 will always return 2 bytes with it. The first byte is the G-Keys pressed, the first bit position (LSB) relates to G1, with the 6th being G6. Similarly, the second byte is the M keys, and their bit positions (LSB = M1, M2, M3, MR).

With this information, you can work out the keys held down at any given point in time.

Media Keys

When holding the FN key down on the keyboard, the media keys (side-printed in red) can also be observed as packet #2.

Packet #2 contains bit positions for the 7 keys, with F12 being the LSB (bit 0), and F6 being bit 7.

Super Lock + Brightness

The Super Lock (Windows Lock) and Brightness keys also get reported under Packet #4. Bit position 1 is for the Super Lock key, and bit 2 is for the brighness key.

Macro LEDs

The LEDs on the M1, M2, M3 and MR keys can be individually controlled by reporting to #6.

M1 is mapped to bit position 1, M2 - 2, M3 - 3 and MR - 4.

Backlight Brighness

This one I haven't found anywhere else - but we can set the brighness of the backlight.

This is done through report #7, which expects 3 values, which looks to be an RGB value. My assumption here is that this keyboard controller outputs the 3 channels, just Logitech decided against RGB backlighting on this keyboard for cost reasons. The value we are interested in is the Blue value, which is the 3rd byte. These values can range from 0-255, taking up the full byte.

Summary

From this experimentation I have found the following reports we can poke at with HID Feature Reports.

ID 2 (input)

ID 2 contains currently held-down media key keys.

It should be noted, while listing here, media keys are not forwarded to the operating system (on linux).

Depending on which bits are set, determines which keys are held down. These keys are still subject to ghosting.

  • F12 (Fast Forward) = Bit 1
  • F11 (Rewind) = Bit 2
  • F10 (Stop) = Bit 3
  • F9 (Pause/Play) = Bit 4
  • F8 (Volume Up) = Bit 5
  • F7 (Volume Down) = Bit 6
  • F8 (Volume Mute) = Bit 7

ID 3 (input)

ID 3 contains the currently held-down G-Keys and M-Keys.

This ID reports 2 bytes (3 including ID), the first being for the G-Keys and the last being for M-Keys.

Depending on which bits are set, determines which keys are held down.

First Byte

  • G1 = Bit 1
  • G2 = Bit 2
  • G3 = Bit 3
  • G4 = Bit 4
  • G5 = Bit 5
  • G6 = Bit 6

Second Byte

  • M1 = Bit 1
  • M2 = Bit 2
  • M3 = Bit 3
  • M4 = Bit 4

ID 4 (input)

ID 4 contains the held state of the super-lock key and the brighness key.

It is returns a singular byte, where only the 2 LSBs can be set.

  • Super Lock = Bit 1
  • Brightness = Bit 2

ID 5 (feature)

The contents of this register is unknown.

ID 6 (feature)

This register sets the LEDs of the M1, M2, M3 and MR keys depending on the bits set.

A set bit indicates a lit LED.

  • M1 = Bit 1
  • M2 = Bit 2
  • M3 = Bit 3
  • M4 = Bit 4

ID 7 (feature)

This register contains 3 bytes for the backlight color/brightness. The first byte represents the red channel, the second the green, and the third the blue.

Each byte is a value from 0-255, mapping each value to a different brightness, with 0 being off, 255 being max.

ID 8 (feature)

This register contains the scancodes to output when one of the G-Keys are pressed, and as such there are 6 bytes.

These values are of HID Keyboard Scan Codes (0x07). If you wish for no output, and instead to read only, set a value of 0x00.

  • G1 = Byte 1
  • G2 = Byte 2
  • G3 = Byte 3
  • G4 = Byte 4
  • G5 = Byte 5
  • G6 = Byte 6

ID 9 (feature)

The contents of this register are unknown, however they seem to correspond with the currently selected backlight profile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment