Files
BatchuKVM/server/service/vm/jiggler/jiggler.go

135 lines
2.0 KiB
Go

package jiggler
import (
"NanoKVM-Server/service/hid"
"os"
"strings"
"sync"
"time"
)
const (
ConfigFile = "/etc/kvm/mouse-jiggler"
Interval = 15 * time.Second
)
var (
jiggler Jiggler
once sync.Once
)
type Jiggler struct {
mutex sync.Mutex
enabled bool
running bool
mode string
lastUpdated time.Time
}
func GetJiggler() *Jiggler {
once.Do(func() {
jiggler = Jiggler{
mutex: sync.Mutex{},
enabled: false,
running: false,
mode: "relative",
lastUpdated: time.Now(),
}
content, err := os.ReadFile(ConfigFile)
if err != nil {
return
}
mode := strings.ReplaceAll(string(content), "\n", "")
if mode != "" {
jiggler.mode = mode
}
jiggler.enabled = true
})
return &jiggler
}
func (j *Jiggler) Enable(mode string) error {
err := os.WriteFile(ConfigFile, []byte(mode), 0644)
if err != nil {
return err
}
j.enabled = true
j.mode = mode
j.Run()
return nil
}
func (j *Jiggler) Disable() error {
if err := os.Remove(ConfigFile); err != nil {
return err
}
j.enabled = false
j.mode = "relative"
return nil
}
func (j *Jiggler) Run() {
if !j.enabled || j.running {
return
}
j.mutex.Lock()
j.running = true
j.mutex.Unlock()
j.Update()
go func() {
ticker := time.NewTicker(Interval)
defer ticker.Stop()
for range ticker.C {
if !j.enabled {
j.running = false
return
}
if time.Since(j.lastUpdated) > Interval {
move(j.mode)
j.Update()
}
}
}()
}
func (j *Jiggler) Update() {
if j.running {
j.lastUpdated = time.Now()
}
}
func (j *Jiggler) IsEnabled() bool {
return j.enabled
}
func (j *Jiggler) GetMode() string {
return j.mode
}
func move(mode string) {
h := hid.GetHid()
if mode == "absolute" {
h.WriteHid2([]byte{0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00})
time.Sleep(100 * time.Millisecond)
h.WriteHid2([]byte{0x00, 0xff, 0x3f, 0xff, 0x3f, 0x00})
} else {
h.WriteHid1([]byte{0x00, 0xa, 0xa, 0x00})
time.Sleep(100 * time.Millisecond)
h.WriteHid1([]byte{0x00, 0xf6, 0xf6, 0x00})
}
}