Adding upstream version 0.7.0+dfsg.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
f170ee46ad
commit
79ead63b61
35 changed files with 2904 additions and 0 deletions
33
cmd/gclip-gui/AndroidManifest.xml
Normal file
33
cmd/gclip-gui/AndroidManifest.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2021 The golang.design Initiative Authors.
|
||||
All rights reserved. Use of this source code is governed
|
||||
by a MIT license that can be found in the LICENSE file.
|
||||
|
||||
Written by Changkun Ou <changkun.de>
|
||||
-->
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="design.golang.clipboard.gclip"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
|
||||
<!-- In order to access the clipboard, the application manifest must
|
||||
specify the permission requirement. See the following page for
|
||||
details.
|
||||
http://developer.android.com/guide/topics/manifest/manifest-intro.html#perms -->
|
||||
<uses-permission android:name="android.permission.CLIPBOARD" />
|
||||
|
||||
<application android:label="gclip" android:debuggable="true">
|
||||
<activity android:name="org.golang.app.GoNativeActivity"
|
||||
android:label="Gclip"
|
||||
android:configChanges="orientation|keyboardHidden">
|
||||
<meta-data android:name="android.app.lib_name" android:value="Gclip" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
31
cmd/gclip-gui/README.md
Normal file
31
cmd/gclip-gui/README.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
# gclip-gui
|
||||
|
||||
This is a very basic example for verification purpose that demonstrates
|
||||
how the [golang.design/x/clipboard](https://golang.design/x/clipboard)
|
||||
can interact with macOS/Linux/Windows/Android/iOS system clipboard.
|
||||
|
||||
The gclip GUI application writes a string to the system clipboard
|
||||
periodically then reads it back and renders it if possible.
|
||||
|
||||
Because of the system limitation, on mobile devices, only string data is
|
||||
supported at the moment. Hence, one must use clipboard.FmtText. Other supplied
|
||||
formats result in a panic.
|
||||
|
||||
This example is intentded as cross platform application. To build it, one
|
||||
must use [gomobile](https://golang.org/x/mobile). You may follow the instructions
|
||||
provided in the [GoMobile wiki](https://github.com/golang/go/wiki/Mobile) page.
|
||||
|
||||
|
||||
- For desktop: `go build -o gclip-gui`
|
||||
- For Android: `gomobile build -v -target=android -o gclip-gui.apk`
|
||||
- For iOS: `gomobile build -v -target=ios -bundleid design.golang.gclip-gui.app`
|
||||
|
||||
## Screenshots
|
||||
|
||||
| macOS | iOS | Windows | Android | Linux |
|
||||
|:-----:|:---:|:-------:|:-------:|:-----:|
|
||||
||||||
|
||||
|
||||
## License
|
||||
|
||||
MIT | © 2021 The golang.design Initiative Authors, written by [Changkun Ou](https://changkun.de).
|
239
cmd/gclip-gui/main.go
Normal file
239
cmd/gclip-gui/main.go
Normal file
|
@ -0,0 +1,239 @@
|
|||
// Copyright 2021 The golang.design Initiative Authors.
|
||||
// All rights reserved. Use of this source code is governed
|
||||
// by a MIT license that can be found in the LICENSE file.
|
||||
//
|
||||
// Written by Changkun Ou <changkun.de>
|
||||
|
||||
//go:build android || ios || linux || darwin || windows
|
||||
// +build android ios linux darwin windows
|
||||
|
||||
// This is a very basic example for verification purpose that
|
||||
// demonstrates how the golang.design/x/clipboard can interact
|
||||
// with macOS/Linux/Windows/Android/iOS system clipboard.
|
||||
//
|
||||
// The gclip GUI application writes a string to the system clipboard
|
||||
// periodically then reads it back and renders it if possible.
|
||||
//
|
||||
// Because of the system limitation, on mobile devices, only string
|
||||
// data is supported at the moment. Hence, one must use clipboard.FmtText.
|
||||
// Other supplied formats result in a panic.
|
||||
//
|
||||
// This example is intentded as cross platform application.
|
||||
// To build it, one must use gomobile (https://golang.org/x/mobile).
|
||||
// You may follow the instructions provided in the GoMobile's wiki page:
|
||||
// https://github.com/golang/go/wiki/Mobile.
|
||||
//
|
||||
// - For desktop:
|
||||
//
|
||||
// go build -o gclip-gui
|
||||
//
|
||||
// - For Android:
|
||||
//
|
||||
// gomobile build -v -target=android -o gclip-gui.apk
|
||||
//
|
||||
// - For iOS:
|
||||
//
|
||||
// gomobile build -v -target=ios -bundleid design.golang.gclip-gui.app
|
||||
//
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.design/x/clipboard"
|
||||
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/font/basicfont"
|
||||
"golang.org/x/image/math/fixed"
|
||||
"golang.org/x/mobile/app"
|
||||
"golang.org/x/mobile/event/lifecycle"
|
||||
"golang.org/x/mobile/event/paint"
|
||||
"golang.org/x/mobile/event/size"
|
||||
"golang.org/x/mobile/exp/gl/glutil"
|
||||
"golang.org/x/mobile/geom"
|
||||
"golang.org/x/mobile/gl"
|
||||
)
|
||||
|
||||
type Label struct {
|
||||
sz size.Event
|
||||
images *glutil.Images
|
||||
m *glutil.Image
|
||||
drawer *font.Drawer
|
||||
|
||||
mu sync.Mutex
|
||||
data string
|
||||
}
|
||||
|
||||
func NewLabel(images *glutil.Images) *Label {
|
||||
return &Label{
|
||||
images: images,
|
||||
data: "Hello! Gclip.",
|
||||
drawer: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Label) SetLabel(s string) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
l.data = s
|
||||
}
|
||||
|
||||
const (
|
||||
fontWidth = 5
|
||||
fontHeight = 7
|
||||
lineWidth = 100
|
||||
lineHeight = 120
|
||||
)
|
||||
|
||||
func (l *Label) Draw(sz size.Event) {
|
||||
l.mu.Lock()
|
||||
s := l.data
|
||||
l.mu.Unlock()
|
||||
imgW, imgH := lineWidth*basicfont.Face7x13.Width, lineHeight*basicfont.Face7x13.Height
|
||||
if sz.WidthPx == 0 && sz.HeightPx == 0 {
|
||||
return
|
||||
}
|
||||
if imgW > sz.WidthPx {
|
||||
imgW = sz.WidthPx
|
||||
}
|
||||
|
||||
if l.sz != sz {
|
||||
l.sz = sz
|
||||
if l.m != nil {
|
||||
l.m.Release()
|
||||
}
|
||||
l.m = l.images.NewImage(imgW, imgH)
|
||||
}
|
||||
// Clear the drawing image.
|
||||
for i := 0; i < len(l.m.RGBA.Pix); i++ {
|
||||
l.m.RGBA.Pix[i] = 0
|
||||
}
|
||||
|
||||
l.drawer = &font.Drawer{
|
||||
Dst: l.m.RGBA,
|
||||
Src: image.NewUniform(color.RGBA{0, 100, 125, 255}),
|
||||
Face: basicfont.Face7x13,
|
||||
Dot: fixed.P(5, 10),
|
||||
}
|
||||
l.drawer.DrawString(s)
|
||||
l.m.Upload()
|
||||
l.m.Draw(
|
||||
sz,
|
||||
geom.Point{X: 0, Y: 50},
|
||||
geom.Point{X: geom.Pt(imgW), Y: 50},
|
||||
geom.Point{X: 0, Y: geom.Pt(imgH)},
|
||||
l.m.RGBA.Bounds(),
|
||||
)
|
||||
}
|
||||
|
||||
func (l *Label) Release() {
|
||||
if l.m != nil {
|
||||
l.m.Release()
|
||||
l.m = nil
|
||||
l.images = nil
|
||||
}
|
||||
}
|
||||
|
||||
// GclipApp is the application instance.
|
||||
type GclipApp struct {
|
||||
app app.App
|
||||
|
||||
ctx gl.Context
|
||||
siz size.Event
|
||||
|
||||
images *glutil.Images
|
||||
l *Label
|
||||
|
||||
counter int
|
||||
}
|
||||
|
||||
// WatchClipboard watches the system clipboard every seconds.
|
||||
func (g *GclipApp) WatchClipboard() {
|
||||
go func() {
|
||||
tk := time.NewTicker(time.Second)
|
||||
for range tk.C {
|
||||
// Write something to the clipboard
|
||||
w := fmt.Sprintf("(gclip: %d)", g.counter)
|
||||
clipboard.Write(clipboard.FmtText, []byte(w))
|
||||
g.counter++
|
||||
log.Println(w)
|
||||
|
||||
// Read it back and render it, if possible.
|
||||
data := clipboard.Read(clipboard.FmtText)
|
||||
if len(data) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Set the current clipboard data as label content and render on the screen.
|
||||
r := fmt.Sprintf("clipboard: %s", string(data))
|
||||
g.l.SetLabel(r)
|
||||
g.app.Send(paint.Event{})
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (g *GclipApp) OnStart(e lifecycle.Event) {
|
||||
g.ctx, _ = e.DrawContext.(gl.Context)
|
||||
g.images = glutil.NewImages(g.ctx)
|
||||
g.l = NewLabel(g.images)
|
||||
g.app.Send(paint.Event{})
|
||||
}
|
||||
|
||||
func (g *GclipApp) OnStop() {
|
||||
g.l.Release()
|
||||
g.images.Release()
|
||||
g.ctx = nil
|
||||
}
|
||||
|
||||
func (g *GclipApp) OnSize(size size.Event) {
|
||||
g.siz = size
|
||||
}
|
||||
|
||||
func (g *GclipApp) OnDraw() {
|
||||
if g.ctx == nil {
|
||||
return
|
||||
}
|
||||
defer g.app.Send(paint.Event{})
|
||||
defer g.app.Publish()
|
||||
g.ctx.ClearColor(0, 0, 0, 1)
|
||||
g.ctx.Clear(gl.COLOR_BUFFER_BIT)
|
||||
g.l.Draw(g.siz)
|
||||
}
|
||||
|
||||
func init() {
|
||||
err := clipboard.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
app.Main(func(a app.App) {
|
||||
gclip := GclipApp{app: a}
|
||||
gclip.app.Send(size.Event{WidthPx: 800, HeightPx: 500})
|
||||
gclip.WatchClipboard()
|
||||
for e := range gclip.app.Events() {
|
||||
switch e := gclip.app.Filter(e).(type) {
|
||||
case lifecycle.Event:
|
||||
switch e.Crosses(lifecycle.StageVisible) {
|
||||
case lifecycle.CrossOn:
|
||||
gclip.OnStart(e)
|
||||
case lifecycle.CrossOff:
|
||||
gclip.OnStop()
|
||||
os.Exit(0)
|
||||
}
|
||||
case size.Event:
|
||||
gclip.OnSize(e)
|
||||
case paint.Event:
|
||||
gclip.OnDraw()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
40
cmd/gclip/README.md
Normal file
40
cmd/gclip/README.md
Normal file
|
@ -0,0 +1,40 @@
|
|||
# gclip
|
||||
|
||||
`gclip` command offers the ability to interact with the system clipboard
|
||||
from the shell. To install:
|
||||
|
||||
```bash
|
||||
$ go install golang.design/x/clipboard/cmd/gclip@latest
|
||||
```
|
||||
|
||||
```bash
|
||||
$ gclip
|
||||
gclip is a command that provides clipboard interaction.
|
||||
usage: gclip [-copy|-paste] [-f <file>]
|
||||
options:
|
||||
-copy
|
||||
copy data to clipboard
|
||||
-f string
|
||||
source or destination to a given file path
|
||||
-paste
|
||||
paste data from clipboard
|
||||
examples:
|
||||
gclip -paste paste from clipboard and prints the content
|
||||
gclip -paste -f x.txt paste from clipboard and save as text to x.txt
|
||||
gclip -paste -f x.png paste from clipboard and save as image to x.png
|
||||
cat x.txt | gclip -copy copy content from x.txt to clipboard
|
||||
gclip -copy -f x.txt copy content from x.txt to clipboard
|
||||
gclip -copy -f x.png copy x.png as image data to clipboard
|
||||
```
|
||||
|
||||
If `-copy` is used, the command will exit when the data is no longer
|
||||
available from the clipboard. You can always send the command to the
|
||||
background using a shell `&` operator, for example:
|
||||
|
||||
```bash
|
||||
$ cat x.txt | gclip -copy &
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT | © 2021 The golang.design Initiative Authors, written by [Changkun Ou](https://changkun.de).
|
131
cmd/gclip/main.go
Normal file
131
cmd/gclip/main.go
Normal file
|
@ -0,0 +1,131 @@
|
|||
// Copyright 2021 The golang.design Initiative Authors.
|
||||
// All rights reserved. Use of this source code is governed
|
||||
// by a MIT license that can be found in the LICENSE file.
|
||||
//
|
||||
// Written by Changkun Ou <changkun.de>
|
||||
|
||||
package main // go install golang.design/x/clipboard/cmd/gclip@latest
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"golang.design/x/clipboard"
|
||||
)
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, `gclip is a command that provides clipboard interaction.
|
||||
|
||||
usage: gclip [-copy|-paste] [-f <file>]
|
||||
|
||||
options:
|
||||
`)
|
||||
flag.PrintDefaults()
|
||||
fmt.Fprintf(os.Stderr, `
|
||||
examples:
|
||||
gclip -paste paste from clipboard and prints the content
|
||||
gclip -paste -f x.txt paste from clipboard and save as text to x.txt
|
||||
gclip -paste -f x.png paste from clipboard and save as image to x.png
|
||||
|
||||
cat x.txt | gclip -copy copy content from x.txt to clipboard
|
||||
gclip -copy -f x.txt copy content from x.txt to clipboard
|
||||
gclip -copy -f x.png copy x.png as image data to clipboard
|
||||
`)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
var (
|
||||
in = flag.Bool("copy", false, "copy data to clipboard")
|
||||
out = flag.Bool("paste", false, "paste data from clipboard")
|
||||
file = flag.String("f", "", "source or destination to a given file path")
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := clipboard.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
if *out {
|
||||
if err := pst(); err != nil {
|
||||
usage()
|
||||
}
|
||||
return
|
||||
}
|
||||
if *in {
|
||||
if err := cpy(); err != nil {
|
||||
usage()
|
||||
}
|
||||
return
|
||||
}
|
||||
usage()
|
||||
}
|
||||
|
||||
func cpy() error {
|
||||
t := clipboard.FmtText
|
||||
ext := filepath.Ext(*file)
|
||||
|
||||
switch ext {
|
||||
case ".png":
|
||||
t = clipboard.FmtImage
|
||||
case ".txt":
|
||||
fallthrough
|
||||
default:
|
||||
t = clipboard.FmtText
|
||||
}
|
||||
|
||||
var (
|
||||
b []byte
|
||||
err error
|
||||
)
|
||||
if *file != "" {
|
||||
b, err = os.ReadFile(*file)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to read given file: %v", err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
b, err = io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to read from stdin: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Wait until clipboard content has been changed.
|
||||
<-clipboard.Write(t, b)
|
||||
return nil
|
||||
}
|
||||
|
||||
func pst() (err error) {
|
||||
var b []byte
|
||||
|
||||
b = clipboard.Read(clipboard.FmtText)
|
||||
if b == nil {
|
||||
b = clipboard.Read(clipboard.FmtImage)
|
||||
}
|
||||
|
||||
if *file != "" && b != nil {
|
||||
err = os.WriteFile(*file, b, os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to write data to file %s: %v", *file, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
for len(b) > 0 {
|
||||
n, err := os.Stdout.Write(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue