| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 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 for connected VIA-compatible keyboards.
- func Discover(keyboards []Keyboard) ([]Device, error) {
- var found []Device
- for _, kb := range keyboards {
- err := hid.Enumerate(kb.VendorID, kb.ProductID, func(info *hid.DeviceInfo) error {
- found = append(found, Device{
- Keyboard: kb,
- Path: info.Path,
- })
- return nil
- })
- if err != nil {
- return nil, fmt.Errorf("enumerate VID=0x%04x PID=0x%04x: %w", kb.VendorID, kb.ProductID, err)
- }
- }
- fmt.Fprintf(os.Stderr, "DEBUG discover: found %d keyboard(s)\n", len(found))
- for _, d := range found {
- fmt.Fprintf(os.Stderr, "DEBUG discover: %s path=%s VID=0x%04x PID=0x%04x\n", d.Name, d.Path, d.VendorID, d.ProductID)
- }
- return found, nil
- }
|