diff --git a/go.mod b/go.mod index d593471..e736547 100644 --- a/go.mod +++ b/go.mod @@ -7,3 +7,5 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e golang.org/x/net v0.4.0 ) + +require github.com/bendahl/uinput v1.6.0 // indirect diff --git a/go.sum b/go.sum index fcbadb0..68ab245 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/bendahl/uinput v1.6.0 h1:fM6r3OSC17rHh758mizKjSBuqi+XinhiGd4N3pWvZiI= +github.com/bendahl/uinput v1.6.0/go.mod h1:Np7w3DINc9wB83p12fTAM3DPPhFnAKP0WTXRqCQJ6Z8= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= diff --git a/inputcontrol/controller_uinput.go b/inputcontrol/controller_uinput.go new file mode 100644 index 0000000..0b16f10 --- /dev/null +++ b/inputcontrol/controller_uinput.go @@ -0,0 +1,195 @@ +//go:build uinput + +/* + * Copyright (c) 2023 De_Coder github.com/ps100000 + * + * This file is part of Remote-Touchpad. + * + * Remote-Touchpad is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Remote-Touchpad is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Remote-Touchpad. If not, see . + */ + +package inputcontrol + +import "github.com/bendahl/uinput" +import "errors" + +var ukeysMap = map[Keysym]int { + 0x0061: uinput.KeyA, + 0x0062: uinput.KeyB, + 0x0063: uinput.KeyC, + 0x0064: uinput.KeyD, + 0x0065: uinput.KeyE, + 0x0066: uinput.KeyF, + 0x0067: uinput.KeyG, + 0x0068: uinput.KeyH, + 0x0069: uinput.KeyI, + 0x006a: uinput.KeyJ, + 0x006b: uinput.KeyK, + 0x006c: uinput.KeyL, + 0x006d: uinput.KeyM, + 0x006e: uinput.KeyN, + 0x006f: uinput.KeyO, + 0x0070: uinput.KeyP, + 0x0071: uinput.KeyQ, + 0x0072: uinput.KeyR, + 0x0073: uinput.KeyS, + 0x0074: uinput.KeyT, + 0x0075: uinput.KeyU, + 0x0076: uinput.KeyV, + 0x0077: uinput.KeyW, + 0x0078: uinput.KeyX, + 0x0079: uinput.KeyY, + 0x007a: uinput.KeyZ, + + 0x0030: uinput.Key0, + 0x0031: uinput.Key1, + 0x0032: uinput.Key2, + 0x0033: uinput.Key3, + 0x0034: uinput.Key4, + 0x0035: uinput.Key5, + 0x0036: uinput.Key6, + 0x0037: uinput.Key7, + 0x0038: uinput.Key8, + 0x0039: uinput.Key9, + + 0xff1b: uinput.KeyEsc, + 0x002d: uinput.KeyMinus, + 0x002b: uinput.KeyKpplus, + 0x002a: uinput.KeyKpasterisk, + 0x003d: uinput.KeyEqual, + 0xff08: uinput.KeyBackspace, + 0xff09: uinput.KeyTab, + 0x0028: uinput.KeyLeftbrace, + 0x0029: uinput.KeyRightbrace, + 0xff0d: uinput.KeyEnter, + 0x003b: uinput.KeySemicolon, + 0x0027: uinput.KeyApostrophe, + 0x0060: uinput.KeyGrave, + 0x005c: uinput.KeyBackslash, + 0x002c: uinput.KeyComma, + 0x0abd: uinput.KeyDot, + 0x002f: uinput.KeySlash, + 0x0020: uinput.KeySpace, + 0xff50: uinput.KeyHome, + 0xff52: uinput.KeyUp, + 0xff51: uinput.KeyLeft, + 0xff53: uinput.KeyRight, + 0xff57: uinput.KeyEnd, + 0xff54: uinput.KeyDown, + 0xffff: uinput.KeyDelete, + 0x1008FF12: uinput.KeyMute, + 0x1008FF11: uinput.KeyVolumedown, + 0x1008FF13: uinput.KeyVolumeup, + 0xffeb: uinput.KeyLeftmeta, + 0x1008ff26: uinput.KeyBack, + 0x1008ff27: uinput.KeyForward, + 0x1008ff17: uinput.KeyNextsong, + 0x1008ff14: uinput.KeyPlaypause, + 0x1008ff16: uinput.KeyPrevioussong, +} + +type uinputController struct { + keyboard uinput.Keyboard + mouse uinput.Mouse +} + +func init() { + RegisterController("Uinput", InitUinputController, 0) +} + +func InitUinputController() (Controller, error) { + keyboard, err := uinput.CreateKeyboard("/dev/uinput", []byte("remote-tp-keyboard")) + if err != nil { + return nil, err + } + mouse, err := uinput.CreateMouse("/dev/uinput", []byte("remote-tp-mouse")) + if err != nil { + return nil, err + } + p := &uinputController{keyboard, mouse} + return p, nil +} + +func (p *uinputController) Close() error { + p.keyboard.Close() + p.mouse.Close() + return nil +} + +func (p *uinputController) sendKeysym(sym Keysym) error { + if sym >= 0x0041 && sym <= 0x005a { + p.keyboard.KeyDown(uinput.KeyLeftshift) + p.keyboard.KeyPress(ukeysMap[sym + 0x20]) + p.keyboard.KeyUp(uinput.KeyLeftshift) + } + p.keyboard.KeyPress(ukeysMap[sym]) + return nil +} + +func (p *uinputController) KeyboardText(text string) error { + for _, runeValue := range text { + keysym, err := RuneToKeysym(runeValue) + if err != nil { + return err + } + err = p.sendKeysym(keysym); + + } + return nil +} + +func (p *uinputController) KeyboardKey(key Key) error { + keysym, err := KeyToKeysym(key) + if err != nil { + return err + } + return p.sendKeysym(keysym) +} + +func (p *uinputController) PointerButton(button PointerButton, press bool) error { + switch button { + case PointerButtonLeft: + if press { + p.mouse.LeftPress() + } else { + p.mouse.LeftRelease() + } + case PointerButtonRight: + if press { + p.mouse.RightPress() + } else { + p.mouse.RightRelease() + } + case PointerButtonMiddle: + if press { + p.mouse.MiddlePress() + } else { + p.mouse.MiddleRelease() + } + default: + return errors.New("unsupported pointer button") + } + return nil +} + +func (p *uinputController) PointerMove(deltaX, deltaY int) error { + p.mouse.Move(int32(deltaX), int32(deltaY)) + return nil +} + +func (p *uinputController) PointerScroll(deltaHorizontal, deltaVertical int, finish bool) error { + p.mouse.Wheel(false, int32(deltaVertical)) + p.mouse.Wheel(true, int32(deltaHorizontal)) + return nil +} diff --git a/inputcontrol/keysyms.generated.go b/inputcontrol/keysyms.generated.go index 8734718..3e0ead8 100644 --- a/inputcontrol/keysyms.generated.go +++ b/inputcontrol/keysyms.generated.go @@ -1,5 +1,5 @@ // Code generated by keysyms.generator.go. DO NOT EDIT. -//go:build portal || x11 +//go:build portal || x11 || uinput package inputcontrol diff --git a/inputcontrol/keysyms.generator.go b/inputcontrol/keysyms.generator.go index cc18417..71b4094 100644 --- a/inputcontrol/keysyms.generator.go +++ b/inputcontrol/keysyms.generator.go @@ -102,7 +102,7 @@ func main() { keysymsMap[unicode] = keysym } content := "// Code generated by keysyms.generator.go. DO NOT EDIT.\n" + - "//go:build portal || x11\n\n" + + "//go:build portal || x11 || uinput\n\n" + "package inputcontrol\n\n" + "var keysymsMap = map[rune]Keysym{\n" keys := make([]rune, 0) diff --git a/inputcontrol/keysyms.go b/inputcontrol/keysyms.go index 5402120..f523794 100644 --- a/inputcontrol/keysyms.go +++ b/inputcontrol/keysyms.go @@ -1,4 +1,4 @@ -//go:build portal || x11 +//go:build portal || x11 || uinput /* * Copyright (c) 2018 Unrud