| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- package device
- import (
- "encoding/json"
- "fmt"
- "os"
- "path/filepath"
- "github.com/wobkey/rgb/internal/hid"
- )
- // Keyboard represents a VIA-compatible keyboard from keyboards.json.
- type Keyboard struct {
- Name string `json:"name"`
- VendorID uint16 `json:"vendorId"`
- ProductID uint16 `json:"productId"`
- Protocol string `json:"protocol"`
- VIAVersion int `json:"viaVersion"`
- LEDLayout string `json:"ledLayout"`
- }
- // Device represents a connected keyboard device.
- type Device struct {
- Keyboard
- Path string
- }
- // LoadKeyboards reads keyboard definitions from keyboards.json.
- func LoadKeyboards() ([]Keyboard, error) {
- path, err := findKeyboardsJSON()
- if err != nil {
- return nil, fmt.Errorf("find keyboards.json: %w", err)
- }
- data, err := os.ReadFile(path)
- if err != nil {
- return nil, fmt.Errorf("read keyboards.json: %w", err)
- }
- var keyboards []Keyboard
- if err := json.Unmarshal(data, &keyboards); err != nil {
- return nil, fmt.Errorf("parse keyboards.json: %w", err)
- }
- return keyboards, nil
- }
- // findKeyboardsJSON searches for keyboards.json in common locations.
- var findKeyboardsJSON = func() (string, error) {
- exe, err := os.Executable()
- if err == nil {
- path := filepath.Join(filepath.Dir(exe), "keyboards.json")
- if _, err := os.Stat(path); err == nil {
- return path, nil
- }
- }
- path := "keyboards.json"
- if _, err := os.Stat(path); err == nil {
- return path, nil
- }
- cwd, err := os.Getwd()
- if err == nil {
- path := filepath.Join(cwd, "keyboards.json")
- if _, err := os.Stat(path); err == nil {
- return path, nil
- }
- }
- return "", fmt.Errorf("keyboards.json not found")
- }
- // Discover scans all HID devices and returns connected VIA-compatible keyboards.
- func Discover(keyboards []Keyboard) ([]Device, error) {
- devices, err := hid.DiscoverAll()
- if err != nil {
- return nil, fmt.Errorf("enumerate HID devices: %w", err)
- }
- fmt.Fprintf(os.Stderr, "DEBUG discover: keyboards=%d, hid_devices=%d\n", len(keyboards), len(devices))
- for _, kb := range keyboards {
- fmt.Fprintf(os.Stderr, "DEBUG discover: kb=%s VID=%d PID=%d\n", kb.Name, kb.VendorID, kb.ProductID)
- }
- for _, d := range devices {
- fmt.Fprintf(os.Stderr, "DEBUG discover: hid=%s VID=%d PID=%d raw=%t\n", d.Path, d.VendorID, d.ProductID, d.RawHID)
- }
- return matchKeyboards(keyboards, devices), nil
- }
- func matchKeyboards(keyboards []Keyboard, devices []hid.DeviceInfo) []Device {
- var found []Device
- for _, kb := range keyboards {
- for _, d := range devices {
- if !d.RawHID || d.VendorID != kb.VendorID || d.ProductID != kb.ProductID {
- continue
- }
- fmt.Fprintf(os.Stderr, "DEBUG discover: MATCH %s %s rawHID=true\n", kb.Name, d.Path)
- found = append(found, Device{
- Keyboard: kb,
- Path: d.Path,
- })
- }
- }
- fmt.Fprintf(os.Stderr, "DEBUG discover: found=%d\n", len(found))
- return found
- }
|