migrate
This commit is contained in:
53
app/Makefile
Normal file
53
app/Makefile
Normal file
@@ -0,0 +1,53 @@
|
||||
##
|
||||
##
|
||||
##
|
||||
|
||||
.PHONY: help all linux darwin windows cli
|
||||
|
||||
help: ## This help.
|
||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
bin/:
|
||||
@mkdir -p bin
|
||||
|
||||
all: ## build linux, darwin & windows
|
||||
all: linux darwin windows
|
||||
|
||||
cli: linux-cli windows-cli darwin-cli
|
||||
|
||||
linux: linux-cli
|
||||
windows: windows-cli
|
||||
darwin: darwin-cli
|
||||
|
||||
linux-cli: bin/ ## build linux binary
|
||||
@GOOS=linux GOARCH=amd64 CGO_ENABLED=1 \
|
||||
go build \
|
||||
-installsuffix cgo -ldflags=" -s -w" \
|
||||
-o bin/beeon-cli-linux-amd64 \
|
||||
microjelly.com/beeon/app/cmd/cli
|
||||
|
||||
darwin-cli: bin/ ## build darwin binary
|
||||
@GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 \
|
||||
CC=o64-clang CXX=o64-clang++ \
|
||||
LDFLAGS="-linkmode external -s" \
|
||||
go build \
|
||||
-installsuffix cgo -ldflags=" -s -w" \
|
||||
-o bin/beeon-cli-darwin-amd64 \
|
||||
microjelly.com/beeon/app/cmd/cli
|
||||
|
||||
windows-cli: bin/ ## build windows binary
|
||||
@GOOS=windows GOARCH=amd64 CGO_ENABLED=1 \
|
||||
CC=x86_64-w64-mingw32-gcc \
|
||||
go build \
|
||||
-installsuffix cgo -ldflags=" -s -w" \
|
||||
-o bin/beeon-cli-windows-amd64.exe \
|
||||
microjelly.com/beeon/app/cmd/cli
|
||||
|
||||
mod-tidy:
|
||||
@go clean --modcache
|
||||
@GOPROXY=direct GOSUMDB=off go mod tidy
|
||||
|
||||
clean:
|
||||
@rm -rf bin
|
||||
3
app/build/.gitignore
vendored
Normal file
3
app/build/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
Dockerfile.dapper[0-9]*
|
||||
.dapper
|
||||
bin/
|
||||
10
app/build/Dockerfile.dapper
Normal file
10
app/build/Dockerfile.dapper
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM dockercore/golang-cross:latest
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y -q --no-install-recommends libusb-1.0-0-dev
|
||||
|
||||
ENV DAPPER_SOURCE /source
|
||||
ENV DAPPER_OUTPUT ./build/bin
|
||||
WORKDIR ${DAPPER_SOURCE}
|
||||
|
||||
ENTRYPOINT ["./build/scripts/entry"]
|
||||
CMD ["cli"]
|
||||
22
app/build/Makefile
Normal file
22
app/build/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
TARGETS := $(shell ls scripts)
|
||||
|
||||
.dapper:
|
||||
@echo Downloading dapper
|
||||
@curl -sL https://releases.rancher.com/dapper/latest/dapper-`uname -s`-`uname -m` > .dapper.tmp
|
||||
@@chmod +x .dapper.tmp
|
||||
@./.dapper.tmp -v
|
||||
@mv .dapper.tmp .dapper
|
||||
|
||||
$(TARGETS): .dapper
|
||||
cd ../ && $(PWD)/.dapper -f build/Dockerfile.dapper $@
|
||||
@yes | docker image prune > /dev/null
|
||||
|
||||
.PHONY: $(TARGETS)
|
||||
.DEFAULT_GOAL := cli
|
||||
|
||||
clean:
|
||||
@rm -rf $(PWD)/bin $(PWD)/.dapper $(PWD)/Dockerfile.dapper[0-9]*
|
||||
@docker rmi app:master
|
||||
|
||||
shell-bind: .dapper
|
||||
cd ../ && $(PWD)/.dapper -f build/Dockerfile.dapper -m bind -s
|
||||
7
app/build/scripts/cli
Executable file
7
app/build/scripts/cli
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
## multi-platform cli build
|
||||
make cli
|
||||
cp bin/*cli* ${DAPPER_OUTPUT}/
|
||||
ls -la ${DAPPER_OUTPUT}/*cli*
|
||||
13
app/build/scripts/entry
Executable file
13
app/build/scripts/entry
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
mkdir -p ${DAPPER_OUTPUT}
|
||||
if [ -e ${DIR}/$1 ]; then
|
||||
${DIR}/"$@"
|
||||
else
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
chown -R $DAPPER_UID:$DAPPER_GID ${DAPPER_OUTPUT}
|
||||
208
app/cmd/cli/cli.go
Normal file
208
app/cmd/cli/cli.go
Normal file
@@ -0,0 +1,208 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"microjelly.com/beeon/app/pkg/device"
|
||||
"microjelly.com/beeon/app/pkg/device/keycodes"
|
||||
"microjelly.com/beeon/app/pkg/device/report3"
|
||||
)
|
||||
|
||||
var (
|
||||
appVersion string = "1.01"
|
||||
vendorID uint16 = 0x16d0
|
||||
productID uint16 = 0x09fa
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
var (
|
||||
action string = "none"
|
||||
serialNumber string = ""
|
||||
inState string = ""
|
||||
newState report3.State = report3.StateUnset
|
||||
inRate string = ""
|
||||
newRate report3.Rate = report3.RateUnset
|
||||
newMode report3.Mode = report3.ModeUnset
|
||||
inMouseMode string = ""
|
||||
newMouseMode report3.MouseMode = report3.MouseModeUnset
|
||||
inKeyCode uint = 256
|
||||
newKeyCode keycodes.KeyCode = keycodes.KeyUnset
|
||||
)
|
||||
|
||||
debugFlag := flag.Bool("debug", false, "enable debug logging")
|
||||
listFlag := flag.Bool("list", false, "list connected devices")
|
||||
readFlag := flag.Bool("read", false, "read device config")
|
||||
flag.StringVar(&serialNumber, "serial", "", "target specific device by serial_number")
|
||||
flag.StringVar(&inState, "state", "", "change device state <idle|active>")
|
||||
flag.StringVar(&inRate, "rate", "", "change device rate <extra-slow|slow|normal|fast>")
|
||||
flag.StringVar(&inMouseMode, "mouse", "", "change to mouse mode and set mode <circle|random>")
|
||||
flag.UintVar(&inKeyCode, "keyboard", 256, "change to keyboard mode and set keycod")
|
||||
flag.Parse()
|
||||
|
||||
if *debugFlag {
|
||||
device.SetLogLevel(device.LogDebug)
|
||||
}
|
||||
|
||||
if *listFlag {
|
||||
action = "list"
|
||||
} else if *readFlag {
|
||||
action = "read"
|
||||
}
|
||||
|
||||
log.Printf("beeon-cli core:%s usb:%t", device.Version(), device.UsbSupported())
|
||||
|
||||
if serialNumber != "" {
|
||||
log.Printf("serial:%s", serialNumber)
|
||||
}
|
||||
|
||||
if action == "list" {
|
||||
devs, err := device.Enumerate(vendorID, productID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i, _dev := range devs {
|
||||
log.Printf("[%d] %s:v%s:%s:%s",
|
||||
i,
|
||||
_dev.Serial,
|
||||
fmt.Sprintf("%d.%02d", (_dev.Version&0xff00)>>8, (_dev.Version&0x00ff)),
|
||||
_dev.Manufacturer,
|
||||
_dev.Product,
|
||||
)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if action == "read" {
|
||||
r3, err := device.ReadReport3(vendorID, productID, serialNumber)
|
||||
if err != nil {
|
||||
log.Printf(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Printf("%+v", r3)
|
||||
}
|
||||
|
||||
if inMouseMode != "" {
|
||||
switch strings.ToLower(inMouseMode) {
|
||||
case "circle":
|
||||
newMouseMode = report3.MouseModeCircle
|
||||
newMode = report3.ModeMouse
|
||||
action = "write"
|
||||
case "random":
|
||||
newMouseMode = report3.MouseModeRandom
|
||||
newMode = report3.ModeMouse
|
||||
action = "write"
|
||||
default:
|
||||
log.Printf("invalid mouse-mode %s", inMouseMode)
|
||||
}
|
||||
}
|
||||
|
||||
if inKeyCode != 256 && action == "none" {
|
||||
newKeyCode = keycodes.KeyCode(inKeyCode)
|
||||
newMode = report3.ModeKeyboard
|
||||
action = "write"
|
||||
}
|
||||
|
||||
if inState != "" {
|
||||
switch strings.ToLower(inState) {
|
||||
case "idle":
|
||||
newState = report3.StateIdle
|
||||
action = "write"
|
||||
case "active":
|
||||
newState = report3.StateActive
|
||||
action = "write"
|
||||
default:
|
||||
log.Printf("invalid state %s", inState)
|
||||
}
|
||||
}
|
||||
|
||||
if inRate != "" {
|
||||
switch strings.ToLower(inRate) {
|
||||
case "extra-slow":
|
||||
newRate = report3.RateExtraSlow
|
||||
action = "write"
|
||||
case "slow":
|
||||
newRate = report3.RateSlow
|
||||
action = "write"
|
||||
case "normal":
|
||||
newRate = report3.RateNormal
|
||||
action = "write"
|
||||
case "fast":
|
||||
newRate = report3.RateFast
|
||||
action = "write"
|
||||
default:
|
||||
log.Printf("invalid rate %s", inRate)
|
||||
}
|
||||
}
|
||||
|
||||
if action == "none" {
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if action == "write" {
|
||||
hasChange := false
|
||||
whatChanged := []string{}
|
||||
r3, err := device.ReadReport3(vendorID, productID, serialNumber)
|
||||
if err != nil {
|
||||
log.Printf(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if (newMode != report3.ModeUnset) && (r3.Mode != newMode) {
|
||||
whatChanged = append(whatChanged, fmt.Sprintf("Mode(%s>%s)", r3.Mode, newMode))
|
||||
r3.Mode = newMode
|
||||
hasChange = true
|
||||
} else {
|
||||
r3.Mode = report3.ModeUnset
|
||||
}
|
||||
|
||||
if newKeyCode != keycodes.KeyUnset && (newKeyCode != r3.KeyCode) {
|
||||
whatChanged = append(whatChanged, fmt.Sprintf("KeyCode(%s>%s)", r3.KeyCode, newKeyCode))
|
||||
r3.KeyCode = newKeyCode
|
||||
hasChange = true
|
||||
} else {
|
||||
r3.KeyCode = keycodes.KeyUnset
|
||||
}
|
||||
|
||||
if newMouseMode != report3.MouseModeUnset && (newMouseMode != r3.MouseMode) {
|
||||
whatChanged = append(whatChanged, fmt.Sprintf("MouseMode(%s>%s)", r3.MouseMode, newMouseMode))
|
||||
r3.MouseMode = newMouseMode
|
||||
hasChange = true
|
||||
} else {
|
||||
r3.MouseMode = report3.MouseModeUnset
|
||||
}
|
||||
|
||||
if newState != report3.StateUnset && (newState != r3.State) {
|
||||
whatChanged = append(whatChanged, fmt.Sprintf("State(%s>%s)", r3.State, newState))
|
||||
r3.State = newState
|
||||
hasChange = true
|
||||
} else {
|
||||
r3.State = report3.StateUnset
|
||||
}
|
||||
|
||||
if newRate != report3.RateUnset && (newRate != r3.Rate) {
|
||||
whatChanged = append(whatChanged, fmt.Sprintf("Rate(%s>%s)", r3.Rate, newRate))
|
||||
r3.Rate = newRate
|
||||
hasChange = true
|
||||
} else {
|
||||
r3.Rate = report3.RateUnset
|
||||
}
|
||||
|
||||
if hasChange {
|
||||
err := device.WriteReport3(vendorID, productID, serialNumber, r3.Bytes())
|
||||
if err != nil {
|
||||
log.Printf(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Printf("changes made {%s}", strings.Join(whatChanged, "; "))
|
||||
} else {
|
||||
log.Printf("no changes")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
5
app/go.mod
Normal file
5
app/go.mod
Normal file
@@ -0,0 +1,5 @@
|
||||
module microjelly.com/beeon/app
|
||||
|
||||
go 1.13
|
||||
|
||||
require github.com/microjelly/hid v0.0.0-20200814141453-3602713b3885
|
||||
2
app/go.sum
Normal file
2
app/go.sum
Normal file
@@ -0,0 +1,2 @@
|
||||
github.com/microjelly/hid v0.0.0-20200814141453-3602713b3885 h1:UdpWecEd/pxs7YgX+gYnROdB4ID6oKIuv2GnVhhXofk=
|
||||
github.com/microjelly/hid v0.0.0-20200814141453-3602713b3885/go.mod h1:bPSrfoMz72p90YvMJSC/hCd0xL7MebXTyM8oWhtsgu8=
|
||||
106
app/pkg/device/device.go
Normal file
106
app/pkg/device/device.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"github.com/microjelly/hid"
|
||||
"microjelly.com/beeon/app/pkg/device/report3"
|
||||
)
|
||||
|
||||
var (
|
||||
_devices []Info
|
||||
_logLevel LogLevel = LogNone
|
||||
)
|
||||
|
||||
// Version - returns the version of this module
|
||||
func Version() string {
|
||||
return "v1.0.1"
|
||||
}
|
||||
|
||||
// UsbSupported - returns true if usb is supported on this platform
|
||||
func UsbSupported() bool {
|
||||
return hid.Supported()
|
||||
}
|
||||
|
||||
// SetLogLevel - sets the logging level
|
||||
func SetLogLevel(level LogLevel) {
|
||||
_logLevel = level
|
||||
}
|
||||
|
||||
// Enumerate - gets connected devices
|
||||
func Enumerate(vendorID uint16, productID uint16) ([]Info, error) {
|
||||
|
||||
var (
|
||||
_devices []Info = nil
|
||||
pSN string = ""
|
||||
)
|
||||
|
||||
for _, dev := range hid.Enumerate(vendorID, productID) {
|
||||
if dev.Serial != pSN {
|
||||
_devices = append(_devices, Info{
|
||||
Serial: dev.Serial,
|
||||
Version: dev.Release,
|
||||
Manufacturer: dev.Manufacturer,
|
||||
Product: dev.Product,
|
||||
})
|
||||
pSN = dev.Serial
|
||||
}
|
||||
}
|
||||
|
||||
return _devices, nil
|
||||
}
|
||||
|
||||
func open(vendorID uint16, productID uint16, serial string) (*hid.Device, error) {
|
||||
|
||||
devices := hid.Enumerate(vendorID, productID)
|
||||
for _, dev := range devices {
|
||||
if (serial != "" && dev.Serial == serial) || serial == "" {
|
||||
_log(LogInfo, "opening device [%s]", dev.Serial)
|
||||
return dev.Open()
|
||||
}
|
||||
}
|
||||
return nil, errors.New("device not found")
|
||||
}
|
||||
|
||||
// ReadReport3 - get device configuration
|
||||
func ReadReport3(vendorID uint16, productID uint16, serial string) (*report3.Report, error) {
|
||||
|
||||
report := []byte{0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
||||
dev, err := open(vendorID, productID, serial)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer dev.Close()
|
||||
_, err = dev.GetFeatureReport(report)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r := report3.New(report)
|
||||
_log(LogDebug, "read %v > %v", report, r)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// WriteReport3 - get device configuration
|
||||
func WriteReport3(vendorID uint16, productID uint16, serial string, report []byte) error {
|
||||
|
||||
dev, err := open(vendorID, productID, serial)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dev.Close()
|
||||
|
||||
_log(LogDebug, "write %v > %v", report, report3.New(report))
|
||||
_, err = dev.SendFeatureReport(report)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func _log(level LogLevel, format string, v ...interface{}) {
|
||||
if level >= _logLevel {
|
||||
log.Printf(format, v...)
|
||||
}
|
||||
}
|
||||
175
app/pkg/device/keycodes/keycodes.go
Normal file
175
app/pkg/device/keycodes/keycodes.go
Normal file
@@ -0,0 +1,175 @@
|
||||
// The contents of this file is free and unencumbered software released into
|
||||
// the public domain. Refer to <http://unlicense.org/> for more information.
|
||||
// Src: https://github.com/yakshaveinc/go-keycodes/blob/master/keycodes.go
|
||||
|
||||
package keycodes
|
||||
|
||||
import "fmt"
|
||||
|
||||
type KeyCode uint8
|
||||
|
||||
func (k KeyCode) String() string {
|
||||
if k == KeyUnset {
|
||||
return "unset"
|
||||
}
|
||||
return fmt.Sprintf("Key(%d)", k)
|
||||
}
|
||||
|
||||
// note: similar keys have different key codes, like Enter and
|
||||
// Keypad Enter
|
||||
|
||||
// cross-platform key codes, compatible with SDL 2 and USB HID speccy
|
||||
// https://hg.libsdl.org/SDL/file/default/include/SDL_scancode.h
|
||||
// http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (page 53)
|
||||
|
||||
// key for codes 0 - 3 are not present on keyboards, they are:
|
||||
// 0 - Reserved (no event)
|
||||
// 1 - ErrorRollOver
|
||||
// 2 - POSTFail
|
||||
// 3 - ErrorUndefined
|
||||
|
||||
const (
|
||||
KeyA KeyCode = 4 + iota
|
||||
KeyB
|
||||
KeyC
|
||||
KeyD
|
||||
KeyE
|
||||
KeyF
|
||||
KeyG
|
||||
KeyH
|
||||
KeyI
|
||||
KeyJ
|
||||
KeyK
|
||||
KeyL
|
||||
KeyM
|
||||
KeyN
|
||||
KeyO
|
||||
KeyP
|
||||
KeyQ
|
||||
KeyR
|
||||
KeyS
|
||||
KeyT
|
||||
KeyU
|
||||
KeyV
|
||||
KeyW
|
||||
KeyX
|
||||
KeyY
|
||||
KeyZ
|
||||
)
|
||||
const (
|
||||
Key1 KeyCode = 30 + iota
|
||||
Key2
|
||||
Key3
|
||||
Key4
|
||||
Key5
|
||||
Key6
|
||||
Key7
|
||||
Key8
|
||||
Key9
|
||||
Key0
|
||||
)
|
||||
const (
|
||||
// choice is to use Enter name instead of Return
|
||||
// and the key code is different from Keypad Enter
|
||||
KeyEnter KeyCode = 40 + iota
|
||||
KeyEscape
|
||||
KeyBackspace
|
||||
KeyTab
|
||||
KeySpace
|
||||
// keypad minus has different key code
|
||||
KeyMinus
|
||||
KeyEquals
|
||||
KeyLeftBracket
|
||||
KeyRightBracket
|
||||
KeyBackslash
|
||||
)
|
||||
|
||||
// key code number 50 is skipped, because it is unclear
|
||||
// where is the key, and what is its name and function
|
||||
|
||||
const (
|
||||
// different name from SDL2 for brevity
|
||||
KeyColon KeyCode = 51 + iota
|
||||
KeyApostrophe
|
||||
// KeyTilde is an alias
|
||||
KeyGrave
|
||||
KeyCommad
|
||||
// KeyDot is an alias, keypad period is a different
|
||||
KeyPeriod
|
||||
Slash
|
||||
CapsLock
|
||||
)
|
||||
const KeyTilde = KeyGrave
|
||||
const KeyDot = KeyPeriod
|
||||
|
||||
const (
|
||||
KeyF1 KeyCode = 58 + iota
|
||||
KeyF2
|
||||
KeyF3
|
||||
KeyF4
|
||||
KeyF5
|
||||
KeyF6
|
||||
KeyF7
|
||||
KeyF8
|
||||
KeyF9
|
||||
KeyF10
|
||||
KeyF11
|
||||
KeyF12
|
||||
)
|
||||
const (
|
||||
KeyPrintScreen KeyCode = 70 + iota
|
||||
KeyScrollLock
|
||||
KeyPause
|
||||
KeyInsert
|
||||
KeyHome
|
||||
KeyPageUp
|
||||
KeyDelete
|
||||
KeyEnd
|
||||
KeyPageDown
|
||||
KeyRight
|
||||
KeyLeft
|
||||
KeyDown
|
||||
KeyUp
|
||||
)
|
||||
const (
|
||||
KeyNumLock KeyCode = 83 + iota
|
||||
KeyKpDivide
|
||||
KeyKpMultiply
|
||||
KeyKpMinus
|
||||
KeyKpPlus
|
||||
KeyKpEnter
|
||||
KeyKp1
|
||||
KeyKp2
|
||||
KeyKp3
|
||||
KeyKp4
|
||||
KeyKp5
|
||||
KeyKp6
|
||||
KeyKp7
|
||||
KeyKp8
|
||||
KeyKp9
|
||||
KeyKp0
|
||||
// KeyKpDot is an alias
|
||||
KeyKpPeriod
|
||||
)
|
||||
const KeyKpDot = KeyKpPeriod
|
||||
|
||||
// key code 100 is skipped, because I can not find the key
|
||||
// key code 101 is not present on Mac
|
||||
// key codes 102-223 are not present on PC
|
||||
|
||||
const (
|
||||
KeyLCtrl KeyCode = 224 + iota
|
||||
KeyLShift
|
||||
KeyLAlt
|
||||
// KeyLWin is an alias
|
||||
KeyLGUI
|
||||
KeyRCtrl
|
||||
KeyRShift
|
||||
KeyRAlt
|
||||
// KeyRWin is an alias
|
||||
KeyRGUI
|
||||
)
|
||||
const KeyLWin = KeyLGUI
|
||||
const KeyRWin = KeyRGUI
|
||||
|
||||
const KeyUnset = 255
|
||||
139
app/pkg/device/report3/report3.go
Normal file
139
app/pkg/device/report3/report3.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package report3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"microjelly.com/beeon/app/pkg/device/keycodes"
|
||||
)
|
||||
|
||||
type State uint8
|
||||
|
||||
const (
|
||||
StateIdle = State(10)
|
||||
StateActive = State(20)
|
||||
StateUnset = State(255)
|
||||
)
|
||||
|
||||
func (r State) String() string {
|
||||
switch r {
|
||||
case StateActive:
|
||||
return "active"
|
||||
case StateIdle:
|
||||
return "idle"
|
||||
case StateUnset:
|
||||
return "unset"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
type Mode uint8
|
||||
|
||||
const (
|
||||
ModeMouse = Mode(10)
|
||||
ModeKeyboard = Mode(20)
|
||||
ModeUnset = Mode(255)
|
||||
)
|
||||
|
||||
func (r Mode) String() string {
|
||||
switch r {
|
||||
case ModeMouse:
|
||||
return "mouse"
|
||||
case ModeKeyboard:
|
||||
return "keyboard"
|
||||
case ModeUnset:
|
||||
return "unset"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
type Rate uint8
|
||||
|
||||
const (
|
||||
RateFast = Rate(1)
|
||||
RateNormal = Rate(8)
|
||||
RateSlow = Rate(16)
|
||||
RateExtraSlow = Rate(32)
|
||||
RateUnset = Rate(255)
|
||||
)
|
||||
|
||||
func (r Rate) String() string {
|
||||
switch r {
|
||||
case RateFast:
|
||||
return "fast"
|
||||
case RateNormal:
|
||||
return "normal"
|
||||
case RateSlow:
|
||||
return "slow"
|
||||
case RateExtraSlow:
|
||||
return "extra-slow"
|
||||
case RateUnset:
|
||||
return "unset"
|
||||
default:
|
||||
return fmt.Sprintf("custom (%d)", r)
|
||||
}
|
||||
}
|
||||
|
||||
type MouseMode uint8
|
||||
|
||||
const (
|
||||
MouseModeCircle = MouseMode(10)
|
||||
MouseModeRandom = MouseMode(20)
|
||||
MouseModeUnset = MouseMode(255)
|
||||
)
|
||||
|
||||
func (r MouseMode) String() string {
|
||||
switch r {
|
||||
case MouseModeCircle:
|
||||
return "circle"
|
||||
case MouseModeRandom:
|
||||
return "random"
|
||||
case MouseModeUnset:
|
||||
return "unset"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
type Report struct {
|
||||
State State
|
||||
Mode Mode
|
||||
Rate Rate
|
||||
KeyCode keycodes.KeyCode
|
||||
MouseMode MouseMode
|
||||
}
|
||||
|
||||
func (r Report) String() string {
|
||||
switch r.Mode {
|
||||
case ModeMouse:
|
||||
return fmt.Sprintf("{Mode: %s, MouseMode: %s, Rate: %s, State: %s}", r.Mode, r.MouseMode, r.Rate, r.State)
|
||||
case ModeKeyboard:
|
||||
return fmt.Sprintf("{Mode: %s, KeyCode: %s, Rate: %s, State: %s}", r.Mode, r.KeyCode, r.Rate, r.State)
|
||||
case ModeUnset:
|
||||
return fmt.Sprintf("{Mode: %s, MouseMode: %s, KeyCode: %s, Rate: %s, State: %s}", r.Mode, r.MouseMode, r.KeyCode, r.Rate, r.State)
|
||||
default:
|
||||
return "{invalid}"
|
||||
}
|
||||
}
|
||||
|
||||
func New(b []byte) *Report {
|
||||
r := new(Report)
|
||||
r.State = State(b[1])
|
||||
r.Mode = Mode(b[2])
|
||||
r.Rate = Rate(b[3])
|
||||
r.KeyCode = keycodes.KeyCode(b[4])
|
||||
r.MouseMode = MouseMode(b[5])
|
||||
return r
|
||||
}
|
||||
|
||||
func (r Report) Bytes() []byte {
|
||||
b := make([]byte, 6)
|
||||
b[0] = 3
|
||||
b[1] = uint8(r.State)
|
||||
b[2] = uint8(r.Mode)
|
||||
b[3] = uint8(r.Rate)
|
||||
b[4] = uint8(r.KeyCode)
|
||||
b[5] = uint8(r.MouseMode)
|
||||
return b
|
||||
}
|
||||
21
app/pkg/device/types.go
Normal file
21
app/pkg/device/types.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package device
|
||||
|
||||
// Info - short list of details
|
||||
type Info struct {
|
||||
Serial string
|
||||
Manufacturer string
|
||||
Version uint16
|
||||
Product string
|
||||
}
|
||||
|
||||
// LogLevel - something
|
||||
type LogLevel uint
|
||||
|
||||
// LogNone - disabled logging
|
||||
// LogInfo - basic logging
|
||||
// LogDebug - even more
|
||||
const (
|
||||
LogDebug LogLevel = iota
|
||||
LogInfo
|
||||
LogNone
|
||||
)
|
||||
Reference in New Issue
Block a user