mirror of
https://github.com/xxjwxc/public.git
synced 2025-09-26 20:01:19 +08:00
1
This commit is contained in:
@@ -126,6 +126,8 @@ func (a *structAnalys) structFieldInfo(astPkg *ast.Package, sinfo *ast.StructTyp
|
|||||||
}
|
}
|
||||||
case *ast.InterfaceType:
|
case *ast.InterfaceType:
|
||||||
info.Type = "Interface"
|
info.Type = "Interface"
|
||||||
|
case *ast.ArrayType:
|
||||||
|
info.Type = "Array"
|
||||||
}
|
}
|
||||||
case *ast.StarExpr:
|
case *ast.StarExpr:
|
||||||
switch x := exp.X.(type) {
|
switch x := exp.X.(type) {
|
||||||
|
27
myclipboard/clipboard/LICENSE
Normal file
27
myclipboard/clipboard/LICENSE
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2013 Ato Araki. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of @atotto. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
48
myclipboard/clipboard/README.md
Normal file
48
myclipboard/clipboard/README.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
[](https://travis-ci.com/atotto/clipboard)
|
||||||
|
|
||||||
|
[](http://godoc.org/github.com/atotto/clipboard)
|
||||||
|
|
||||||
|
# Clipboard for Go
|
||||||
|
|
||||||
|
Provide copying and pasting to the Clipboard for Go.
|
||||||
|
|
||||||
|
Build:
|
||||||
|
|
||||||
|
$ go get github.com/atotto/clipboard
|
||||||
|
|
||||||
|
Platforms:
|
||||||
|
|
||||||
|
* OSX
|
||||||
|
* Windows 7 (probably work on other Windows)
|
||||||
|
* Linux, Unix (requires 'xclip' or 'xsel' command to be installed)
|
||||||
|
|
||||||
|
|
||||||
|
Document:
|
||||||
|
|
||||||
|
* http://godoc.org/github.com/atotto/clipboard
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* Text string only
|
||||||
|
* UTF-8 text encoding only (no conversion)
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
|
||||||
|
* Clipboard watcher(?)
|
||||||
|
|
||||||
|
## Commands:
|
||||||
|
|
||||||
|
paste shell command:
|
||||||
|
|
||||||
|
$ go get github.com/atotto/clipboard/cmd/gopaste
|
||||||
|
$ # example:
|
||||||
|
$ gopaste > document.txt
|
||||||
|
|
||||||
|
copy shell command:
|
||||||
|
|
||||||
|
$ go get github.com/atotto/clipboard/cmd/gocopy
|
||||||
|
$ # example:
|
||||||
|
$ cat document.txt | gocopy
|
||||||
|
|
||||||
|
|
||||||
|
|
20
myclipboard/clipboard/clipboard.go
Normal file
20
myclipboard/clipboard/clipboard.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2013 @atotto. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package clipboard read/write on clipboard
|
||||||
|
package clipboard
|
||||||
|
|
||||||
|
// ReadAll read string from clipboard
|
||||||
|
func ReadAll() (string, error) {
|
||||||
|
return readAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteAll write string to clipboard
|
||||||
|
func WriteAll(text string) error {
|
||||||
|
return writeAll(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unsupported might be set true during clipboard init, to help callers decide
|
||||||
|
// whether or not to offer clipboard options.
|
||||||
|
var Unsupported bool
|
52
myclipboard/clipboard/clipboard_darwin.go
Normal file
52
myclipboard/clipboard/clipboard_darwin.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2013 @atotto. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package clipboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
pasteCmdArgs = "pbpaste"
|
||||||
|
copyCmdArgs = "pbcopy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getPasteCommand() *exec.Cmd {
|
||||||
|
return exec.Command(pasteCmdArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCopyCommand() *exec.Cmd {
|
||||||
|
return exec.Command(copyCmdArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readAll() (string, error) {
|
||||||
|
pasteCmd := getPasteCommand()
|
||||||
|
out, err := pasteCmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(out), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeAll(text string) error {
|
||||||
|
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()
|
||||||
|
}
|
42
myclipboard/clipboard/clipboard_plan9.go
Normal file
42
myclipboard/clipboard/clipboard_plan9.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2013 @atotto. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build plan9
|
||||||
|
|
||||||
|
package clipboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func readAll() (string, error) {
|
||||||
|
f, err := os.Open("/dev/snarf")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
str, err := ioutil.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(str), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeAll(text string) error {
|
||||||
|
f, err := os.OpenFile("/dev/snarf", os.O_WRONLY, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = f.Write([]byte(text))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
73
myclipboard/clipboard/clipboard_test.go
Normal file
73
myclipboard/clipboard/clipboard_test.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2013 @atotto. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package clipboard_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/atotto/clipboard"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCopyAndPaste(t *testing.T) {
|
||||||
|
expected := "日本語"
|
||||||
|
|
||||||
|
err := WriteAll(expected)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if actual != expected {
|
||||||
|
t.Errorf("want %s, got %s", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMultiCopyAndPaste(t *testing.T) {
|
||||||
|
expected1 := "French: éèêëàùœç"
|
||||||
|
expected2 := "Weird UTF-8: 💩☃"
|
||||||
|
|
||||||
|
err := WriteAll(expected1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual1, err := ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if actual1 != expected1 {
|
||||||
|
t.Errorf("want %s, got %s", expected1, actual1)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = WriteAll(expected2)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual2, err := ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if actual2 != expected2 {
|
||||||
|
t.Errorf("want %s, got %s", expected2, actual2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkReadAll(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
ReadAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkWriteAll(b *testing.B) {
|
||||||
|
text := "いろはにほへと"
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
WriteAll(text)
|
||||||
|
}
|
||||||
|
}
|
149
myclipboard/clipboard/clipboard_unix.go
Normal file
149
myclipboard/clipboard/clipboard_unix.go
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
// Copyright 2013 @atotto. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build freebsd linux netbsd openbsd solaris dragonfly
|
||||||
|
|
||||||
|
package clipboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
xsel = "xsel"
|
||||||
|
xclip = "xclip"
|
||||||
|
powershellExe = "powershell.exe"
|
||||||
|
clipExe = "clip.exe"
|
||||||
|
wlcopy = "wl-copy"
|
||||||
|
wlpaste = "wl-paste"
|
||||||
|
termuxClipboardGet = "termux-clipboard-get"
|
||||||
|
termuxClipboardSet = "termux-clipboard-set"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Primary bool
|
||||||
|
trimDos 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"}
|
||||||
|
|
||||||
|
powershellExePasteArgs = []string{powershellExe, "Get-Clipboard"}
|
||||||
|
clipExeCopyArgs = []string{clipExe}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pasteCmdArgs = powershellExePasteArgs
|
||||||
|
copyCmdArgs = clipExeCopyArgs
|
||||||
|
trimDos = true
|
||||||
|
|
||||||
|
if _, err := exec.LookPath(clipExe); err == nil {
|
||||||
|
if _, err := exec.LookPath(powershellExe); 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
|
||||||
|
}
|
||||||
|
result := string(out)
|
||||||
|
if trimDos && len(result) > 1 {
|
||||||
|
result = result[:len(result)-2]
|
||||||
|
}
|
||||||
|
return result, 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()
|
||||||
|
}
|
157
myclipboard/clipboard/clipboard_windows.go
Normal file
157
myclipboard/clipboard/clipboard_windows.go
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
// Copyright 2013 @atotto. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package clipboard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
cfUnicodetext = 13
|
||||||
|
gmemMoveable = 0x0002
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
user32 = syscall.MustLoadDLL("user32")
|
||||||
|
isClipboardFormatAvailable = user32.MustFindProc("IsClipboardFormatAvailable")
|
||||||
|
openClipboard = user32.MustFindProc("OpenClipboard")
|
||||||
|
closeClipboard = user32.MustFindProc("CloseClipboard")
|
||||||
|
emptyClipboard = user32.MustFindProc("EmptyClipboard")
|
||||||
|
getClipboardData = user32.MustFindProc("GetClipboardData")
|
||||||
|
setClipboardData = user32.MustFindProc("SetClipboardData")
|
||||||
|
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32")
|
||||||
|
globalAlloc = kernel32.NewProc("GlobalAlloc")
|
||||||
|
globalFree = kernel32.NewProc("GlobalFree")
|
||||||
|
globalLock = kernel32.NewProc("GlobalLock")
|
||||||
|
globalUnlock = kernel32.NewProc("GlobalUnlock")
|
||||||
|
lstrcpy = kernel32.NewProc("lstrcpyW")
|
||||||
|
)
|
||||||
|
|
||||||
|
// waitOpenClipboard opens the clipboard, waiting for up to a second to do so.
|
||||||
|
func waitOpenClipboard() error {
|
||||||
|
started := time.Now()
|
||||||
|
limit := started.Add(time.Second)
|
||||||
|
var r uintptr
|
||||||
|
var err error
|
||||||
|
for time.Now().Before(limit) {
|
||||||
|
r, _, err = openClipboard.Call(0)
|
||||||
|
if r != 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func readAll() (string, error) {
|
||||||
|
// LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution).
|
||||||
|
// Otherwise if the goroutine switch thread during execution (which is a common practice), the OpenClipboard and CloseClipboard will happen on two different threads, and it will result in a clipboard deadlock.
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
if formatAvailable, _, err := isClipboardFormatAvailable.Call(cfUnicodetext); formatAvailable == 0 {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
err := waitOpenClipboard()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
h, _, err := getClipboardData.Call(cfUnicodetext)
|
||||||
|
if h == 0 {
|
||||||
|
_, _, _ = closeClipboard.Call()
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
l, _, err := globalLock.Call(h)
|
||||||
|
if l == 0 {
|
||||||
|
_, _, _ = closeClipboard.Call()
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
text := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(l))[:])
|
||||||
|
|
||||||
|
r, _, err := globalUnlock.Call(h)
|
||||||
|
if r == 0 {
|
||||||
|
_, _, _ = closeClipboard.Call()
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
closed, _, err := closeClipboard.Call()
|
||||||
|
if closed == 0 {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return text, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeAll(text string) error {
|
||||||
|
// LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution).
|
||||||
|
// Otherwise if the goroutine switch thread during execution (which is a common practice), the OpenClipboard and CloseClipboard will happen on two different threads, and it will result in a clipboard deadlock.
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
err := waitOpenClipboard()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r, _, err := emptyClipboard.Call(0)
|
||||||
|
if r == 0 {
|
||||||
|
_, _, _ = closeClipboard.Call()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
data := syscall.StringToUTF16(text)
|
||||||
|
|
||||||
|
// "If the hMem parameter identifies a memory object, the object must have
|
||||||
|
// been allocated using the function with the GMEM_MOVEABLE flag."
|
||||||
|
h, _, err := globalAlloc.Call(gmemMoveable, uintptr(len(data)*int(unsafe.Sizeof(data[0]))))
|
||||||
|
if h == 0 {
|
||||||
|
_, _, _ = closeClipboard.Call()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if h != 0 {
|
||||||
|
globalFree.Call(h)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
l, _, err := globalLock.Call(h)
|
||||||
|
if l == 0 {
|
||||||
|
_, _, _ = closeClipboard.Call()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r, _, err = lstrcpy.Call(l, uintptr(unsafe.Pointer(&data[0])))
|
||||||
|
if r == 0 {
|
||||||
|
_, _, _ = closeClipboard.Call()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r, _, err = globalUnlock.Call(h)
|
||||||
|
if r == 0 {
|
||||||
|
if err.(syscall.Errno) != 0 {
|
||||||
|
_, _, _ = closeClipboard.Call()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r, _, err = setClipboardData.Call(cfUnicodetext, h)
|
||||||
|
if r == 0 {
|
||||||
|
_, _, _ = closeClipboard.Call()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
h = 0 // suppress deferred cleanup
|
||||||
|
closed, _, err := closeClipboard.Call()
|
||||||
|
if closed == 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
38
myclipboard/clipboard/cmd/gocopy/gocopy.go
Normal file
38
myclipboard/clipboard/cmd/gocopy/gocopy.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/atotto/clipboard"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
timeout := flag.Duration("t", 0, "Erase clipboard after timeout. Durations are specified like \"20s\" or \"2h45m\". 0 (default) means never erase.")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
out, err := ioutil.ReadAll(os.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := clipboard.WriteAll(string(out)); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if timeout != nil && *timeout > 0 {
|
||||||
|
<-time.After(*timeout)
|
||||||
|
text, err := clipboard.ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if text == string(out) {
|
||||||
|
err = clipboard.WriteAll("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
16
myclipboard/clipboard/cmd/gopaste/gopaste.go
Normal file
16
myclipboard/clipboard/cmd/gopaste/gopaste.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/atotto/clipboard"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
text, err := clipboard.ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print(text)
|
||||||
|
}
|
16
myclipboard/clipboard/example_test.go
Normal file
16
myclipboard/clipboard/example_test.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package clipboard_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/atotto/clipboard"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example() {
|
||||||
|
clipboard.WriteAll("日本語")
|
||||||
|
text, _ := clipboard.ReadAll()
|
||||||
|
fmt.Println(text)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// 日本語
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
package myclipboard
|
package myclipboard
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/atotto/clipboard"
|
"github.com/xxjwxc/public/myclipboard/clipboard"
|
||||||
"github.com/xxjwxc/public/mylog"
|
"github.com/xxjwxc/public/mylog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user