libclipboard

This commit is contained in:
Craig 2020-02-02 22:48:23 +00:00
parent 7253b5ac62
commit ed6f6f5a93
10 changed files with 103 additions and 146 deletions

View File

@ -4,7 +4,7 @@ FROM debian:stretch-slim
# cluster fuck of packages for neko, node, go and gstreamer # cluster fuck of packages for neko, node, go and gstreamer
RUN set -eux; apt-get update; apt-get install -y --no-install-recommends \ RUN set -eux; apt-get update; apt-get install -y --no-install-recommends \
autoconf ca-certificates curl netbase wget \ autoconf ca-certificates curl netbase wget \
bzr git mercurial openssh-client subversion procps automake bzip2 dpkg-dev file g++ gcc \ bzr git mercurial openssh-client subversion procps cmake automake bzip2 dpkg-dev file g++ gcc \
libbz2-dev libc6-dev libcurl4-openssl-dev libdb-dev libevent-dev libffi-dev libgdbm-dev libglib2.0-dev libgmp-dev \ libbz2-dev libc6-dev libcurl4-openssl-dev libdb-dev libevent-dev libffi-dev libgdbm-dev libglib2.0-dev libgmp-dev \
libjpeg-dev libkrb5-dev liblzma-dev libmagickcore-dev libmagickwand-dev libmaxminddb-dev libncurses5-dev libncursesw5-dev \ libjpeg-dev libkrb5-dev liblzma-dev libmagickcore-dev libmagickwand-dev libmaxminddb-dev libncurses5-dev libncursesw5-dev \
libpng-dev libpq-dev libreadline-dev libsqlite3-dev libssl-dev libtool libwebp-dev libxml2-dev libxslt-dev libyaml-dev \ libpng-dev libpq-dev libreadline-dev libsqlite3-dev libssl-dev libtool libwebp-dev libxml2-dev libxslt-dev libyaml-dev \
@ -96,6 +96,17 @@ RUN set -eux; \
ENV GOPATH /go ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
#
# install libclipboard
RUN set -eux; \
cd /tmp ; \
git clone https://github.com/jtanx/libclipboard ; \
cd libclipboard ; \
cmake -DBUILD_SHARED_LIBS=ON -DLIBCLIPBOARD_FORCE_X11=on -DLIBCLIPBOARD_ADD_SOVERSION=ON --prefix=/usr/local . ; \
make -j4; \
make install; \
rm -rf /tmp/libclipboard
# #
# install Go tools w/module support # install Go tools w/module support
RUN set -eux; \ RUN set -eux; \
@ -156,6 +167,10 @@ ARG INSTALL_ZSH="true"
ARG COMMON_SCRIPT_SOURCE="https://raw.githubusercontent.com/microsoft/vscode-dev-containers/master/script-library/common-debian.sh" ARG COMMON_SCRIPT_SOURCE="https://raw.githubusercontent.com/microsoft/vscode-dev-containers/master/script-library/common-debian.sh"
ARG COMMON_SCRIPT_SHA="dev-mode" ARG COMMON_SCRIPT_SHA="dev-mode"
#
# Docker Compose version
ARG COMPOSE_VERSION=1.24.0
# #
# verify git, common tools / libs installed, add/modify non-root user, optionally install zsh # verify git, common tools / libs installed, add/modify non-root user, optionally install zsh
RUN set -eux; \ RUN set -eux; \

View File

@ -7,19 +7,19 @@
"settings": { "settings": {
"terminal.integrated.shell.linux": "/bin/bash", "terminal.integrated.shell.linux": "/bin/bash",
"go.gopath": "/go" "go.gopath": "/go"
}, },
"extensions": [ "extensions": [
"ms-vscode.go", "ms-vscode.go",
"octref.vetur", "octref.vetur",
"ms-vscode.cpptools",
"esbenp.prettier-vscode", "esbenp.prettier-vscode",
"dbaeumer.vscode-eslint", "dbaeumer.vscode-eslint",
"ms-vscode-remote.vscode-remote-extensionpack", "ms-vscode-remote.vscode-remote-extensionpack",
"ms-vscode-remote.remote-containers", "ms-vscode-remote.remote-containers",
"ms-azuretools.vscode-docker", "ms-azuretools.vscode-docker",
"editorconfig.editorconfig", "editorconfig.editorconfig",
"psioniq.psi-header",
"gruntfuggly.todo-tree", "gruntfuggly.todo-tree",
"swyphcosmo.spellchecker", "eamodio.gitlens",
"eamodio.gitlens" "swyphcosmo.spellchecker"
] ]
} }

View File

@ -1,5 +1,6 @@
FROM debian:stretch-slim FROM debian:stretch-slim
#
# avoid warnings by switching to noninteractive # avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
@ -7,9 +8,27 @@ ARG USERNAME=neko
ARG USER_UID=1000 ARG USER_UID=1000
ARG USER_GID=$USER_UID ARG USER_GID=$USER_UID
#
# install libclipboard
RUN set -eux; apt-get update; \
apt-get install -y --no-install-recommends ca-certificates git cmake pkg-config build-essential libx11-dev ; \
cd /tmp ; \
git clone https://github.com/jtanx/libclipboard ; \
cd libclipboard ; \
cmake -DBUILD_SHARED_LIBS=ON -DLIBCLIPBOARD_FORCE_X11=on -DLIBCLIPBOARD_ADD_SOVERSION=ON --prefix=/usr/local . ; \
make -j4; \
make install; \
rm -rf /tmp/libclipboard ; \
#
# clean up
apt-get autoremove -y git cmake pkg-config build-essential libx11-dev; \
apt-get clean -y; \
rm -rf /var/lib/apt/lists/* /var/cache/apt/*
#
# install neko dependencies # install neko dependencies
RUN set -eux; apt-get update; \ RUN set -eux; apt-get update; \
apt-get install -y --no-install-recommends wget ca-certificates pulseaudio openbox dbus-x11 xvfb xclip supervisor; \ apt-get install -y --no-install-recommends wget ca-certificates pulseaudio openbox dbus-x11 xvfb supervisor; \
apt-get install -y --no-install-recommends libxv1 libopus0 libvpx4; \ apt-get install -y --no-install-recommends libxv1 libopus0 libvpx4; \
# #
# create a non-root user # create a non-root user
@ -31,15 +50,16 @@ RUN set -eux; apt-get update; \
chown -R $USERNAME:$USERNAME /home/$USERNAME; \ chown -R $USERNAME:$USERNAME /home/$USERNAME; \
# #
# clean up # clean up
apt-get autoremove -y; \
apt-get clean -y; \ apt-get clean -y; \
rm -rf /var/lib/apt/lists/* /var/cache/apt/* rm -rf /var/lib/apt/lists/* /var/cache/apt/*
#
# add gst to env # add gst to env
ENV PATH=/gst/local/bin:$PATH ENV PATH=/gst/local/bin:$PATH
ENV LD_LIBRARY_PATH=/gst/local/lib:$LD_LIBRARY_PATH ENV LD_LIBRARY_PATH=/gst/local/lib:$LD_LIBRARY_PATH
ENV PKG_CONFIG_PATH=/gst/local/lib/pkgconfig:$PKG_CONFIG_PATH ENV PKG_CONFIG_PATH=/gst/local/lib/pkgconfig:$PKG_CONFIG_PATH
#
# copy gst # copy gst
COPY .build/gst/local /gst/local/ COPY .build/gst/local /gst/local/

View File

@ -33,6 +33,7 @@
"remote.containers.defaultExtensions": [ "remote.containers.defaultExtensions": [
"ms-vscode.go", "ms-vscode.go",
"octref.vetur", "octref.vetur",
"ms-vscode.cpptools",
"esbenp.prettier-vscode", "esbenp.prettier-vscode",
"dbaeumer.vscode-eslint", "dbaeumer.vscode-eslint",
"ms-vscode-remote.vscode-remote-extensionpack", "ms-vscode-remote.vscode-remote-extensionpack",
@ -40,8 +41,8 @@
"ms-azuretools.vscode-docker", "ms-azuretools.vscode-docker",
"editorconfig.editorconfig", "editorconfig.editorconfig",
"gruntfuggly.todo-tree", "gruntfuggly.todo-tree",
"swyphcosmo.spellchecker", "eamodio.gitlens",
"eamodio.gitlens" "swyphcosmo.spellchecker"
], ]
} }
} }

View 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);
}

View 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))
}

View File

@ -0,0 +1,5 @@
#include <libclipboard.h>
clipboard_c *getClipboard(void);
void set_clipboard(char *src);
char * get_clipboard();

View File

@ -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()
}

View File

@ -1,7 +1,7 @@
package websocket package websocket
import ( 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"
"n.eko.moe/neko/internal/types/event" "n.eko.moe/neko/internal/types/event"
"n.eko.moe/neko/internal/types/message" "n.eko.moe/neko/internal/types/message"
@ -113,6 +113,6 @@ func (h *MessageHandler) controlClipboard(id string, session types.Session, payl
return nil return nil
} }
clipboard.WriteAll(payload.Text) clip.Write(payload.Text)
return nil return nil
} }

View File

@ -9,7 +9,7 @@ import (
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/rs/zerolog/log" "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"
"n.eko.moe/neko/internal/types/config" "n.eko.moe/neko/internal/types/config"
"n.eko.moe/neko/internal/types/event" "n.eko.moe/neko/internal/types/event"
@ -81,11 +81,7 @@ func (ws *WebSocketHandler) Start() error {
ws.logger.Info().Msg("shutdown") ws.logger.Info().Msg("shutdown")
}() }()
current := "" current := clip.Read()
clip, err := clipboard.ReadAll()
if err == nil && clip != current {
current = clip
}
for { for {
select { select {
@ -93,16 +89,16 @@ func (ws *WebSocketHandler) Start() error {
return return
default: default:
if ws.sessions.HasHost() { if ws.sessions.HasHost() {
clip, err := clipboard.ReadAll() text := clip.Read()
if err == nil && clip != current { if text != current {
session, ok := ws.sessions.GetHost() session, ok := ws.sessions.GetHost()
if ok { if ok {
session.Send(message.Clipboard{ session.Send(message.Clipboard{
Event: event.CONTROL_CLIPBOARD, Event: event.CONTROL_CLIPBOARD,
Text: clip, Text: text,
}) })
} }
current = clip current = text
} }
} }
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)