Codebase list golang-github-atotto-clipboard / b5b795f
Import upstream version 0.1.4+git20210312.1.1438b32 Debian Janitor 1 year, 6 months ago
5 changed file(s) with 118 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
00 language: go
11
2 os:
3 - linux
4 - osx
5 - windows
6
27 go:
3 - go1.4.3
4 - go1.5.4
5 - go1.6.4
6 - go1.7.6
7 - go1.8.7
8 - go1.9.4
9 - go1.10
8 - go1.13.x
9 - go1.x
10
11 services:
12 - xvfb
1013
1114 before_install:
1215 - export DISPLAY=:99.0
13 - sh -e /etc/init.d/xvfb start
1416
1517 script:
16 - sudo apt-get install xsel
18 - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get install xsel; fi
1719 - go test -v .
18 - sudo apt-get install xclip
20 - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get install xclip; fi
1921 - go test -v .
0 [![Build Status](https://travis-ci.org/atotto/clipboard.svg?branch=master)](https://travis-ci.org/atotto/clipboard)
0 [![Build Status](https://travis-ci.com/atotto/clipboard.svg?branch=master)](https://travis-ci.com/atotto/clipboard)
11
22 [![GoDoc](https://godoc.org/github.com/atotto/clipboard?status.svg)](http://godoc.org/github.com/atotto/clipboard)
33
0 // Copyright 2013 @atotto. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // +build plan9
5
6 package clipboard
7
8 import (
9 "os"
10 "io/ioutil"
11 )
12
13 func readAll() (string, error) {
14 f, err := os.Open("/dev/snarf")
15 if err != nil {
16 return "", err
17 }
18 defer f.Close()
19
20 str, err := ioutil.ReadAll(f)
21 if err != nil {
22 return "", err
23 }
24
25 return string(str), nil
26 }
27
28 func writeAll(text string) error {
29 f, err := os.OpenFile("/dev/snarf", os.O_WRONLY, 0666)
30 if err != nil {
31 return err
32 }
33 defer f.Close()
34
35 _, err = f.Write([]byte(text))
36 if err != nil {
37 return err
38 }
39
40 return nil
41 }
1414 const (
1515 xsel = "xsel"
1616 xclip = "xclip"
17 wlcopy = "wl-copy"
18 wlpaste = "wl-paste"
17 powershellExe = "powershell.exe"
18 clipExe = "clip.exe"
19 wlcopy = "wl-copy"
20 wlpaste = "wl-paste"
1921 termuxClipboardGet = "termux-clipboard-get"
2022 termuxClipboardSet = "termux-clipboard-set"
2123 )
2224
2325 var (
2426 Primary bool
27 trimDos bool
2528
2629 pasteCmdArgs []string
2730 copyCmdArgs []string
3235 xclipPasteArgs = []string{xclip, "-out", "-selection", "clipboard"}
3336 xclipCopyArgs = []string{xclip, "-in", "-selection", "clipboard"}
3437
38 powershellExePasteArgs = []string{powershellExe, "Get-Clipboard"}
39 clipExeCopyArgs = []string{clipExe}
40
3541 wlpasteArgs = []string{wlpaste, "--no-newline"}
36 wlcopyArgs = []string{wlcopy}
42 wlcopyArgs = []string{wlcopy}
3743
3844 termuxPasteArgs = []string{termuxClipboardGet}
3945 termuxCopyArgs = []string{termuxClipboardSet}
4349
4450 func init() {
4551 if os.Getenv("WAYLAND_DISPLAY") != "" {
46 pasteCmdArgs = wlpasteArgs;
47 copyCmdArgs = wlcopyArgs;
52 pasteCmdArgs = wlpasteArgs
53 copyCmdArgs = wlcopyArgs
4854
4955 if _, err := exec.LookPath(wlcopy); err == nil {
5056 if _, err := exec.LookPath(wlpaste); err == nil {
7682 }
7783 }
7884
85 pasteCmdArgs = powershellExePasteArgs
86 copyCmdArgs = clipExeCopyArgs
87 trimDos = true
88
89 if _, err := exec.LookPath(clipExe); err == nil {
90 if _, err := exec.LookPath(powershellExe); err == nil {
91 return
92 }
93 }
94
7995 Unsupported = true
8096 }
8197
102118 if err != nil {
103119 return "", err
104120 }
105 return string(out), nil
121 result := string(out)
122 if trimDos && len(result) > 1 {
123 result = result[:len(result)-2]
124 }
125 return result, nil
106126 }
107127
108128 func writeAll(text string) error {
66 package clipboard
77
88 import (
9 "runtime"
910 "syscall"
1011 "time"
1112 "unsafe"
1718 )
1819
1920 var (
20 user32 = syscall.MustLoadDLL("user32")
21 openClipboard = user32.MustFindProc("OpenClipboard")
22 closeClipboard = user32.MustFindProc("CloseClipboard")
23 emptyClipboard = user32.MustFindProc("EmptyClipboard")
24 getClipboardData = user32.MustFindProc("GetClipboardData")
25 setClipboardData = user32.MustFindProc("SetClipboardData")
21 user32 = syscall.MustLoadDLL("user32")
22 isClipboardFormatAvailable = user32.MustFindProc("IsClipboardFormatAvailable")
23 openClipboard = user32.MustFindProc("OpenClipboard")
24 closeClipboard = user32.MustFindProc("CloseClipboard")
25 emptyClipboard = user32.MustFindProc("EmptyClipboard")
26 getClipboardData = user32.MustFindProc("GetClipboardData")
27 setClipboardData = user32.MustFindProc("SetClipboardData")
2628
2729 kernel32 = syscall.NewLazyDLL("kernel32")
2830 globalAlloc = kernel32.NewProc("GlobalAlloc")
4951 }
5052
5153 func readAll() (string, error) {
54 // LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution).
55 // 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.
56 runtime.LockOSThread()
57 defer runtime.UnlockOSThread()
58 if formatAvailable, _, err := isClipboardFormatAvailable.Call(cfUnicodetext); formatAvailable == 0 {
59 return "", err
60 }
5261 err := waitOpenClipboard()
5362 if err != nil {
5463 return "", err
5564 }
56 defer closeClipboard.Call()
5765
5866 h, _, err := getClipboardData.Call(cfUnicodetext)
5967 if h == 0 {
68 _, _, _ = closeClipboard.Call()
6069 return "", err
6170 }
6271
6372 l, _, err := globalLock.Call(h)
6473 if l == 0 {
74 _, _, _ = closeClipboard.Call()
6575 return "", err
6676 }
6777
6979
7080 r, _, err := globalUnlock.Call(h)
7181 if r == 0 {
82 _, _, _ = closeClipboard.Call()
7283 return "", err
7384 }
7485
86 closed, _, err := closeClipboard.Call()
87 if closed == 0 {
88 return "", err
89 }
7590 return text, nil
7691 }
7792
7893 func writeAll(text string) error {
94 // LockOSThread ensure that the whole method will keep executing on the same thread from begin to end (it actually locks the goroutine thread attribution).
95 // 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.
96 runtime.LockOSThread()
97 defer runtime.UnlockOSThread()
98
7999 err := waitOpenClipboard()
80100 if err != nil {
81101 return err
82102 }
83 defer closeClipboard.Call()
84103
85104 r, _, err := emptyClipboard.Call(0)
86105 if r == 0 {
106 _, _, _ = closeClipboard.Call()
87107 return err
88108 }
89109
93113 // been allocated using the function with the GMEM_MOVEABLE flag."
94114 h, _, err := globalAlloc.Call(gmemMoveable, uintptr(len(data)*int(unsafe.Sizeof(data[0]))))
95115 if h == 0 {
116 _, _, _ = closeClipboard.Call()
96117 return err
97118 }
98119 defer func() {
103124
104125 l, _, err := globalLock.Call(h)
105126 if l == 0 {
127 _, _, _ = closeClipboard.Call()
106128 return err
107129 }
108130
109131 r, _, err = lstrcpy.Call(l, uintptr(unsafe.Pointer(&data[0])))
110132 if r == 0 {
133 _, _, _ = closeClipboard.Call()
111134 return err
112135 }
113136
114137 r, _, err = globalUnlock.Call(h)
115138 if r == 0 {
116139 if err.(syscall.Errno) != 0 {
140 _, _, _ = closeClipboard.Call()
117141 return err
118142 }
119143 }
120144
121145 r, _, err = setClipboardData.Call(cfUnicodetext, h)
122146 if r == 0 {
147 _, _, _ = closeClipboard.Call()
123148 return err
124149 }
125150 h = 0 // suppress deferred cleanup
151 closed, _, err := closeClipboard.Call()
152 if closed == 0 {
153 return err
154 }
126155 return nil
127156 }