mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
libclipboard
This commit is contained in:
23
server/internal/clip/clip.c
Normal file
23
server/internal/clip/clip.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "clip.h"
|
||||
|
||||
#include <libclipboard.h>
|
||||
#include <string.h>
|
||||
|
||||
clipboard_c *CLIPBOARD = NULL;
|
||||
|
||||
clipboard_c *getClipboard(void) {
|
||||
if (CLIPBOARD == NULL) {
|
||||
CLIPBOARD = clipboard_new(NULL);
|
||||
}
|
||||
return CLIPBOARD;
|
||||
}
|
||||
|
||||
void set_clipboard(char *src) {
|
||||
clipboard_c *cb = getClipboard();
|
||||
clipboard_set_text_ex(cb, src, strlen(src), 0);
|
||||
}
|
||||
|
||||
char * get_clipboard() {
|
||||
clipboard_c *cb = getClipboard();
|
||||
return clipboard_text_ex(cb, NULL, 0);
|
||||
}
|
21
server/internal/clip/clip.go
Normal file
21
server/internal/clip/clip.go
Normal file
@ -0,0 +1,21 @@
|
||||
// NOTE: I have no fucking clue what I'm doing with this,
|
||||
// it works, but I am positive I'm doing this very wrong...
|
||||
// should I be freeing these strings? does go cg them?
|
||||
// pretty sure this *isn't* thread safe either.... /shrug
|
||||
|
||||
package clip
|
||||
|
||||
/*
|
||||
#cgo linux LDFLAGS: -lclipboard
|
||||
|
||||
#include "clip.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func Read() string {
|
||||
return C.GoString(C.get_clipboard())
|
||||
}
|
||||
|
||||
func Write(data string) {
|
||||
C.set_clipboard(C.CString(data))
|
||||
}
|
5
server/internal/clip/clip.h
Normal file
5
server/internal/clip/clip.h
Normal file
@ -0,0 +1,5 @@
|
||||
#include <libclipboard.h>
|
||||
|
||||
clipboard_c *getClipboard(void);
|
||||
void set_clipboard(char *src);
|
||||
char * get_clipboard();
|
@ -1,124 +0,0 @@
|
||||
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,7 +1,7 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"n.eko.moe/neko/internal/hid/clipboard"
|
||||
"n.eko.moe/neko/internal/clip"
|
||||
"n.eko.moe/neko/internal/types"
|
||||
"n.eko.moe/neko/internal/types/event"
|
||||
"n.eko.moe/neko/internal/types/message"
|
||||
@ -113,6 +113,6 @@ func (h *MessageHandler) controlClipboard(id string, session types.Session, payl
|
||||
return nil
|
||||
}
|
||||
|
||||
clipboard.WriteAll(payload.Text)
|
||||
clip.Write(payload.Text)
|
||||
return nil
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"n.eko.moe/neko/internal/hid/clipboard"
|
||||
"n.eko.moe/neko/internal/clip"
|
||||
"n.eko.moe/neko/internal/types"
|
||||
"n.eko.moe/neko/internal/types/config"
|
||||
"n.eko.moe/neko/internal/types/event"
|
||||
@ -81,11 +81,7 @@ func (ws *WebSocketHandler) Start() error {
|
||||
ws.logger.Info().Msg("shutdown")
|
||||
}()
|
||||
|
||||
current := ""
|
||||
clip, err := clipboard.ReadAll()
|
||||
if err == nil && clip != current {
|
||||
current = clip
|
||||
}
|
||||
current := clip.Read()
|
||||
|
||||
for {
|
||||
select {
|
||||
@ -93,16 +89,16 @@ func (ws *WebSocketHandler) Start() error {
|
||||
return
|
||||
default:
|
||||
if ws.sessions.HasHost() {
|
||||
clip, err := clipboard.ReadAll()
|
||||
if err == nil && clip != current {
|
||||
text := clip.Read()
|
||||
if text != current {
|
||||
session, ok := ws.sessions.GetHost()
|
||||
if ok {
|
||||
session.Send(message.Clipboard{
|
||||
Event: event.CONTROL_CLIPBOARD,
|
||||
Text: clip,
|
||||
Text: text,
|
||||
})
|
||||
}
|
||||
current = clip
|
||||
current = text
|
||||
}
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
Reference in New Issue
Block a user