mirror of https://github.com/OrbTools/OrbMap
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
3.3 KiB
Go
170 lines
3.3 KiB
Go
//go:build windows
|
|
// +build windows
|
|
|
|
package keypad
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"fmt"
|
|
|
|
"github.com/OrbTools/OrbCommon/hid"
|
|
"github.com/OrbTools/OrbMap/keyevents"
|
|
"github.com/google/gousb"
|
|
)
|
|
|
|
const (
|
|
leftControl byte = 0x1
|
|
leftShift byte = 0x2
|
|
leftAlt byte = 0x4
|
|
)
|
|
|
|
type swaps struct {
|
|
S1 *swapInt
|
|
S2 *swapInt
|
|
}
|
|
|
|
type swapInt struct {
|
|
K1 byte
|
|
K2 byte
|
|
K3 byte
|
|
K4 byte
|
|
K5 byte
|
|
K6 byte
|
|
K7 byte
|
|
K8 byte
|
|
K9 byte
|
|
}
|
|
|
|
func (s *swapInt) contains(k byte) bool {
|
|
return (s.K1 == k || s.K2 == k || s.K3 == k || s.K4 == k || s.K5 == k || s.K6 == k || s.K7 == k || s.K8 == k || s.K9 == k)
|
|
}
|
|
|
|
func (s *swaps) swap() {
|
|
ss := s.S1
|
|
s.S1 = s.S2
|
|
s.S2 = ss
|
|
}
|
|
|
|
func trans(M byte) []byte {
|
|
r := make([]byte, 0)
|
|
if (M & leftShift) != 0 {
|
|
r = append(r, byte(hid.GetMappingFromName("SHIFT_LEFT").Usb))
|
|
} else {
|
|
r = append(r, 0)
|
|
}
|
|
if (M & leftControl) != 0 {
|
|
r = append(r, byte(hid.GetMappingFromName("CONTROL_LEFT").Usb))
|
|
} else {
|
|
r = append(r, 0)
|
|
}
|
|
if (M & leftAlt) != 0 {
|
|
r = append(r, byte(hid.GetMappingFromName("ALT_LEFT").Usb))
|
|
} else {
|
|
r = append(r, 0)
|
|
}
|
|
return r
|
|
}
|
|
|
|
func (s *swapInt) Differ(s2 *swapInt) []byte {
|
|
r := make([]byte, 0)
|
|
if !s2.contains(s.K1) {
|
|
r = append(r, s.K1)
|
|
}
|
|
if !s2.contains(s.K2) {
|
|
r = append(r, s.K2)
|
|
}
|
|
if !s2.contains(s.K3) {
|
|
r = append(r, s.K3)
|
|
}
|
|
if !s2.contains(s.K4) {
|
|
r = append(r, s.K4)
|
|
}
|
|
if !s2.contains(s.K5) {
|
|
r = append(r, s.K5)
|
|
}
|
|
if !s2.contains(s.K6) {
|
|
r = append(r, s.K6)
|
|
}
|
|
if !s2.contains(s.K7) {
|
|
r = append(r, s.K7)
|
|
}
|
|
if !s2.contains(s.K8) {
|
|
r = append(r, s.K8)
|
|
}
|
|
if !s2.contains(s.K9) {
|
|
r = append(r, s.K9)
|
|
}
|
|
return r
|
|
}
|
|
|
|
//OrbLoop Main loop for this device
|
|
func (p *Keypad) OrbLoop(KeyBus chan *keyevents.KeyEvent) {
|
|
fmt.Println("Windows Loop Init")
|
|
ctx := gousb.NewContext()
|
|
dev, err := ctx.OpenDeviceWithVIDPID(gousb.ID(p.definition.Device.VendorID), gousb.ID(p.definition.Device.ProdID))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
fmt.Println("Device connected")
|
|
defer dev.Close()
|
|
conf, err := dev.Config(1)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
intf, err := conf.Interface(0, 0)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
fmt.Println("Windows Loop Interf")
|
|
defer intf.Close()
|
|
in, err := intf.InEndpoint(1)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
fmt.Println("Windows Loop Pointed")
|
|
data := make([]byte, in.Desc.MaxPacketSize)
|
|
rs, _ := in.NewStream(in.Desc.MaxPacketSize, 3)
|
|
swaper := new(swaps)
|
|
swaper.S1 = new(swapInt)
|
|
swaper.S2 = new(swapInt)
|
|
fmt.Println("Windows Loop Starting")
|
|
for {
|
|
_, err := rs.Read(data)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
addin := trans(data[0])
|
|
tdat := data[2:]
|
|
dat := append(addin, tdat...)
|
|
for i := 0; i < len(dat); i++ {
|
|
if dat[i] != 0 {
|
|
dat[i] = byte(hid.GetMappingFromHID(uint16(dat[i])).Evdev)
|
|
dat[i] = byte(p.keymaps.Maps[p.keymaps.Currentmap].Keymap[p.ecm[uint16(dat[i])]])
|
|
dat[i] = byte(hid.GetMappingFromLinux(uint16(dat[i])).Win)
|
|
}
|
|
}
|
|
err = binary.Read(bytes.NewReader(dat), binary.LittleEndian, swaper.S1)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
for _, pre := range swaper.S1.Differ(swaper.S2) {
|
|
if pre != 0 {
|
|
KeyEv := &keyevents.KeyEvent{}
|
|
KeyEv.Code = uint16(pre)
|
|
KeyEv.Type = 1
|
|
KeyBus <- KeyEv
|
|
}
|
|
}
|
|
for _, rel := range swaper.S2.Differ(swaper.S1) {
|
|
if rel != 0 {
|
|
KeyEv := &keyevents.KeyEvent{}
|
|
KeyEv.Code = uint16(rel)
|
|
KeyEv.Type = 2
|
|
KeyBus <- KeyEv
|
|
}
|
|
}
|
|
swaper.swap()
|
|
}
|
|
}
|