cleaned up some code

handle delays better
add ability to have comments
add defaults to keymaps
This commit is contained in:
lordwelch 2018-11-04 23:59:13 -08:00
parent bf090a5b67
commit 0b2415ac40
7 changed files with 164 additions and 65 deletions

View File

@ -18,17 +18,22 @@ type syncer interface {
Sync() error Sync() error
} }
// A Key is a USB HID value
type Key struct { type Key struct {
Modifier []string `json:"modifier"` Modifier []string `json:"modifier"`
Decimal byte `json:"decimal"` Decimal byte `json:"decimal"`
DelayDelimiter bool `json:"delayDelimiter,omitempty"` PressDelayDelimiter bool `json:"pressDelayDelimiter,omitempty"`
ReleaseDelayDelimiter bool `json:"releaseDelayDelimiter,omitempty"`
Comment bool `json:"comment,omitempty"`
} }
// A Keymap is a json representation of the unicode rune mapped to its USB HID value
type Keymap map[string]Key type Keymap map[string]Key
// Keyboard is a type to attach the methods to if someone wants to use it
type Keyboard struct{} type Keyboard struct{}
const NONE = 0 // bit flag of modifier keys
const ( const (
LCTRL byte = 1 << iota LCTRL byte = 1 << iota
LSHIFT LSHIFT
@ -38,18 +43,20 @@ const (
RSHIFT RSHIFT
RALT RALT
RSUPER RSUPER
NONE = 0
) )
const delayDelimiter = "⏲" const delayDelimiter = "⏲"
var ( var (
currentKeyMap int PressDelay time.Duration // PressDelay is the time in ms to delay befor sending a press event
DefaultDelay time.Duration ReleaseDelay time.Duration // ReleaseDelay is the time in ms to wait before sending the release event
KeymapOrder []string // Keymap Order is the order in which the specified keymaps cycle on the computer
KeymapShortcut [8]byte // KeymapShortcut is the key combo that will cycle the current keymap by one
ErrOnUnknownKey bool // ErrOnUnknownKey whether or not to fail if the unicode rune is invalid or is not in the specified keymaps
KeymapPath string // KeymapPath is the pathe to where the keymap files are stored
KeymapOrder []string = []string{"qwerty"} currentKeyMap int
KeymapShortcut [8]byte
ErrOnUnknownKey bool
KeymapPath string
keys = make(map[string]Keymap) keys = make(map[string]Keymap)
flags = map[string]byte{ flags = map[string]byte{
"LSHIFT": LSHIFT, "LSHIFT": LSHIFT,
@ -89,9 +96,6 @@ func write(p []byte) (n int, err error) {
var ( var (
mod byte mod byte
) )
if DefaultDelay > 0 && i > 2 {
break
}
r, s = utf8.DecodeRune(p[index:]) r, s = utf8.DecodeRune(p[index:])
if r == utf8.RuneError { if r == utf8.RuneError {
return index, fmt.Errorf("invalid rune: 0x%X", p[index]) // This probably screws things up if the last rune in 'p' is incomplete return index, fmt.Errorf("invalid rune: 0x%X", p[index]) // This probably screws things up if the last rune in 'p' is incomplete
@ -103,26 +107,44 @@ func write(p []byte) (n int, err error) {
return index, fmt.Errorf("rune not in keymap: %c", r) return index, fmt.Errorf("rune not in keymap: %c", r)
} }
} else { } else {
break break press
} }
} }
// Check if this is a delay switch {
if cur.DelayDelimiter { case cur.PressDelayDelimiter:
index += s + parseDelay(p[index+s:]) var n int
break n, PressDelay = parseDelay(p[index+s:])
} index += s + n
break press
case cur.ReleaseDelayDelimiter:
var n int
n, PressDelay = parseDelay(p[index+s:])
index += s + n
break press
case cur.Comment:
var n int
n = bytes.Index(p[index+s:], []byte("\n"))
if n < 0 {
n = 0
}
index += s + n
break press
default:
// Calculate next modifier byte // Calculate next modifier byte
for _, v := range cur.Modifier { for _, v := range cur.Modifier {
mod = mod | flags[v] mod = mod | flags[v]
} }
// Set the modifier if it is the first key otherwise // Set the modifier if it is the first key otherwise
// check if the next modifier byte is the same // check if the next modifier byte is the same
if i == 2 { if i == 2 {
flag = mod flag = mod
} else if flag != mod { } else if flag != mod {
break break press
} }
// Check for duplicate key press. You can't press a key if it is already pressed. // Check for duplicate key press. You can't press a key if it is already pressed.
@ -131,20 +153,24 @@ func write(p []byte) (n int, err error) {
break press break press
} }
} }
}
report[i] = cur.Decimal report[i] = cur.Decimal
index += s index += s
if PressDelay > 0 {
break press
}
} }
report[0] = flag report[0] = flag
r, _ = utf8.DecodeRune(p[index-1:]) r, _ = utf8.DecodeRune(p[index-1:])
fmt.Printf("%c: delay: %v %v\n", r, DefaultDelay, DefaultDelay > (0))
Press(report, Hidg0) Press(report, Hidg0)
delay() delay(PressDelay)
} }
keymapto0() // To make it reproducible keymapto0() // To make it reproducible
return index, nil return index, nil
} }
func parseDelay(buffer []byte) int { func parseDelay(buffer []byte) (count int, delay time.Duration) {
var index int var index int
sb := strings.Builder{} sb := strings.Builder{}
for index < len(buffer) { for index < len(buffer) {
@ -158,26 +184,24 @@ func parseDelay(buffer []byte) int {
} }
i, err := strconv.Atoi(sb.String()) i, err := strconv.Atoi(sb.String())
if err == nil || err == strconv.ErrRange { if err == nil || err == strconv.ErrRange {
DefaultDelay = time.Millisecond * time.Duration(i) return index, time.Millisecond * time.Duration(i)
return index
} }
return 0 return 0, 0
} }
func delay() { func delay(Delay time.Duration) {
if DefaultDelay > 0 { if Delay > 0 {
if syncCheck, ok := Hidg0.(syncer); ok { if syncCheck, ok := Hidg0.(syncer); ok {
syncCheck.Sync() syncCheck.Sync()
} }
time.Sleep(DefaultDelay) time.Sleep(Delay)
// DefaultDelay = 0 // DefaultDelay = 0
} }
} }
func Press(press [8]byte, file io.Writer) { func Press(press [8]byte, file io.Writer) {
file.Write(press[:]) file.Write(press[:])
Hidg0.(syncer).Sync() delay(ReleaseDelay)
time.Sleep(DefaultDelay)
file.Write([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) file.Write([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
} }
@ -198,37 +222,40 @@ func changeKeymap(r rune) bool {
buf := bytes.NewBuffer(make([]byte, 0, 8*len(KeymapOrder))) // To batch shortcut presses buf := bytes.NewBuffer(make([]byte, 0, 8*len(KeymapOrder))) // To batch shortcut presses
for i := 0; i < len(KeymapOrder); i++ { for i := 0; i < len(KeymapOrder); i++ {
if _, ok := CurrentKeymap()[string(r)]; ok { _, ok := CurrentKeymap()[string(r)]
if ok {
Hidg0.Write(buf.Bytes()) Hidg0.Write(buf.Bytes())
return true return true
} else { }
Press(KeymapShortcut, buf) Press(KeymapShortcut, buf)
if currentKeyMap == len(KeymapOrder)-1 { if currentKeyMap == len(KeymapOrder)-1 {
currentKeyMap = 0 currentKeyMap = 0
} else { } else {
currentKeyMap++ currentKeyMap++
} }
}
} }
return false return false
} }
func CurrentKeymap() Keymap { func CurrentKeymap() Keymap {
if keymap, ok := keys[KeymapOrder[currentKeyMap]]; ok { keymap, ok := keys[KeymapOrder[currentKeyMap]]
if ok {
return keymap return keymap
} else {
return LoadKeymap(KeymapOrder[currentKeyMap])
} }
return LoadKeymap(KeymapOrder[currentKeyMap])
} }
func LoadKeymap(keymapName string) Keymap { func LoadKeymap(keymapName string) Keymap {
var ( var (
err error err error
content []byte content []byte
file = path.Join(path.Join(KeymapPath, "hid"), keymapName+".json")
tmp = make(Keymap, 0) tmp = make(Keymap, 0)
) )
fmt.Println(path.Join(path.Join(KeymapPath, "hid"), keymapName+".json")) fmt.Println(file)
content, err = ioutil.ReadFile(path.Join(path.Join(KeymapPath, "hid"), keymapName+".json")) content, err = ioutil.ReadFile(file)
if err != nil { if err != nil {
return nil return nil
} }

View File

@ -386,5 +386,20 @@
" ": { " ": {
"modifier": ["NONE"], "modifier": ["NONE"],
"decimal": 44 "decimal": 44
},
"⏲": {
"modifier": ["NONE"],
"decimal": 0,
"PressDelayDelimiter": true
},
"🐉": {
"modifier": ["NONE"],
"decimal": 0,
"releaseDelayDelimiter": true
},
"⨌": {
"modifier": ["NONE"],
"decimal": 0,
"comment": true
} }
} }

View File

@ -390,6 +390,16 @@
"⏲": { "⏲": {
"modifier": ["NONE"], "modifier": ["NONE"],
"decimal": 0, "decimal": 0,
"delayDelimiter": true "PressDelayDelimiter": true
},
"🐉": {
"modifier": ["NONE"],
"decimal": 0,
"releaseDelayDelimiter": true
},
"⨌": {
"modifier": ["NONE"],
"decimal": 0,
"comment": true
} }
} }

View File

@ -306,5 +306,20 @@
" ": { " ": {
"modifier": ["NONE"], "modifier": ["NONE"],
"decimal": 44 "decimal": 44
},
"⏲": {
"modifier": ["NONE"],
"decimal": 0,
"PressDelayDelimiter": true
},
"🐉": {
"modifier": ["NONE"],
"decimal": 0,
"releaseDelayDelimiter": true
},
"⨌": {
"modifier": ["NONE"],
"decimal": 0,
"comment": true
} }
} }

View File

@ -374,5 +374,20 @@
" ": { " ": {
"modifier": ["NONE"], "modifier": ["NONE"],
"decimal": 44 "decimal": 44
},
"⏲": {
"modifier": ["NONE"],
"decimal": 0,
"PressDelayDelimiter": true
},
"🐉": {
"modifier": ["NONE"],
"decimal": 0,
"releaseDelayDelimiter": true
},
"⨌": {
"modifier": ["NONE"],
"decimal": 0,
"comment": true
} }
} }

View File

@ -558,5 +558,20 @@
" ": { " ": {
"modifier": ["NONE"], "modifier": ["NONE"],
"decimal": 44 "decimal": 44
},
"⏲": {
"modifier": ["NONE"],
"decimal": 0,
"PressDelayDelimiter": true
},
"🐉": {
"modifier": ["NONE"],
"decimal": 0,
"releaseDelayDelimiter": true
},
"⨌": {
"modifier": ["NONE"],
"decimal": 0,
"comment": true
} }
} }

View File

@ -4,6 +4,7 @@ import (
"flag" "flag"
"fmt" "fmt"
"os" "os"
"time"
"timmy.narnian.us/hid/ghid" "timmy.narnian.us/hid/ghid"
) )
@ -20,6 +21,7 @@ func main() {
flag.Parse() flag.Parse()
hid.KeymapOrder = flag.Args() hid.KeymapOrder = flag.Args()
hid.ReleaseDelay = time.Duration(10) * time.Millisecond
fmt.Println(hid.KeymapPath) fmt.Println(hid.KeymapPath)