Skip to content

Commit 3773c7e

Browse files
committed
fix: correctly set keycodes
1 parent c2a2ce6 commit 3773c7e

File tree

11 files changed

+120
-71
lines changed

11 files changed

+120
-71
lines changed

cmd/effects/main.go

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
package main
33

44
import (
5-
"fmt"
6-
75
"github.com/mishamyrt/nuga-lib"
6+
"github.com/mishamyrt/nuga-lib/features/keys"
7+
"github.com/mishamyrt/nuga-lib/layout"
88
"github.com/mishamyrt/nuga-lib/packages/cli"
99
)
1010

@@ -20,23 +20,40 @@ var (
2020
Run: func(_ []string) {
2121
dev, err := nuga.Open()
2222
cli.Must("open device", err)
23-
effects, err := dev.Features.Light.GetEffects()
24-
cli.Must("get effects", err)
25-
fmt.Println("Backlight")
26-
fmt.Printf(" Mode: %v\n", effects.Backlight.Mode.Name)
27-
fmt.Printf(" Color: %v\n", effects.Backlight.CurrentParams().Color)
28-
fmt.Printf(" Brightness: %v\n", effects.Backlight.CurrentParams().Brightness)
29-
fmt.Printf(" Speed: %v\n", effects.Backlight.CurrentParams().Speed)
30-
fmt.Println("Halo")
31-
fmt.Printf(" Mode: %v\n", effects.Halo.Mode.Name)
32-
fmt.Printf(" Color: %v\n", effects.Halo.Color)
33-
fmt.Printf(" Brightness: %v\n", effects.Halo.Brightness)
34-
fmt.Printf(" Speed: %v\n", effects.Halo.Speed)
35-
fmt.Println("Sidelight")
36-
fmt.Printf(" Mode: %v\n", effects.Sidelight.Mode.Name)
37-
fmt.Printf(" Color: %v\n", effects.Sidelight.Color)
38-
fmt.Printf(" Brightness: %v\n", effects.Sidelight.Brightness)
39-
fmt.Printf(" Speed: %v\n", effects.Sidelight.Speed)
23+
// effects, err := dev.Features.Light.GetEffects()
24+
// cli.Must("get effects", err)
25+
keyMap, err := dev.Features.Keys.GetMac()
26+
cli.Must("get keymap", err)
27+
keyMap.SetKey(layout.KeyB, keys.Key{
28+
Type: keys.ActionKeystroke,
29+
Keystroke: &keys.KeystrokeParams{
30+
Name: layout.KeyA,
31+
Modifiers: nil,
32+
},
33+
})
34+
// err = dev.Features.Keys.SetMac(keyMap)
35+
// cli.Must("set keymap", err)
36+
// localMap := *keyMap
37+
// fmt.Println(localMap[layout.KeyHome].Keystroke.Name)
38+
// keyMap.Bytes(layout.GetKeystrokeTemplate(dev.Name))
39+
// data, err := json.Marshal(&keyMap)
40+
// cli.Must("marshal effects", err)
41+
// fmt.Println(string(data))fghbccbcbnnnnnxzzsdfhfgjeryiyui
42+
// fmt.Println("Backlight")gh
43+
// fmt.Printf(" Mode: %v\n", effects.Backlight.Mode.Name)
44+
// fmt.Printf(" Color: %v\n", effects.Backlight.CurrentParams().Color)
45+
// fmt.Printf(" Brightness: %v\n", effects.Backlight.CurrentParams().Brightness)
46+
// fmt.Printf(" Speed: %v\n", effects.Backlight.CurrentParams().Speed)
47+
// fmt.Println("Halo")
48+
// fmt.Printf(" Mode: %v\n", effects.Halo.Mode.Name)
49+
// fmt.Printf(" Color: %v\n", effects.Halo.Color)
50+
// fmt.Printf(" Brightness: %v\n", effects.Halo.Brightness)
51+
// fmt.Printf(" Speed: %v\n", effects.Halo.Speed)
52+
// fmt.Println("Sidelight")
53+
// fmt.Printf(" Mode: %v\n", effects.Sidelight.Mode.Name)
54+
// fmt.Printf(" Color: %v\n", effects.Sidelight.Color)
55+
// fmt.Printf(" Brightness: %v\n", effects.Sidelight.Brightness)
56+
// fmt.Printf(" Speed: %v\n", effects.Sidelight.Speed)
4057
},
4158
}
4259
)

examples/keycodes/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"fmt"
77
"os"
88

9-
"github.com/mishamyrt/nuga-lib/dump"
9+
"github.com/mishamyrt/nuga-lib/device"
1010
"github.com/mishamyrt/nuga-lib/examples/keycodes/annotation"
1111
"github.com/mishamyrt/nuga-lib/examples/keycodes/keymap"
1212
"github.com/mishamyrt/nuga-lib/features/keys"
@@ -25,7 +25,7 @@ func main() {
2525
if err != nil {
2626
die("Error reading file: %v", err)
2727
}
28-
var state dump.State
28+
var state device.State
2929
err = json.Unmarshal(data, &state)
3030
if err != nil {
3131
die("Error unmarshalling: %v", err)

features/features.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ type LightFeature interface {
2222
SetBacklightColors(*light.BacklightColors) error
2323
GetCustomEffect() (*light.CustomEffectMap, error)
2424
SetCustomEffect(*light.CustomEffectMap) error
25-
GetStateData() (*light.StateData, error)
26-
SetStateData(*light.StateData) error
25+
GetStateData() (*device.LightsState, error)
26+
SetStateData(*device.LightsState) error
2727
}
2828

2929
// KeysFeature represents keyboard keys feature
@@ -34,14 +34,18 @@ type KeysFeature interface {
3434
SetMac(keyMap *keys.KeyMap) error
3535
GetMacros() (keys.Macros, error)
3636
SetMacros(macros keys.Macros) error
37-
GetStateData() (*keys.StateData, error)
38-
SetStateData(*keys.StateData) error
37+
GetStateData() (*device.KeysState, error)
38+
SetStateData(*device.KeysState) error
3939
}
4040

4141
// New creates Features instance with handle
42-
func New(dev hid.Handler, model device.Model) *Features {
42+
func New(dev hid.Handler, model device.Model) (*Features, error) {
43+
k, err := keys.New(dev, model)
44+
if err != nil {
45+
return nil, err
46+
}
4347
return &Features{
4448
Light: light.New(dev, model),
45-
Keys: keys.New(dev, model),
46-
}
49+
Keys: k,
50+
}, nil
4751
}

features/keys/errors.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ var ErrWrongMacroHeader = errors.New("wrong macro header. Must be 0x85")
1616

1717
// ErrWrongLength is returned when slice length is wrong
1818
var ErrWrongLength = errors.New("slice should be of length 4")
19+
20+
// ErrKeyNotFound is returned when key not found
21+
var ErrKeyNotFound = errors.New("key not found")

features/keys/feature.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,35 @@ import (
1111
type Feature struct {
1212
handle hid.Handler
1313
template *layout.Template
14+
defaults *device.KeysState
1415
}
1516

1617
// New creates keys feature instance.
17-
func New(handle hid.Handler, model device.Model) *Feature {
18+
func New(handle hid.Handler, model device.Model) (*Feature, error) {
19+
template := layout.GetKeystrokeTemplate(model)
20+
state, err := device.GetDefaults(model)
21+
if err != nil {
22+
return nil, err
23+
}
1824
return &Feature{
1925
handle: handle,
20-
template: layout.GetKeystrokeTemplate(model),
21-
}
26+
template: template,
27+
defaults: state.Data.Keys,
28+
}, nil
2229
}
2330

2431
// GetWin returns win keyboard keys
2532
func (f *Feature) GetWin() (*KeyMap, error) {
26-
return f.getKeys(cmdGetWinKeys)
33+
m, err := f.getKeys(cmdGetWinKeys)
34+
if err != nil {
35+
return nil, err
36+
}
37+
return m, nil
2738
}
2839

2940
// SetWin sets win keyboard keys
3041
func (f *Feature) SetWin(keyMap *KeyMap) error {
31-
return f.setKeys(cmdSetWinKeys, keyMap)
42+
return f.setKeys(cmdSetWinKeys, keyMap, f.defaults.Win)
3243
}
3344

3445
// GetMac returns mac keyboard keys
@@ -38,7 +49,7 @@ func (f *Feature) GetMac() (*KeyMap, error) {
3849

3950
// SetMac sets mac keyboard keys
4051
func (f *Feature) SetMac(keyMap *KeyMap) error {
41-
return f.setKeys(cmdSetMacKeys, keyMap)
52+
return f.setKeys(cmdSetMacKeys, keyMap, f.defaults.Mac)
4253
}
4354

4455
// GetRawMacros returns raw keyboard macros
@@ -77,7 +88,7 @@ func (f *Feature) SetMacros(macros Macros) error {
7788
}
7889

7990
// GetStateData returns current raw keys state
80-
func (f *Feature) GetStateData() (*StateData, error) {
91+
func (f *Feature) GetStateData() (*device.KeysState, error) {
8192
mac, err := f.getRawKeys(cmdGetMacKeys)
8293
if err != nil {
8394
return nil, err
@@ -90,15 +101,15 @@ func (f *Feature) GetStateData() (*StateData, error) {
90101
if err != nil {
91102
return nil, err
92103
}
93-
return &StateData{
104+
return &device.KeysState{
94105
Mac: mac,
95106
Win: win,
96107
Macros: macros,
97108
}, nil
98109
}
99110

100111
// SetStateData sets current raw keys state
101-
func (f *Feature) SetStateData(data *StateData) error {
112+
func (f *Feature) SetStateData(data *device.KeysState) error {
102113
if err := f.setRawKeys(cmdSetMacKeys, data.Mac); err != nil {
103114
return err
104115
}
@@ -142,10 +153,10 @@ func (f *Feature) getKeys(cmd []byte) (*KeyMap, error) {
142153
return keys, nil
143154
}
144155

145-
func (f *Feature) setKeys(cmdSet []byte, keys *KeyMap) error {
156+
func (f *Feature) setKeys(cmdSet []byte, keys *KeyMap, defaults []byte) error {
146157
if f.template == nil {
147158
return ErrNoTemplate
148159
}
149-
raw := keys.Bytes(f.template)
160+
raw := keys.Bytes(f.template, defaults)
150161
return f.setRawKeys(cmdSet, raw)
151162
}

features/keys/feature_simulation.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,21 @@ import (
88
// FeatureSimulation represents simulated keys feature.
99
type FeatureSimulation struct {
1010
state *State
11+
defaults *device.KeysState
1112
template *layout.Template
1213
}
1314

1415
// NewSimulation creates simulated keys from template.
15-
func NewSimulation(s *StateData, model device.Model) (*FeatureSimulation, error) {
16+
func NewSimulation(s *device.KeysState, model device.Model) (*FeatureSimulation, error) {
1617
var (
1718
f FeatureSimulation
1819
err error
1920
)
21+
22+
f.defaults = s
2023
f.template = layout.GetKeystrokeTemplate(model)
2124
if f.template != nil {
22-
f.state, err = s.Parse(f.template)
25+
f.state, err = ParseState(s, f.template)
2326
}
2427
if err != nil {
2528
return nil, err
@@ -79,23 +82,23 @@ func (f *FeatureSimulation) SetMacros(m Macros) error {
7982
}
8083

8184
// GetStateData returns current simulated state.
82-
func (f *FeatureSimulation) GetStateData() (*StateData, error) {
85+
func (f *FeatureSimulation) GetStateData() (*device.KeysState, error) {
8386
if f.template == nil {
84-
return &StateData{
87+
return &device.KeysState{
8588
Mac: make([]byte, 1024),
8689
Win: make([]byte, 1024),
8790
Macros: make([]byte, 1024),
8891
}, nil
8992
}
90-
return f.state.Data(f.template)
93+
return f.state.Data(f.template, f.defaults)
9194
}
9295

9396
// SetStateData sets current simulated state.
94-
func (f *FeatureSimulation) SetStateData(s *StateData) error {
97+
func (f *FeatureSimulation) SetStateData(s *device.KeysState) error {
9598
if f.template == nil {
9699
return ErrNoTemplate
97100
}
98-
state, err := s.Parse(f.template)
101+
state, err := ParseState(s, f.template)
99102
if err != nil {
100103
return err
101104
}

features/keys/keycode.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@ func UnpackKeyCodes(v []uint32) []byte {
2020
var offset int
2121
for i := 0; i < len(v); i++ {
2222
offset = (i * 4)
23-
payload[offset] = byte(v[i] & 0xFF)
24-
payload[offset+1] = byte((v[i] >> 8) & 0xFF)
25-
payload[offset+2] = byte((v[i] >> 16) & 0xFF)
26-
payload[offset+3] = byte((v[i] >> 24) & 0xFF)
23+
UnpackKeyCode(v[i], payload[offset:offset+4])
2724
}
2825
return payload
2926
}
27+
28+
// UnpackKeyCode unpacks key code to target slice
29+
func UnpackKeyCode(v uint32, target []byte) {
30+
target[0] = byte(v & 0xFF)
31+
target[1] = byte((v >> 8) & 0xFF)
32+
target[2] = byte((v >> 16) & 0xFF)
33+
target[3] = byte((v >> 24) & 0xFF)
34+
}

features/keys/keycode_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ var keyCodes = []uint32{
1515
func TestPackKeyCodes(t *testing.T) {
1616
t.Parallel()
1717
result := PackKeyCodes(rawBytes)
18-
// Check some random values
1918
for i, v := range keyCodes {
2019
if result[i] != v {
2120
t.Errorf("result[%d] = %02x, want %02x", i, result[i], v)

features/keys/keymap.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package keys
22

3-
import "github.com/mishamyrt/nuga-lib/layout"
3+
import (
4+
"github.com/mishamyrt/nuga-lib/layout"
5+
)
46

57
// ActionType represents action type
68
type ActionType string
@@ -30,24 +32,34 @@ type Key struct {
3032
// KeyMap represents keyboard layout
3133
type KeyMap map[layout.KeyName]Key
3234

35+
func (k KeyMap) SetKey(name layout.KeyName, value Key) error {
36+
if _, ok := k[name]; !ok {
37+
return ErrKeyNotFound
38+
}
39+
k[name] = value
40+
return nil
41+
}
42+
3343
// Bytes returns key map as bytes
34-
func (k KeyMap) Bytes(tpl *layout.Template) []byte {
35-
codes := make([]uint32, 256)
44+
func (k KeyMap) Bytes(tpl *layout.Template, defaults []byte) []byte {
45+
raw := make([]byte, len(defaults))
46+
copy(raw, defaults)
3647
for keyName, v := range k {
48+
var code uint32
3749
position := tpl.GetPosition(keyName)
3850
switch v.Type {
3951
case ActionKeystroke:
40-
codes[position] = layout.FindKeyCode(v.Keystroke.Name)
41-
if IsRegularKey(codes[position]) && v.Keystroke.Modifiers != nil {
42-
codes[position] = ApplyModifiers(codes[position], v.Keystroke.Modifiers)
52+
code = layout.FindKeyCode(v.Keystroke.Name)
53+
if IsRegularKey(code) && v.Keystroke.Modifiers != nil {
54+
code = ApplyModifiers(code, v.Keystroke.Modifiers)
4355
}
4456
case ActionMacro:
45-
codes[position] = IndexToMacro(*v.MacroIndex)
46-
case ActionNone:
47-
codes[position] = 0
57+
code = IndexToMacro(*v.MacroIndex)
4858
}
59+
rawPosition := position * 4
60+
UnpackKeyCode(code, raw[rawPosition:rawPosition+4])
4961
}
50-
return UnpackKeyCodes(codes)
62+
return raw
5163
}
5264

5365
// ParseKeyMap key map from values

features/keys/keymap_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ func TestBytes(t *testing.T) {
6464
{layout.KeyY, keys.IndexToMacro(1)},
6565
{layout.KeyR, layout.Keys[layout.KeyNone].Code},
6666
}
67-
raw := testKeyMap.Bytes(&testTemplate)
67+
defaultsMock := make([]byte, len(tests)*4)
68+
raw := testKeyMap.Bytes(&testTemplate, defaultsMock)
6869
codes := keys.PackKeyCodes(raw)
6970

7071
if len(codes) < len(testTemplate) {

features/simulation.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,13 @@ import (
77
"github.com/pkg/errors"
88
)
99

10-
// StateData represents raw features state. It contains data of all supported features
11-
type StateData struct {
12-
Lights *light.StateData `json:"lights"`
13-
Keys *keys.StateData `json:"keys"`
14-
}
15-
1610
// NewSimulation creates simulated features from state
17-
func NewSimulation(s *StateData, model device.Model) (*Features, error) {
18-
l, err := light.NewSimulation(s.Lights, model)
11+
func NewSimulation(s *device.State) (*Features, error) {
12+
l, err := light.NewSimulation(s.Data.Lights, s.Model)
1913
if err != nil {
2014
return nil, errors.Wrap(err, "lights")
2115
}
22-
k, err := keys.NewSimulation(s.Keys, model)
16+
k, err := keys.NewSimulation(s.Data.Keys, s.Model)
2317
if err != nil {
2418
return nil, errors.Wrap(err, "keys")
2519
}

0 commit comments

Comments
 (0)