My G815 Keyboard is on Steroids (Shortcut helper)
Tags: go, productivity, watercooler, showdev
Published: 2020-08-29 17:11:48

# Logitech G815 Shortcut Helper

I wrote a small shortcut helper in GoLang that helps me to remember the most useful shortcuts for IntelliJ based products tested with **Rider** and **GoLand** and a QWERTZ keyboard.

![](https://github.com/klyse/LogitechKeyboardLED/blob/master/Images/example2.gif?raw=true)

## Intro

I recently bought a [Logitech G815](https://www.logitechg.com/en-us/products/gaming-keyboards/g815-low-profile-rgb-mechanical-gaming-keyboard.html) which turned out to be a great decision for multiple reasons. The obvious one being that it's a great keyboard ✨. The other one is that I found out Logitech provides an SDK for the keyboard => 👌.

![](https://resource.logitechg.com/w_1800,c_limit,f_auto,q_auto:best,f_auto,dpr_auto/content/dam/gaming/en/products/g815/g815-intro-desktop.png?v=1)

### RGB Keys

The keyboard supports RGB background lighting for each key. There are plenty of integrated functions such as a color wave which looks great🌟. The keyboard is made for gaming purposes and yes it does integrate with a lot of games but I didn't try any myself🙈.

# SDK

The Logitech SDK can be found on this website: https://www.logitechg.com/en-us/innovation/developer-lab.html.

I was particularly interested in the LED Illumination SDK.

The SKD is written in C++ and provides the .lib, .h, .dll, and some examples and is **windows only**.

## Integration with GO

I'm currently learning **GoLang** and I wanted to program this in go and not in C++ or C#.

### Calling native C++ functions from GO

I found a great way to call native C++ functions from Go using the ``sys`` module.

Original repo: https://github.com/golang/go/wiki/WindowsDLLs

```go
type LogiKeyboard struct {
    dll                             *windows.LazyDLL
    ledInit                         *windows.LazyProc
    // ...
}

func Create() *LogiKeyboard {
    p := new(LogiKeyboard)

    // initialization of the dll
    p.dll = windows.NewLazyDLL("LogitechLedEnginesWrapper.dll")
    
    // assign the function
    p.ledInit = p.dll.NewProc("LogiLedInit")
    //...
    return p
}

// wrapper for the init function
func (v LogiKeyboard) Init() {
    ret, _, _ := v.ledInit.Call()

    if ret != 1 {
        log.Fatal("Already initialized")
    }
}

```

Additionally, I had to translate the .h file in go syntax. This helps to have all the constants (like defines) in one place and reduce code duplication. [Here](https://github.com/klyse/LogitechKeyboardLED/blob/master/LogiKeyboardTypes/KeyboardTypes.go) is the file.

# Integration with Windows

I needed a slim and easy way to catch Windows keystrokes. Turns out there is a great module for that as well: [github.com/moutend/go-hook](https://github.com/moutend/go-hook).

main.go:
```go
if err := run(shortcuts); err != nil {
    log.Fatal(err)
}

func run(shortcuts []Shortcuts.Shortcut) error {
    // Buffer size is depends on your need. The 100 is placeholder value.
    keyboardChan := make(chan types.KeyboardEvent, 100)
    if err := keyboard.Install(nil, keyboardChan); err != nil {
        return err
    }
    
    signalChan := make(chan os.Signal, 1)
    signal.Notify(signalChan, os.Interrupt)
    for {
        select {
        case <-time.After(5 * time.Minute):
            fmt.Println("Received timeout signal")
            return nil
        case <-signalChan:
            fmt.Println("Received shutdown signal")
            return nil
        case k := <-keyboardChan:
            // check if shortcut modifiers are pressed and set RGB color
        }
        continue
    }
}
```


Those few lines of code are everything you need to create a keylogger in go. Isn't that crazy?

# Shortcuts

Shortcuts can be modified in ``main.go``:

```go
var shortcuts = []Shortcuts.Shortcut{
    // if the left shift key is presed:
    // F6 will start blinking red
    // F9 will change the color to blue
    Shortcuts.CreateWithKey([]types.VKCode{types.VK_LSHIFT}, []Shortcuts.ShortcutKey{
        Shortcuts.CreateKeyColorEffect(LogiKeyboardTypes.F6, 100, 0, 0, Shortcuts.Blinking),
        Shortcuts.CreateKeyColor(LogiKeyboardTypes.F9, 0, 0, 100),
    }),
    //...
    }
```

# Integration with Logitech GHub

The keyboard has five G keys and each key can be assigned with a different task. One task is to launch an application => great :). The downside of this function is that an application can be started but not stopped. I wanted to start and stop the shortcut helper with the same key just like a toggle.

As always there is a workaround in PowerShell😂:

```ps
Set-Location -Path C:\Projects\LogitechKeyboardLED

$ProcessActive = (Get-Process logitechKeyboardLed -ErrorAction SilentlyContinue).Id
if($null -eq $ProcessActive)
{
    Start-Process ./logitechKeyboardLed.exe -NoNewWindow
}
else
{
    Stop-Process $ProcessActive
}

```
Configure the G key using the ``Launch Application`` option:
![](https://github.com/klyse/LogitechKeyboardLED/raw/master/Images/GHubConfig.png)

# Shortcuthelper in action

![](https://github.com/klyse/LogitechKeyboardLED/raw/master/Images/example.gif)

# Github Repo
{% github https://github.com/klyse/LogitechKeyboardLED %}

Thanks for reading :)