neko/server/internal/hid/hid.go
2020-01-18 23:30:09 +00:00

237 lines
6.9 KiB
Go

package hid
/*
#cgo linux CFLAGS: -I/usr/src
#cgo linux LDFLAGS: -L/usr/src -lX11 -lXtst
#include "hid.h"
*/
import "C"
import (
"fmt"
"time"
"n.eko.moe/neko/internal/hid/keycode"
)
var debounce = make(map[int]time.Time)
var buttons = make(map[int]keycode.Button)
var keys = make(map[int]keycode.Key)
func init() {
keys[keycode.BACKSPACE.Code] = keycode.BACKSPACE
keys[keycode.TAB.Code] = keycode.TAB
keys[keycode.CLEAR.Code] = keycode.CLEAR
keys[keycode.ENTER.Code] = keycode.ENTER
keys[keycode.SHIFT.Code] = keycode.SHIFT
keys[keycode.CTRL.Code] = keycode.CTRL
keys[keycode.ALT.Code] = keycode.ALT
keys[keycode.PAUSE.Code] = keycode.PAUSE
keys[keycode.CAPS_LOCK.Code] = keycode.CAPS_LOCK
keys[keycode.ESCAPE.Code] = keycode.ESCAPE
keys[keycode.SPACE.Code] = keycode.SPACE
keys[keycode.PAGE_UP.Code] = keycode.PAGE_UP
keys[keycode.PAGE_DOWN.Code] = keycode.PAGE_DOWN
keys[keycode.END.Code] = keycode.END
keys[keycode.HOME.Code] = keycode.HOME
keys[keycode.LEFT_ARROW.Code] = keycode.LEFT_ARROW
keys[keycode.UP_ARROW.Code] = keycode.UP_ARROW
keys[keycode.RIGHT_ARROW.Code] = keycode.RIGHT_ARROW
keys[keycode.DOWN_ARROW.Code] = keycode.DOWN_ARROW
keys[keycode.INSERT.Code] = keycode.INSERT
keys[keycode.DELETE.Code] = keycode.DELETE
keys[keycode.KEY_0.Code] = keycode.KEY_0
keys[keycode.KEY_1.Code] = keycode.KEY_1
keys[keycode.KEY_2.Code] = keycode.KEY_2
keys[keycode.KEY_3.Code] = keycode.KEY_3
keys[keycode.KEY_4.Code] = keycode.KEY_4
keys[keycode.KEY_5.Code] = keycode.KEY_5
keys[keycode.KEY_6.Code] = keycode.KEY_6
keys[keycode.KEY_7.Code] = keycode.KEY_7
keys[keycode.KEY_8.Code] = keycode.KEY_8
keys[keycode.KEY_9.Code] = keycode.KEY_9
keys[keycode.KEY_A.Code] = keycode.KEY_A
keys[keycode.KEY_B.Code] = keycode.KEY_B
keys[keycode.KEY_C.Code] = keycode.KEY_C
keys[keycode.KEY_D.Code] = keycode.KEY_D
keys[keycode.KEY_E.Code] = keycode.KEY_E
keys[keycode.KEY_F.Code] = keycode.KEY_F
keys[keycode.KEY_G.Code] = keycode.KEY_G
keys[keycode.KEY_H.Code] = keycode.KEY_H
keys[keycode.KEY_I.Code] = keycode.KEY_I
keys[keycode.KEY_J.Code] = keycode.KEY_J
keys[keycode.KEY_K.Code] = keycode.KEY_K
keys[keycode.KEY_L.Code] = keycode.KEY_L
keys[keycode.KEY_M.Code] = keycode.KEY_M
keys[keycode.KEY_N.Code] = keycode.KEY_N
keys[keycode.KEY_O.Code] = keycode.KEY_O
keys[keycode.KEY_P.Code] = keycode.KEY_P
keys[keycode.KEY_Q.Code] = keycode.KEY_Q
keys[keycode.KEY_R.Code] = keycode.KEY_R
keys[keycode.KEY_S.Code] = keycode.KEY_S
keys[keycode.KEY_T.Code] = keycode.KEY_T
keys[keycode.KEY_U.Code] = keycode.KEY_U
keys[keycode.KEY_V.Code] = keycode.KEY_V
keys[keycode.KEY_W.Code] = keycode.KEY_W
keys[keycode.KEY_X.Code] = keycode.KEY_X
keys[keycode.KEY_Y.Code] = keycode.KEY_Y
keys[keycode.KEY_Z.Code] = keycode.KEY_Z
keys[keycode.WIN_LEFT.Code] = keycode.WIN_LEFT
keys[keycode.WIN_RIGHT.Code] = keycode.WIN_RIGHT
keys[keycode.PAD_0.Code] = keycode.PAD_0
keys[keycode.PAD_1.Code] = keycode.PAD_1
keys[keycode.PAD_2.Code] = keycode.PAD_2
keys[keycode.PAD_3.Code] = keycode.PAD_3
keys[keycode.PAD_4.Code] = keycode.PAD_4
keys[keycode.PAD_5.Code] = keycode.PAD_5
keys[keycode.PAD_6.Code] = keycode.PAD_6
keys[keycode.PAD_7.Code] = keycode.PAD_7
keys[keycode.PAD_8.Code] = keycode.PAD_8
keys[keycode.PAD_9.Code] = keycode.PAD_9
keys[keycode.MULTIPLY.Code] = keycode.MULTIPLY
keys[keycode.ADD.Code] = keycode.ADD
keys[keycode.SUBTRACT.Code] = keycode.SUBTRACT
keys[keycode.DECIMAL.Code] = keycode.DECIMAL
keys[keycode.DIVIDE.Code] = keycode.DIVIDE
keys[keycode.KEY_F1.Code] = keycode.KEY_F1
keys[keycode.KEY_F2.Code] = keycode.KEY_F2
keys[keycode.KEY_F3.Code] = keycode.KEY_F3
keys[keycode.KEY_F4.Code] = keycode.KEY_F4
keys[keycode.KEY_F5.Code] = keycode.KEY_F5
keys[keycode.KEY_F6.Code] = keycode.KEY_F6
keys[keycode.KEY_F7.Code] = keycode.KEY_F7
keys[keycode.KEY_F8.Code] = keycode.KEY_F8
keys[keycode.KEY_F9.Code] = keycode.KEY_F9
keys[keycode.KEY_F10.Code] = keycode.KEY_F10
keys[keycode.KEY_F11.Code] = keycode.KEY_F11
keys[keycode.KEY_F12.Code] = keycode.KEY_F12
keys[keycode.NUM_LOCK.Code] = keycode.NUM_LOCK
keys[keycode.SCROLL_LOCK.Code] = keycode.SCROLL_LOCK
keys[keycode.SEMI_COLON.Code] = keycode.SEMI_COLON
keys[keycode.EQUAL.Code] = keycode.EQUAL
keys[keycode.COMMA.Code] = keycode.COMMA
keys[keycode.DASH.Code] = keycode.DASH
keys[keycode.PERIOD.Code] = keycode.PERIOD
keys[keycode.FORWARD_SLASH.Code] = keycode.FORWARD_SLASH
keys[keycode.GRAVE.Code] = keycode.GRAVE
keys[keycode.OPEN_BRACKET.Code] = keycode.OPEN_BRACKET
keys[keycode.BACK_SLASH.Code] = keycode.BACK_SLASH
keys[keycode.CLOSE_BRAKET.Code] = keycode.CLOSE_BRAKET
keys[keycode.SINGLE_QUOTE.Code] = keycode.SINGLE_QUOTE
buttons[keycode.LEFT_BUTTON.Code] = keycode.LEFT_BUTTON
buttons[keycode.CENTER_BUTTON.Code] = keycode.CENTER_BUTTON
buttons[keycode.RIGHT_BUTTON.Code] = keycode.RIGHT_BUTTON
buttons[keycode.SCROLL_UP_BUTTON.Code] = keycode.SCROLL_UP_BUTTON
buttons[keycode.SCROLL_DOWN_BUTTON.Code] = keycode.SCROLL_DOWN_BUTTON
buttons[keycode.SCROLL_LEFT_BUTTON.Code] = keycode.SCROLL_LEFT_BUTTON
buttons[keycode.SCROLL_RIGHT_BUTTON.Code] = keycode.SCROLL_RIGHT_BUTTON
}
func Display(display string) {
C.setXDisplay(C.CString(display))
}
func Move(x, y int) {
C.mouseMove(C.int(x), C.int(y))
}
func Scroll(x, y int) {
C.mouseScroll(C.int(x), C.int(y))
}
func ButtonDown(code int) (*keycode.Button, error) {
button, ok := buttons[code]
if !ok {
return nil, fmt.Errorf("invalid button %v", code)
}
if _, ok := debounce[code]; ok {
return nil, fmt.Errorf("debounced button %v(%v)", button.Name, code)
}
debounce[code] = time.Now()
C.mouseEvent(C.uint(button.Keysym), C.int(1))
return &button, nil
}
func KeyDown(code int) (*keycode.Key, error) {
key, ok := keys[code]
if !ok {
return nil, fmt.Errorf("invalid key %v", code)
}
if _, ok := debounce[code]; ok {
return nil, fmt.Errorf("debounced key %v(%v)", key.Name, code)
}
debounce[code] = time.Now()
C.keyEvent(C.ulong(key.Keysym), C.int(1))
return &key, nil
}
func ButtonUp(code int) (*keycode.Button, error) {
button, ok := buttons[code]
if !ok {
return nil, fmt.Errorf("invalid button %v", code)
}
if _, ok := debounce[code]; !ok {
return nil, fmt.Errorf("debounced button %v(%v)", button.Name, code)
}
delete(debounce, code)
C.mouseEvent(C.uint(button.Keysym), C.int(0))
return &button, nil
}
func KeyUp(code int) (*keycode.Key, error) {
key, ok := keys[code]
if !ok {
return nil, fmt.Errorf("invalid key %v", code)
}
if _, ok := debounce[code]; !ok {
return nil, fmt.Errorf("debounced key %v(%v)", key.Name, code)
}
delete(debounce, code)
C.keyEvent(C.ulong(key.Keysym), C.int(0))
return &key, nil
}
func Reset() {
for key := range debounce {
if (key < 8) {
ButtonUp(key)
} else {
KeyUp(key)
}
delete(debounce, key)
}
}
func Check(duration time.Duration) {
t := time.Now()
for key, start := range debounce {
if t.Sub(start) < duration {
continue
}
if (key < 8) {
ButtonUp(key)
} else {
KeyUp(key)
}
delete(debounce, key)
}
}