Skip to content

Commit 03b1d10

Browse files
committed
fix: correctly set keycodes
1 parent c2a2ce6 commit 03b1d10

File tree

14 files changed

+88
-56
lines changed

14 files changed

+88
-56
lines changed

collect.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// Package dump provides device state collector
21
package nuga
32

43
import (

device/state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ type LightsState struct {
77
CustomEffect []byte `json:"custom_effect"`
88
}
99

10-
// StateData represents raw keys state.
10+
// KeysState represents raw keys state.
1111
type KeysState struct {
1212
Mac []byte `json:"mac"`
1313
Win []byte `json:"win"`

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: 23 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,35 @@ type Key struct {
3032
// KeyMap represents keyboard layout
3133
type KeyMap map[layout.KeyName]Key
3234

35+
// SetKey sets key
36+
func (k KeyMap) SetKey(name layout.KeyName, value Key) error {
37+
if _, ok := k[name]; !ok {
38+
return ErrKeyNotFound
39+
}
40+
k[name] = value
41+
return nil
42+
}
43+
3344
// Bytes returns key map as bytes
34-
func (k KeyMap) Bytes(tpl *layout.Template) []byte {
35-
codes := make([]uint32, 256)
45+
func (k KeyMap) Bytes(tpl *layout.Template, defaults []byte) []byte {
46+
raw := make([]byte, len(defaults))
47+
copy(raw, defaults)
3648
for keyName, v := range k {
49+
var code uint32
3750
position := tpl.GetPosition(keyName)
3851
switch v.Type {
3952
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)
53+
code = layout.FindKeyCode(v.Keystroke.Name)
54+
if IsRegularKey(code) && v.Keystroke.Modifiers != nil {
55+
code = ApplyModifiers(code, v.Keystroke.Modifiers)
4356
}
4457
case ActionMacro:
45-
codes[position] = IndexToMacro(*v.MacroIndex)
46-
case ActionNone:
47-
codes[position] = 0
58+
code = IndexToMacro(*v.MacroIndex)
4859
}
60+
rawPosition := position * 4
61+
UnpackKeyCode(code, raw[rawPosition:rawPosition+4])
4962
}
50-
return UnpackKeyCodes(codes)
63+
return raw
5164
}
5265

5366
// 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/keys/state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func (s *State) Data(tpl *layout.Template, defaults *device.KeysState) (*device.
2727
}, nil
2828
}
2929

30-
// Parse raw state data.
30+
// ParseState parses raw state data.
3131
func ParseState(s *device.KeysState, tpl *layout.Template) (*State, error) {
3232
if tpl == nil {
3333
return nil, ErrNoTemplate

features/light/state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (s *State) Data(tpl *layout.Template) *device.LightsState {
2929
}
3030
}
3131

32-
// Parse raw state data.
32+
// ParseState parses raw state data.
3333
func ParseState(s *device.LightsState, tpl *layout.Template) (*State, error) {
3434
colors, err := ParseBacklightColors(s.Colors)
3535
if err != nil {

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)