2017-10-26 13:51:49 -07:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2017-11-06 14:00:44 -08:00
|
|
|
"bufio"
|
2017-10-26 16:50:36 -07:00
|
|
|
"encoding/binary"
|
2017-11-06 14:00:44 -08:00
|
|
|
"encoding/json"
|
2017-11-06 20:53:22 -08:00
|
|
|
"fmt"
|
2017-10-31 13:06:45 -07:00
|
|
|
"io"
|
2017-11-06 14:00:44 -08:00
|
|
|
"io/ioutil"
|
2017-10-26 13:51:49 -07:00
|
|
|
"os"
|
2017-11-06 14:00:44 -08:00
|
|
|
"path"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/alexflint/go-arg"
|
2017-10-26 13:51:49 -07:00
|
|
|
)
|
|
|
|
|
2017-11-06 14:00:44 -08:00
|
|
|
type Key struct {
|
2018-01-24 10:21:44 -08:00
|
|
|
Modifier []string `json:"modifier"`
|
|
|
|
Decimal int `json:"decimal"`
|
2017-11-06 14:00:44 -08:00
|
|
|
}
|
|
|
|
|
2017-11-06 21:52:49 -08:00
|
|
|
type Keys map[string]Key
|
2017-11-06 14:00:44 -08:00
|
|
|
|
2017-11-06 20:53:22 -08:00
|
|
|
type Args struct {
|
|
|
|
SHORTCUT string `arg:"-S,help:Keymap cycle shortcut"`
|
2017-11-06 21:09:55 -08:00
|
|
|
ORDER []string `arg:"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[:])
|
2017-11-06 14:00:44 -08:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2018-01-23 23:12:41 -08:00
|
|
|
func keymapto0(args Args, hidg0 *os.File, currentKeyMap *int) {
|
|
|
|
|
|
|
|
for i := 0; i <= len(args.ORDER)-(*currentKeyMap+1); 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) {
|
2018-01-23 23:12:41 -08:00
|
|
|
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
|
2017-11-10 13:15:24 -08:00
|
|
|
envExists bool
|
|
|
|
env string
|
2017-11-06 14:00:44 -08:00
|
|
|
hidg0 *os.File
|
|
|
|
err error
|
|
|
|
keymapsF []os.FileInfo
|
2017-11-06 22:35:49 -08:00
|
|
|
keys = make(map[string]Keys)
|
2017-11-10 13:15:24 -08:00
|
|
|
cfgPath string
|
2017-11-06 14:00:44 -08:00
|
|
|
stdin = bufio.NewReader(os.Stdin)
|
|
|
|
currentKeyMap int
|
2017-11-08 10:15:58 -08:00
|
|
|
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
|
|
|
)
|
2017-11-06 14:00:44 -08:00
|
|
|
arg.MustParse(&args)
|
2017-11-10 13:15:24 -08:00
|
|
|
env, envExists = os.LookupEnv("XDG_CONFIG_HOME")
|
|
|
|
if !envExists {
|
|
|
|
env = os.Getenv("HOME")
|
|
|
|
}
|
|
|
|
|
|
|
|
cfgPath = path.Join(env, "hid")
|
2017-11-06 14:00:44 -08:00
|
|
|
keymapsF, err = ioutil.ReadDir(cfgPath)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2017-11-10 13:15:24 -08:00
|
|
|
|
|
|
|
fmt.Println(cfgPath)
|
2017-11-06 14:00:44 -08:00
|
|
|
|
|
|
|
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
|
|
|
|
2017-11-06 14:00:44 -08:00
|
|
|
ext = path.Ext(file.Name())
|
2017-11-10 13:15:24 -08:00
|
|
|
|
2017-11-06 21:16:59 -08:00
|
|
|
if strings.ToLower(ext) == ".json" {
|
2017-11-06 14:00:44 -08:00
|
|
|
var (
|
|
|
|
tmp Keys
|
|
|
|
T *os.File
|
|
|
|
content []byte
|
|
|
|
)
|
2017-11-10 13:15:24 -08:00
|
|
|
|
2017-11-10 13:29:40 -08:00
|
|
|
T, err = os.Open(path.Join(cfgPath, file.Name()))
|
2017-11-06 14:00:44 -08:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2017-11-08 10:15:58 -08:00
|
|
|
//fmt.Println(strings.TrimSuffix(file.Name(), ext))
|
2017-11-06 14:00:44 -08:00
|
|
|
keys[strings.TrimSuffix(file.Name(), ext)] = tmp
|
|
|
|
T.Close()
|
|
|
|
}
|
|
|
|
}
|
2017-11-10 13:35:03 -08:00
|
|
|
//fmt.Println(keys)
|
2017-11-06 20:53:22 -08:00
|
|
|
for {
|
|
|
|
var (
|
|
|
|
r rune
|
|
|
|
flag byte
|
|
|
|
report [6]byte
|
|
|
|
)
|
|
|
|
|
2017-11-06 14:00:44 -08:00
|
|
|
r, _, err = stdin.ReadRune()
|
2017-11-10 13:15:24 -08:00
|
|
|
//fmt.Printf("%s\n", string(r))
|
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 14:00:44 -08:00
|
|
|
}
|
2017-11-06 20:53:22 -08:00
|
|
|
changeKeymap(r, keys, args, hidg0, ¤tKeyMap)
|
2018-01-24 10:21:44 -08:00
|
|
|
for _, v := range keys[args.ORDER[currentKeyMap]][string(r)].Modifier {
|
2018-01-24 12:32:42 -08:00
|
|
|
flag = flag | flags[v]
|
2018-01-24 10:21:44 -08:00
|
|
|
}
|
2017-11-08 10:15:58 -08:00
|
|
|
binary.BigEndian.PutUint16(report[:], uint16(keys[args.ORDER[currentKeyMap]][string(r)].Decimal))
|
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)
|
2018-01-24 10:21:44 -08:00
|
|
|
flag = 0
|
2017-10-27 13:14:03 -07:00
|
|
|
}
|
2018-01-23 23:12:41 -08:00
|
|
|
keymapto0(args, hidg0, ¤tKeyMap)
|
2017-11-07 13:57:24 -08:00
|
|
|
fmt.Println("Success!")
|
2017-11-06 14:00:44 -08:00
|
|
|
hidg0.Close()
|
2017-10-27 13:14:03 -07:00
|
|
|
|
2017-10-26 13:51:49 -07:00
|
|
|
}
|