Initial commit.
This commit is contained in:
commit
2fb196dd6a
19
README.md
Normal file
19
README.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Clip
|
||||
|
||||
A tiny library to access the MacOS clipboard (a.k.a. NSPasteboard).
|
||||
|
||||
```go
|
||||
go get git.wow.st/gmp/clip
|
||||
```
|
||||
|
||||
## API:
|
||||
|
||||
```go
|
||||
// Clear clears the general pasteboard
|
||||
func Clear()
|
||||
// Set puts a string on the pasteboard, returning true if successful
|
||||
func Set(string) bool
|
||||
// Get retrieves the string currently on the pasteboard.
|
||||
func Get() string
|
||||
```
|
||||
|
34
main.go
Normal file
34
main.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package clip
|
||||
|
||||
import (
|
||||
"git.wow.st/gmp/clip/ns"
|
||||
)
|
||||
|
||||
var pb *ns.NSPasteboard
|
||||
|
||||
func Clear() {
|
||||
if pb == nil {
|
||||
pb = ns.NSPasteboardGeneralPasteboard()
|
||||
}
|
||||
pb.ClearContents()
|
||||
}
|
||||
|
||||
func Set(x string) bool {
|
||||
if pb == nil {
|
||||
pb = ns.NSPasteboardGeneralPasteboard()
|
||||
}
|
||||
pb.ClearContents()
|
||||
return pb.SetString(x)
|
||||
}
|
||||
|
||||
func Get() string {
|
||||
if pb == nil {
|
||||
pb = ns.NSPasteboardGeneralPasteboard()
|
||||
}
|
||||
ret := pb.GetString()
|
||||
if ret.Ptr() == nil {
|
||||
return ""
|
||||
} else {
|
||||
return ret.String()
|
||||
}
|
||||
}
|
53
main_test.go
Normal file
53
main_test.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package clip
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClip1(t *testing.T) {
|
||||
pb = nil
|
||||
ok := Set("test1")
|
||||
if pb == nil {
|
||||
t.Errorf(`1: Set() failed, pb == nil\n`)
|
||||
}
|
||||
if !ok {
|
||||
t.Errorf(`2: Set() failed\n`)
|
||||
}
|
||||
x := Get()
|
||||
if x != "test1" {
|
||||
t.Errorf(`3: expected "test1", got "%s"\n`, x)
|
||||
}
|
||||
pb = nil
|
||||
Get() // should not panic
|
||||
Clear()
|
||||
x = Get()
|
||||
if x != "" {
|
||||
t.Errorf(`4: pasteboard not cleared, got "%s"\n`, x)
|
||||
}
|
||||
ok = Set("test2")
|
||||
if !ok {
|
||||
t.Errorf(`5: Set() failed\n`)
|
||||
}
|
||||
x = Get()
|
||||
if x != "test2" {
|
||||
t.Errorf(`6: expected "test2", got "%s"\n`, x)
|
||||
}
|
||||
Clear()
|
||||
x = Get()
|
||||
if x != "" {
|
||||
t.Errorf(`7: pasteboard was not cleared, got "%s"\n`, x)
|
||||
}
|
||||
|
||||
pb = nil
|
||||
ok = Set("test3")
|
||||
if pb == nil {
|
||||
t.Errorf(`8: Set() failed, pb == nil\n`)
|
||||
}
|
||||
if !ok {
|
||||
t.Errorf("9: Set() failed\n")
|
||||
}
|
||||
x = Get()
|
||||
if x != "test3" {
|
||||
t.Errorf(`10: expected "test3", got "%s"\n`, x)
|
||||
}
|
||||
}
|
6056
ns/main.go-
Normal file
6056
ns/main.go-
Normal file
File diff suppressed because it is too large
Load Diff
211
ns/pasteboard.go
Normal file
211
ns/pasteboard.go
Normal file
|
@ -0,0 +1,211 @@
|
|||
package ns
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -x objective-c -fno-objc-arc
|
||||
#cgo LDFLAGS: -framework AppKit -framework Foundation
|
||||
#pragma clang diagnostic ignored "-Wformat-security"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/NSPasteboard.h>
|
||||
|
||||
void
|
||||
NSObject_inst_Release(void* o) {
|
||||
@autoreleasepool {
|
||||
[(NSObject*)o release];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NSString_inst_Release(void* o) {
|
||||
@autoreleasepool {
|
||||
[(NSString*)o release];
|
||||
}
|
||||
}
|
||||
|
||||
const void* _Nullable
|
||||
NSString_inst_UTF8String(void* o) {
|
||||
const char* _Nullable ret;
|
||||
@autoreleasepool {
|
||||
ret = strdup([(NSString*)o UTF8String]);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
NSPasteboard_inst_Release(void* o) {
|
||||
@autoreleasepool {
|
||||
[(NSPasteboard*)o release];
|
||||
}
|
||||
}
|
||||
|
||||
void* _Nullable
|
||||
NSString_StringWithUTF8String(void* nullTerminatedCString) {
|
||||
NSString* _Nullable ret;
|
||||
@autoreleasepool {
|
||||
ret = [NSString stringWithUTF8String:nullTerminatedCString];
|
||||
if(ret != nil) { [ret retain]; }
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void* _Nonnull
|
||||
NSPasteboard_GeneralPasteboard() {
|
||||
NSPasteboard* _Nonnull ret;
|
||||
@autoreleasepool {
|
||||
ret = [NSPasteboard generalPasteboard];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
NSPasteboard_inst_ClearContents(void* o) {
|
||||
@autoreleasepool {
|
||||
[(NSPasteboard*)o clearContents];
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
NSPasteboard_inst_SetString(void* o, void* string) {
|
||||
BOOL ret;
|
||||
@autoreleasepool {
|
||||
ret = [(NSPasteboard*)o setString:string forType:NSPasteboardTypeString];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* _Nullable
|
||||
NSPasteboard_inst_GetString(void* o) {
|
||||
NSString* _Nullable ret;
|
||||
@autoreleasepool {
|
||||
ret = [(NSPasteboard*)o stringForType:NSPasteboardTypeString];
|
||||
if (ret != nil && ret != o) { [ret retain]; }
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type Id struct {
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
func (o *Id) Ptr() unsafe.Pointer { if o == nil { return nil }; return o.ptr }
|
||||
|
||||
type NSObject interface {
|
||||
Ptr() unsafe.Pointer
|
||||
}
|
||||
|
||||
func (o *Id) Release() {
|
||||
C.NSObject_inst_Release(o.Ptr())
|
||||
runtime.KeepAlive(o)
|
||||
}
|
||||
|
||||
func (o *NSPasteboard) Release() {
|
||||
C.NSPasteboard_inst_Release(o.Ptr())
|
||||
runtime.KeepAlive(o)
|
||||
}
|
||||
|
||||
func (o *NSString) Release() {
|
||||
C.NSString_inst_Release(o.Ptr())
|
||||
runtime.KeepAlive(o)
|
||||
}
|
||||
|
||||
func (c *Char) Free() {
|
||||
C.free(unsafe.Pointer(c))
|
||||
}
|
||||
|
||||
type BOOL C.uchar
|
||||
|
||||
type NSString struct { Id }
|
||||
func (o *NSString) Ptr() unsafe.Pointer { if o == nil { return nil }; return o.ptr }
|
||||
func (o *Id) NSString() *NSString {
|
||||
return (*NSString)(unsafe.Pointer(o))
|
||||
}
|
||||
|
||||
func (o *NSString) UTF8String() *Char {
|
||||
ret := (*Char)(unsafe.Pointer(C.NSString_inst_UTF8String(o.Ptr())))
|
||||
runtime.KeepAlive(o)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (o *NSString) String() string {
|
||||
utf8 := o.UTF8String()
|
||||
ret := utf8.String()
|
||||
utf8.Free()
|
||||
runtime.KeepAlive(o)
|
||||
return ret
|
||||
}
|
||||
|
||||
type NSPasteboard struct { Id }
|
||||
func (o *NSPasteboard) Ptr() unsafe.Pointer { if o == nil { return nil }; return o.ptr }
|
||||
func (o *Id) NSPasteboard() *NSPasteboard {
|
||||
return (*NSPasteboard)(unsafe.Pointer(o))
|
||||
}
|
||||
|
||||
type Char C.char
|
||||
|
||||
func CharWithGoString(s string) *Char {
|
||||
return (*Char)(unsafe.Pointer(C.CString(s)))
|
||||
}
|
||||
|
||||
func (c *Char) String() string {
|
||||
return C.GoString((*C.char)(c))
|
||||
}
|
||||
|
||||
func NSStringWithUTF8String(nullTerminatedCString *Char) *NSString {
|
||||
ret := &NSString{}
|
||||
ret.ptr = unsafe.Pointer(C.NSString_StringWithUTF8String(unsafe.Pointer(nullTerminatedCString)))
|
||||
if ret.ptr == nil { return ret }
|
||||
runtime.SetFinalizer(ret, func(o *NSString) {
|
||||
o.Release()
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
func NSStringWithGoString(string string) *NSString {
|
||||
string_chr := CharWithGoString(string)
|
||||
defer string_chr.Free()
|
||||
ret := NSStringWithUTF8String(string_chr)
|
||||
return ret
|
||||
}
|
||||
|
||||
func NSPasteboardGeneralPasteboard() *NSPasteboard {
|
||||
ret := &NSPasteboard{}
|
||||
ret.ptr = unsafe.Pointer(C.NSPasteboard_GeneralPasteboard())
|
||||
if ret.ptr == nil { return ret }
|
||||
return ret
|
||||
}
|
||||
|
||||
func (o *NSPasteboard) ClearContents() {
|
||||
C.NSPasteboard_inst_ClearContents(o.Ptr())
|
||||
runtime.KeepAlive(o)
|
||||
}
|
||||
|
||||
func (o *NSPasteboard) SetString(s string) bool {
|
||||
string := NSStringWithGoString(s)
|
||||
ret := (C.NSPasteboard_inst_SetString(o.Ptr(), string.Ptr())) != 0
|
||||
runtime.KeepAlive(o)
|
||||
runtime.KeepAlive(string)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (o *NSPasteboard) GetString() *NSString {
|
||||
ret := &NSString{}
|
||||
ret.ptr = unsafe.Pointer(C.NSPasteboard_inst_GetString(o.Ptr()))
|
||||
if ret.ptr == nil { runtime.KeepAlive(o); return ret }
|
||||
if ret.ptr == o.ptr { runtime.KeepAlive(o); return (*NSString)(unsafe.Pointer(o)) }
|
||||
runtime.SetFinalizer(ret, func(o *NSString) {
|
||||
o.Release()
|
||||
})
|
||||
runtime.KeepAlive(o)
|
||||
return ret
|
||||
}
|
||||
|
11
nswrap.yaml
Normal file
11
nswrap.yaml
Normal file
|
@ -0,0 +1,11 @@
|
|||
# binding generator for git.wow.st/gmp/nswrap
|
||||
# original binding is in ns/main.go- and is not used.
|
||||
inputfiles:
|
||||
- /System/Library/Frameworks/AppKit.framework/Headers/NSPasteboard.h
|
||||
classes:
|
||||
- NSPasteboard
|
||||
- NSString
|
||||
enums:
|
||||
- NSPasteboard.*
|
||||
frameworks: [ AppKit, Foundation ]
|
||||
pragma: [ clang diagnostic ignored "-Wformat-security" ]
|
Loading…
Reference in New Issue
Block a user