clipboard sync and some minor fixes
This commit is contained in:
124
server/internal/hid/clipboard/clipboard.go
Normal file
124
server/internal/hid/clipboard/clipboard.go
Normal file
@ -0,0 +1,124 @@
|
||||
package clipboard
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
const (
|
||||
xsel = "xsel"
|
||||
xclip = "xclip"
|
||||
wlcopy = "wl-copy"
|
||||
wlpaste = "wl-paste"
|
||||
termuxClipboardGet = "termux-clipboard-get"
|
||||
termuxClipboardSet = "termux-clipboard-set"
|
||||
)
|
||||
|
||||
var (
|
||||
Unsupported bool
|
||||
Primary bool
|
||||
|
||||
pasteCmdArgs []string
|
||||
copyCmdArgs []string
|
||||
|
||||
xselPasteArgs = []string{xsel, "--output", "--clipboard"}
|
||||
xselCopyArgs = []string{xsel, "--input", "--clipboard"}
|
||||
|
||||
xclipPasteArgs = []string{xclip, "-out", "-selection", "clipboard"}
|
||||
xclipCopyArgs = []string{xclip, "-in", "-selection", "clipboard"}
|
||||
|
||||
wlpasteArgs = []string{wlpaste, "--no-newline"}
|
||||
wlcopyArgs = []string{wlcopy}
|
||||
|
||||
termuxPasteArgs = []string{termuxClipboardGet}
|
||||
termuxCopyArgs = []string{termuxClipboardSet}
|
||||
|
||||
missingCommands = errors.New("No clipboard utilities available. Please install xsel, xclip, wl-clipboard or Termux:API add-on for termux-clipboard-get/set.")
|
||||
)
|
||||
|
||||
func init() {
|
||||
if os.Getenv("WAYLAND_DISPLAY") != "" {
|
||||
pasteCmdArgs = wlpasteArgs
|
||||
copyCmdArgs = wlcopyArgs
|
||||
|
||||
if _, err := exec.LookPath(wlcopy); err == nil {
|
||||
if _, err := exec.LookPath(wlpaste); err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pasteCmdArgs = xclipPasteArgs
|
||||
copyCmdArgs = xclipCopyArgs
|
||||
|
||||
if _, err := exec.LookPath(xclip); err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
pasteCmdArgs = xselPasteArgs
|
||||
copyCmdArgs = xselCopyArgs
|
||||
|
||||
if _, err := exec.LookPath(xsel); err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
pasteCmdArgs = termuxPasteArgs
|
||||
copyCmdArgs = termuxCopyArgs
|
||||
|
||||
if _, err := exec.LookPath(termuxClipboardSet); err == nil {
|
||||
if _, err := exec.LookPath(termuxClipboardGet); err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Unsupported = true
|
||||
}
|
||||
|
||||
func getPasteCommand() *exec.Cmd {
|
||||
if Primary {
|
||||
pasteCmdArgs = pasteCmdArgs[:1]
|
||||
}
|
||||
return exec.Command(pasteCmdArgs[0], pasteCmdArgs[1:]...)
|
||||
}
|
||||
|
||||
func getCopyCommand() *exec.Cmd {
|
||||
if Primary {
|
||||
copyCmdArgs = copyCmdArgs[:1]
|
||||
}
|
||||
return exec.Command(copyCmdArgs[0], copyCmdArgs[1:]...)
|
||||
}
|
||||
|
||||
func ReadAll() (string, error) {
|
||||
if Unsupported {
|
||||
return "", missingCommands
|
||||
}
|
||||
pasteCmd := getPasteCommand()
|
||||
out, err := pasteCmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func WriteAll(text string) error {
|
||||
if Unsupported {
|
||||
return missingCommands
|
||||
}
|
||||
copyCmd := getCopyCommand()
|
||||
in, err := copyCmd.StdinPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := copyCmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := in.Write([]byte(text)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := in.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return copyCmd.Wait()
|
||||
}
|
@ -1,56 +1,56 @@
|
||||
#include "hid.h"
|
||||
|
||||
static Display *display = NULL;
|
||||
static char *name = ":0.0";
|
||||
static int registered = 0;
|
||||
static int dirty = 0;
|
||||
static Display *DISPLAY = NULL;
|
||||
static char *NAME = ":0.0";
|
||||
static int REGISTERED = 0;
|
||||
static int DIRTY = 0;
|
||||
|
||||
Display *getXDisplay(void) {
|
||||
/* Close the display if displayName has changed */
|
||||
if (dirty) {
|
||||
if (DIRTY) {
|
||||
closeXDisplay();
|
||||
dirty = 0;
|
||||
DIRTY = 0;
|
||||
}
|
||||
|
||||
if (display == NULL) {
|
||||
if (DISPLAY == NULL) {
|
||||
/* First try the user set displayName */
|
||||
display = XOpenDisplay(name);
|
||||
DISPLAY = XOpenDisplay(NAME);
|
||||
|
||||
/* Then try using environment variable DISPLAY */
|
||||
if (display == NULL) {
|
||||
display = XOpenDisplay(NULL);
|
||||
if (DISPLAY == NULL) {
|
||||
DISPLAY = XOpenDisplay(NULL);
|
||||
}
|
||||
|
||||
if (display == NULL) {
|
||||
if (DISPLAY == NULL) {
|
||||
fputs("Could not open main display\n", stderr);
|
||||
} else if (!registered) {
|
||||
} else if (!REGISTERED) {
|
||||
atexit(&closeXDisplay);
|
||||
registered = 1;
|
||||
REGISTERED = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return display;
|
||||
return DISPLAY;
|
||||
}
|
||||
|
||||
void closeXDisplay(void) {
|
||||
if (display != NULL) {
|
||||
XCloseDisplay(display);
|
||||
display = NULL;
|
||||
if (DISPLAY != NULL) {
|
||||
XCloseDisplay(DISPLAY);
|
||||
DISPLAY = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void setXDisplay(char *input) {
|
||||
name = strdup(input);
|
||||
dirty = 1;
|
||||
NAME = strdup(input);
|
||||
DIRTY = 1;
|
||||
}
|
||||
|
||||
void mouseMove(int x, int y) {
|
||||
void XMove(int x, int y) {
|
||||
Display *display = getXDisplay();
|
||||
XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, x, y);
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
void mouseScroll(int x, int y) {
|
||||
void XScroll(int x, int y) {
|
||||
int ydir = 4; /* Button 4 is up, 5 is down. */
|
||||
int xdir = 6;
|
||||
|
||||
@ -59,7 +59,7 @@ void mouseScroll(int x, int y) {
|
||||
if (y < 0) {
|
||||
ydir = 5;
|
||||
}
|
||||
|
||||
|
||||
if (x < 0) {
|
||||
xdir = 7;
|
||||
}
|
||||
@ -80,13 +80,13 @@ void mouseScroll(int x, int y) {
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
void mouseEvent(unsigned int button, int down) {
|
||||
void XButton(unsigned int button, int down) {
|
||||
Display *display = getXDisplay();
|
||||
XTestFakeButtonEvent(display, button, down, CurrentTime);
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
void keyEvent(unsigned long key, int down) {
|
||||
void XKey(unsigned long key, int down) {
|
||||
Display *display = getXDisplay();
|
||||
KeyCode code = XKeysymToKeycode(display, key);
|
||||
XTestFakeKeyEvent(display, code, down, CurrentTime);
|
||||
|
@ -134,11 +134,11 @@ func Display(display string) {
|
||||
}
|
||||
|
||||
func Move(x, y int) {
|
||||
C.mouseMove(C.int(x), C.int(y))
|
||||
C.XMove(C.int(x), C.int(y))
|
||||
}
|
||||
|
||||
func Scroll(x, y int) {
|
||||
C.mouseScroll(C.int(x), C.int(y))
|
||||
C.XScroll(C.int(x), C.int(y))
|
||||
}
|
||||
|
||||
func ButtonDown(code int) (*keycode.Button, error) {
|
||||
@ -153,7 +153,7 @@ func ButtonDown(code int) (*keycode.Button, error) {
|
||||
|
||||
debounce[code] = time.Now()
|
||||
|
||||
C.mouseEvent(C.uint(button.Keysym), C.int(1))
|
||||
C.XButton(C.uint(button.Keysym), C.int(1))
|
||||
return &button, nil
|
||||
}
|
||||
|
||||
@ -168,12 +168,11 @@ func KeyDown(code int) (*keycode.Key, error) {
|
||||
}
|
||||
|
||||
debounce[code] = time.Now()
|
||||
|
||||
C.keyEvent(C.ulong(key.Keysym), C.int(1))
|
||||
|
||||
C.XKey(C.ulong(key.Keysym), C.int(1))
|
||||
return &key, nil
|
||||
}
|
||||
|
||||
|
||||
func ButtonUp(code int) (*keycode.Button, error) {
|
||||
button, ok := buttons[code]
|
||||
if !ok {
|
||||
@ -186,7 +185,7 @@ func ButtonUp(code int) (*keycode.Button, error) {
|
||||
|
||||
delete(debounce, code)
|
||||
|
||||
C.mouseEvent(C.uint(button.Keysym), C.int(0))
|
||||
C.XButton(C.uint(button.Keysym), C.int(0))
|
||||
return &button, nil
|
||||
}
|
||||
|
||||
@ -202,13 +201,13 @@ func KeyUp(code int) (*keycode.Key, error) {
|
||||
|
||||
delete(debounce, code)
|
||||
|
||||
C.keyEvent(C.ulong(key.Keysym), C.int(0))
|
||||
C.XKey(C.ulong(key.Keysym), C.int(0))
|
||||
return &key, nil
|
||||
}
|
||||
|
||||
func Reset() {
|
||||
for key := range debounce {
|
||||
if (key < 8) {
|
||||
if key < 8 {
|
||||
ButtonUp(key)
|
||||
} else {
|
||||
KeyUp(key)
|
||||
@ -225,7 +224,7 @@ func Check(duration time.Duration) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (key < 8) {
|
||||
if key < 8 {
|
||||
ButtonUp(key)
|
||||
} else {
|
||||
KeyUp(key)
|
||||
|
@ -16,12 +16,13 @@
|
||||
*
|
||||
* Note that this is almost certainly not thread safe. */
|
||||
Display *getXDisplay(void);
|
||||
void closeXDisplay(void);
|
||||
void mouseMove(int x, int y);
|
||||
void mouseScroll(int x, int y);
|
||||
void mouseEvent(unsigned int button, int down);
|
||||
void keyEvent(unsigned long key, int down);
|
||||
|
||||
void XMove(int x, int y);
|
||||
void XScroll(int x, int y);
|
||||
void XButton(unsigned int button, int down);
|
||||
void XKey(unsigned long key, int down);
|
||||
|
||||
void closeXDisplay(void);
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
Reference in New Issue
Block a user