hid/main.go

218 lines
4.2 KiB
Go
Raw Normal View History

2017-10-26 13:51:49 -07:00
package main
import (
"bufio"
2017-10-26 16:50:36 -07:00
"encoding/binary"
"encoding/json"
2017-11-06 20:53:22 -08:00
"fmt"
2017-10-31 13:06:45 -07:00
"io"
"io/ioutil"
2017-10-26 13:51:49 -07:00
"os"
"path"
"strings"
"github.com/alexflint/go-arg"
2017-10-26 13:51:49 -07:00
)
type Key struct {
Modifier []string `json:"modifier"`
Decimal int `json:"decimal"`
}
2017-11-06 21:52:49 -08:00
type Keys map[string]Key
2017-11-06 20:53:22 -08:00
type Args struct {
SHORTCUT string `arg:"-S,help:Keymap cycle shortcut"`
2018-01-24 12:58:03 -08:00
ORDER []string `arg:"required,positional,help:Order of keymaps"`
2017-11-06 20:53:22 -08:00
}
2017-10-26 16:05:49 -07:00
const (
LCTRL byte = 1 << iota
LSHIFT
LALT
LSUPER
RCTRL
RSHIFT
RALT
RSUPER
)
2017-10-31 13:06:45 -07:00
func Press(press [8]byte, file io.Writer) {
binary.Write(file, binary.BigEndian, press[:])
binary.Write(file, binary.BigEndian, [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
}
func Hold(press [8]byte, file io.Writer) {
binary.Write(file, binary.BigEndian, press[:])
2017-10-31 13:06:45 -07:00
}
func keymapto0(args Args, hidg0 *os.File, currentKeyMap *int) {
if len(args.ORDER) > 1 {
for i := 0; i < len(args.ORDER)-(*currentKeyMap); i++ {
Press([8]byte{LALT, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00}, hidg0)
}
}
}
2017-11-06 20:53:22 -08:00
func changeKeymap(r rune, keys map[string]Keys, args Args, hidg0 *os.File, currentKeyMap *int) {
if len(args.ORDER) > 1 {
for i := 0; i < len(args.ORDER); i++ {
if keys[args.ORDER[(*currentKeyMap)]][string(r)].Decimal == 0 {
Press([8]byte{LALT, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00}, hidg0)
if *currentKeyMap == len(args.ORDER)-1 {
*currentKeyMap = 0
} else {
*currentKeyMap++
}
if i == len(args.ORDER)-1 {
fmt.Println("key not in keymap: " + string(r))
}
}
2017-11-06 20:53:22 -08:00
}
}
}
2017-10-26 16:05:49 -07:00
func main() {
2017-10-26 13:51:49 -07:00
var (
2017-11-06 20:53:22 -08:00
args Args
envExists bool
env string
hidg0 *os.File
err error
keymapsF []os.FileInfo
2017-11-06 22:35:49 -08:00
keys = make(map[string]Keys)
cfgPath string
stdin = bufio.NewReader(os.Stdin)
currentKeyMap int
flags = map[string]byte{
"LSHIFT": LSHIFT,
"LCTRL": LCTRL,
"LALT": LALT,
"LSUPER": LSUPER,
"RSHIFT": RSHIFT,
"RCTRL": RCTRL,
"RALT": RALT,
"RSUPER": RSUPER,
"NONE": 0,
}
2017-10-26 13:51:49 -07:00
)
arg.MustParse(&args)
env, envExists = os.LookupEnv("XDG_CONFIG_HOME")
if !envExists {
env = os.Getenv("HOME")
}
cfgPath = path.Join(env, "hid")
keymapsF, err = ioutil.ReadDir(cfgPath)
if err != nil {
panic(err)
}
fmt.Println(cfgPath)
hidg0, err = os.OpenFile("/dev/hidg0", os.O_WRONLY, os.ModePerm)
if err != nil {
panic(err)
}
for _, file := range keymapsF {
var (
ext string
)
2017-10-31 13:06:45 -07:00
ext = path.Ext(file.Name())
2017-11-06 21:16:59 -08:00
if strings.ToLower(ext) == ".json" {
var (
tmp Keys
T *os.File
content []byte
)
2017-11-10 13:29:40 -08:00
T, err = os.Open(path.Join(cfgPath, file.Name()))
if err != nil {
panic(err)
}
content, err = ioutil.ReadAll(T)
if err != nil {
panic(err)
}
2017-11-06 22:04:00 -08:00
err = json.Unmarshal(content, &tmp)
2017-11-06 22:03:20 -08:00
if err != nil {
panic(err)
}
//fmt.Println(strings.TrimSuffix(file.Name(), ext))
keys[strings.TrimSuffix(file.Name(), ext)] = tmp
T.Close()
}
}
2017-11-10 13:35:03 -08:00
//fmt.Println(keys)
cnt := 0
2017-11-06 20:53:22 -08:00
for {
var (
r rune
flag byte
report [6]byte
)
r, _, err = stdin.ReadRune()
2017-11-07 13:57:24 -08:00
if err == io.EOF {
break
}
2017-11-06 20:53:22 -08:00
if err != nil {
panic(err)
}
2017-11-06 20:53:22 -08:00
changeKeymap(r, keys, args, hidg0, &currentKeyMap)
report[0] = uint8(keys[args.ORDER[currentKeyMap]][string(r)].Decimal)
for _, v := range keys[args.ORDER[currentKeyMap]][string(r)].Modifier {
flag = flag | flags[v]
}
for i := 1; i < 6; i++ {
var (
mod byte
rn rune
)
rn, _, err = stdin.ReadRune()
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
for _, v := range keys[args.ORDER[currentKeyMap]][string(rn)].Modifier {
mod = mod | flags[v]
}
uniq := true
for u := 0; u < i; u++ {
if uint8(keys[args.ORDER[currentKeyMap]][string(rn)].Decimal) == report[u] {
uniq = false
break
}
}
if keys[args.ORDER[(currentKeyMap)]][string(rn)].Decimal != 0 && mod == flag && uniq {
report[i] = uint8(keys[args.ORDER[currentKeyMap]][string(rn)].Decimal)
} else {
stdin.UnreadRune()
break
}
}
changeKeymap(r, keys, args, hidg0, &currentKeyMap)
2017-11-06 20:53:22 -08:00
Press([8]byte{flag, 0, report[0], report[1], report[2], report[3], report[4], report[5]}, hidg0)
flag = 0
cnt++
2017-10-27 13:14:03 -07:00
}
keymapto0(args, hidg0, &currentKeyMap)
2017-11-07 13:57:24 -08:00
fmt.Println("Success!")
hidg0.Close()
2017-10-27 13:14:03 -07:00
2017-10-26 13:51:49 -07:00
}