| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- package device
- import (
- "fmt"
- "sort"
- "netdome.biz/paul/qmk-rgb/internal/hid"
- )
- // Device is a connected QMK Raw HID keyboard.
- // Index is 1-based and is what --device accepts.
- type Device struct {
- Index int `json:"index"`
- Path string `json:"path"`
- VendorID uint16 `json:"vendorId"`
- ProductID uint16 `json:"productId"`
- Name string `json:"name,omitempty"`
- }
- // DiscoverAll returns every connected QMK Raw HID keyboard, ordered
- // deterministically and numbered from 1. A keyboard that does not report a USB
- // product string comes back with no Name; that costs the name and nothing else.
- func DiscoverAll() ([]Device, error) {
- infos, err := hid.DiscoverAll()
- if err != nil {
- return nil, fmt.Errorf("discover qmk devices: %w", err)
- }
- devices := make([]Device, 0, len(infos))
- for _, info := range infos {
- devices = append(devices, Device{
- Path: info.Path,
- VendorID: info.VendorID,
- ProductID: info.ProductID,
- Name: info.ProductString,
- })
- }
- return indexDevices(devices), nil
- }
- // indexDevices sorts devices deterministically and assigns 1-based indexes.
- // The input slice is left untouched.
- func indexDevices(devices []Device) []Device {
- sorted := make([]Device, len(devices))
- copy(sorted, devices)
- sort.SliceStable(sorted, func(i, j int) bool {
- a, b := sorted[i], sorted[j]
- switch {
- case a.VendorID != b.VendorID:
- return a.VendorID < b.VendorID
- case a.ProductID != b.ProductID:
- return a.ProductID < b.ProductID
- default:
- return a.Path < b.Path
- }
- })
- for i := range sorted {
- sorted[i].Index = i + 1
- }
- return sorted
- }
|