clipboard: fix windows warnings and run vfmt (#6715)
parent
788de9938a
commit
4ccb219079
|
@ -2,17 +2,15 @@ module clipboard
|
||||||
|
|
||||||
#include <libkern/OSAtomic.h>
|
#include <libkern/OSAtomic.h>
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#flag -framework Cocoa
|
#flag -framework Cocoa
|
||||||
|
|
||||||
pub struct Clipboard {
|
pub struct Clipboard {
|
||||||
pb voidptr
|
pb voidptr
|
||||||
last_cb_serial i64
|
last_cb_serial i64
|
||||||
mut:
|
mut:
|
||||||
foo int // TODO remove, for mut hack
|
foo int // TODO remove, for mut hack
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_clipboard() &Clipboard{
|
fn new_clipboard() &Clipboard {
|
||||||
pb := voidptr(0)
|
pb := voidptr(0)
|
||||||
#pb = [NSPasteboard generalPasteboard];
|
#pb = [NSPasteboard generalPasteboard];
|
||||||
cb := &Clipboard{
|
cb := &Clipboard{
|
||||||
|
@ -25,18 +23,20 @@ fn (cb &Clipboard) check_availability() bool {
|
||||||
return cb.pb != C.NULL
|
return cb.pb != C.NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) clear(){
|
fn (mut cb Clipboard) clear() {
|
||||||
cb.foo = 0
|
cb.foo = 0
|
||||||
#[cb->pb clearContents];
|
#[cb->pb clearContents];
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) free(){
|
fn (mut cb Clipboard) free() {
|
||||||
cb.foo = 0
|
cb.foo = 0
|
||||||
//nothing to free
|
// nothing to free
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (cb &Clipboard) has_ownership() bool {
|
fn (cb &Clipboard) has_ownership() bool {
|
||||||
if cb.last_cb_serial == 0 {return false}
|
if cb.last_cb_serial == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
#return [cb->pb changeCount] == cb->last_cb_serial;
|
#return [cb->pb changeCount] == cb->last_cb_serial;
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,10 @@ fn (mut cb Clipboard) set_text(text string) bool {
|
||||||
cb.foo = 0
|
cb.foo = 0
|
||||||
#NSString *ns_clip;
|
#NSString *ns_clip;
|
||||||
ret := false
|
ret := false
|
||||||
|
|
||||||
#ns_clip = [[ NSString alloc ] initWithBytesNoCopy:text.str length:text.len encoding:NSUTF8StringEncoding freeWhenDone: false];
|
#ns_clip = [[ NSString alloc ] initWithBytesNoCopy:text.str length:text.len encoding:NSUTF8StringEncoding freeWhenDone: false];
|
||||||
#[cb->pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
#[cb->pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||||
#ret = [cb->pb setString:ns_clip forType:NSStringPboardType];
|
#ret = [cb->pb setString:ns_clip forType:NSStringPboardType];
|
||||||
#[ns_clip release];
|
#[ns_clip release];
|
||||||
|
|
||||||
mut serial := 0
|
mut serial := 0
|
||||||
#serial = [cb->pb changeCount];
|
#serial = [cb->pb changeCount];
|
||||||
C.OSAtomicCompareAndSwapLong(cb.last_cb_serial, serial, &cb.last_cb_serial)
|
C.OSAtomicCompareAndSwapLong(cb.last_cb_serial, serial, &cb.last_cb_serial)
|
||||||
|
@ -63,14 +61,12 @@ fn (mut cb Clipboard) get_text() string {
|
||||||
cb.foo = 0
|
cb.foo = 0
|
||||||
#NSString *ns_clip;
|
#NSString *ns_clip;
|
||||||
utf8_clip := byteptr(0)
|
utf8_clip := byteptr(0)
|
||||||
|
|
||||||
#ns_clip = [cb->pb stringForType:NSStringPboardType]; //NSPasteboardTypeString
|
#ns_clip = [cb->pb stringForType:NSStringPboardType]; //NSPasteboardTypeString
|
||||||
#if (ns_clip == nil) {
|
#if (ns_clip == nil) {
|
||||||
# return tos3(""); //in case clipboard is empty
|
#return tos3(""); //in case clipboard is empty
|
||||||
#}
|
#}
|
||||||
|
|
||||||
#utf8_clip = [ns_clip UTF8String];
|
#utf8_clip = [ns_clip UTF8String];
|
||||||
return unsafe { utf8_clip.vstring() }
|
return unsafe {utf8_clip.vstring()}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_primary() &Clipboard {
|
pub fn new_primary() &Clipboard {
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
module clipboard
|
module clipboard
|
||||||
|
|
||||||
pub struct Clipboard {
|
pub struct Clipboard {
|
||||||
mut:
|
mut:
|
||||||
text string // text data sent or received
|
text string // text data sent or received
|
||||||
got_text bool // used to confirm that we have got the text
|
got_text bool // used to confirm that we have got the text
|
||||||
is_owner bool // to save selection owner state
|
is_owner bool // to save selection owner state
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_clipboard() &Clipboard {
|
fn new_clipboard() &Clipboard {
|
||||||
eprintln('TODO: support clipboard on solaris')
|
eprintln('TODO: support clipboard on solaris')
|
||||||
return &Clipboard{}
|
return &Clipboard{}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_primary() &Clipboard {
|
pub fn new_primary() &Clipboard {
|
||||||
eprintln('TODO: support clipboard on solaris')
|
eprintln('TODO: support clipboard on solaris')
|
||||||
return &Clipboard{}
|
return &Clipboard{}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) set_text(text string) bool {
|
fn (mut cb Clipboard) set_text(text string) bool {
|
||||||
cb.text = text
|
cb.text = text
|
||||||
cb.is_owner = true
|
cb.is_owner = true
|
||||||
cb.got_text = true
|
cb.got_text = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) get_text() string {
|
fn (mut cb Clipboard) get_text() string {
|
||||||
return cb.text
|
return cb.text
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) clear(){
|
fn (mut cb Clipboard) clear() {
|
||||||
cb.text = ''
|
cb.text = ''
|
||||||
cb.is_owner = false
|
cb.is_owner = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) free(){
|
fn (mut cb Clipboard) free() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (cb &Clipboard) has_ownership() bool {
|
fn (cb &Clipboard) has_ownership() bool {
|
||||||
return cb.is_owner
|
return cb.is_owner
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (cb &Clipboard) check_availability() bool {
|
fn (cb &Clipboard) check_availability() bool {
|
||||||
// This is a dummy clipboard implementation,
|
// This is a dummy clipboard implementation,
|
||||||
// which can be always used, although it does not do much...
|
// which can be always used, although it does not do much...
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
import clipboard
|
import clipboard
|
||||||
|
|
||||||
fn run_test(is_primary bool){
|
fn run_test(is_primary bool) {
|
||||||
mut cb := if is_primary {clipboard.new_primary()}else{clipboard.new()}
|
mut cb := if is_primary { clipboard.new_primary() } else { clipboard.new() }
|
||||||
if !cb.is_available() {return}
|
if !cb.is_available() {
|
||||||
|
return
|
||||||
|
}
|
||||||
assert cb.check_ownership() == false
|
assert cb.check_ownership() == false
|
||||||
assert cb.copy("I am a good boy!") == true
|
assert cb.copy('I am a good boy!') == true
|
||||||
assert cb.check_ownership() == true
|
assert cb.check_ownership() == true
|
||||||
assert cb.paste() == "I am a good boy!"
|
assert cb.paste() == 'I am a good boy!'
|
||||||
cb.clear_all()
|
cb.clear_all()
|
||||||
assert cb.paste().len <= 0
|
assert cb.paste().len <= 0
|
||||||
cb.destroy()
|
cb.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_primary(){
|
fn test_primary() {
|
||||||
$if linux {
|
$if linux {
|
||||||
//run_test(true)
|
// run_test(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_clipboard(){
|
fn test_clipboard() {
|
||||||
$if linux {
|
$if linux {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ module clipboard
|
||||||
import time
|
import time
|
||||||
|
|
||||||
#flag -lUser32
|
#flag -lUser32
|
||||||
|
|
||||||
struct WndClassEx {
|
struct WndClassEx {
|
||||||
cb_size u32
|
cb_size u32
|
||||||
style u32
|
style u32
|
||||||
|
@ -15,7 +14,7 @@ struct WndClassEx {
|
||||||
h_cursor C.HCURSOR
|
h_cursor C.HCURSOR
|
||||||
hbr_background C.HBRUSH
|
hbr_background C.HBRUSH
|
||||||
lpsz_menu_name &u16 // LPCWSTR
|
lpsz_menu_name &u16 // LPCWSTR
|
||||||
lpsz_class_name &u16
|
lpsz_class_name &u16
|
||||||
h_icon_sm &u16
|
h_icon_sm &u16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ fn C.RegisterClassEx(class WndClassEx) int
|
||||||
|
|
||||||
fn C.GetClipboardOwner() &C.HWND
|
fn C.GetClipboardOwner() &C.HWND
|
||||||
|
|
||||||
fn C.CreateWindowEx(dwExStyle i64, lpClassName, lpWindowName &u16, dwStyle i64, x, y, nWidth, nHeight int, hWndParent i64, hMenu, h_instance, lpParam voidptr) &C.HWND
|
fn C.CreateWindowEx(dwExStyle i64, lpClassName &u16, lpWindowName &u16, dwStyle i64, x int, y int, nWidth int, nHeight int, hWndParent i64, hMenu voidptr, h_instance voidptr, lpParam voidptr) &C.HWND
|
||||||
|
|
||||||
// fn C.MultiByteToWideChar(CodePage u32, dw_flags u16, lpMultiByteStr byteptr, cbMultiByte int, lpWideCharStr u16, cchWideChar int) int
|
// fn C.MultiByteToWideChar(CodePage u32, dw_flags u16, lpMultiByteStr byteptr, cbMultiByte int, lpWideCharStr u16, cchWideChar int) int
|
||||||
fn C.EmptyClipboard()
|
fn C.EmptyClipboard()
|
||||||
|
@ -51,9 +50,9 @@ fn C.OpenClipboard(hwnd C.HWND) int
|
||||||
fn C.DestroyWindow(hwnd C.HWND)
|
fn C.DestroyWindow(hwnd C.HWND)
|
||||||
|
|
||||||
struct Clipboard {
|
struct Clipboard {
|
||||||
max_retries int
|
max_retries int
|
||||||
retry_delay int
|
retry_delay int
|
||||||
mut:
|
mut:
|
||||||
hwnd C.HWND
|
hwnd C.HWND
|
||||||
foo int // TODO remove
|
foo int // TODO remove
|
||||||
}
|
}
|
||||||
|
@ -66,41 +65,41 @@ fn (cb &Clipboard) get_clipboard_lock() bool {
|
||||||
if retries < 0 {
|
if retries < 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
last_error = C.GetLastError()
|
last_error = C.GetLastError()
|
||||||
if C.OpenClipboard(cb.hwnd) > 0 {
|
if C.OpenClipboard(cb.hwnd) > 0 {
|
||||||
return true
|
return true
|
||||||
} else if last_error != u32(C.ERROR_ACCESS_DENIED) {
|
} else if last_error != u32(C.ERROR_ACCESS_DENIED) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
time.sleep(cb.retry_delay)
|
time.sleep(cb.retry_delay)
|
||||||
}
|
}
|
||||||
C.SetLastError(last_error)
|
C.SetLastError(last_error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_clipboard() &Clipboard {
|
fn new_clipboard() &Clipboard {
|
||||||
mut cb := &Clipboard{
|
mut cb := &Clipboard{
|
||||||
max_retries: 5
|
max_retries: 5
|
||||||
retry_delay: 5
|
retry_delay: 5
|
||||||
}
|
}
|
||||||
class_name := 'clipboard'
|
class_name := 'clipboard'
|
||||||
wndclass := WndClassEx{
|
wndclass := WndClassEx{
|
||||||
cb_size: sizeof(WndClassEx)
|
cb_size: sizeof(WndClassEx)
|
||||||
lpfn_wnd_proc: voidptr(&C.DefWindowProc)
|
lpfn_wnd_proc: voidptr(&C.DefWindowProc)
|
||||||
lpsz_class_name: class_name.to_wide()
|
lpsz_class_name: class_name.to_wide()
|
||||||
lpsz_menu_name: 0
|
lpsz_menu_name: 0
|
||||||
h_icon_sm: 0
|
h_icon_sm: 0
|
||||||
}
|
}
|
||||||
if C.RegisterClassEx(&wndclass) == 0 && C.GetLastError() != u32(C.ERROR_CLASS_ALREADY_EXISTS) {
|
if C.RegisterClassEx(&wndclass) == 0 && C.GetLastError() != u32(C.ERROR_CLASS_ALREADY_EXISTS) {
|
||||||
println('Failed registering class.')
|
println('Failed registering class.')
|
||||||
}
|
}
|
||||||
hwnd := C.CreateWindowEx(0, wndclass.lpsz_class_name, wndclass.lpsz_class_name, 0, 0, 0,
|
hwnd := C.CreateWindowEx(0, wndclass.lpsz_class_name, wndclass.lpsz_class_name, 0,
|
||||||
0, 0, C.HWND_MESSAGE, C.NULL, C.NULL, C.NULL)
|
0, 0, 0, 0, C.HWND_MESSAGE, C.NULL, C.NULL, C.NULL)
|
||||||
if hwnd == C.NULL {
|
if hwnd == C.NULL {
|
||||||
println('Error creating window!')
|
println('Error creating window!')
|
||||||
}
|
}
|
||||||
cb.hwnd = hwnd
|
cb.hwnd = hwnd
|
||||||
return cb
|
return cb
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (cb &Clipboard) check_availability() bool {
|
fn (cb &Clipboard) check_availability() bool {
|
||||||
|
@ -108,73 +107,74 @@ fn (cb &Clipboard) check_availability() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (cb &Clipboard) has_ownership() bool {
|
fn (cb &Clipboard) has_ownership() bool {
|
||||||
return C.GetClipboardOwner() == cb.hwnd
|
return C.GetClipboardOwner() == cb.hwnd
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) clear() {
|
fn (mut cb Clipboard) clear() {
|
||||||
if !cb.get_clipboard_lock() {
|
if !cb.get_clipboard_lock() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
C.EmptyClipboard()
|
C.EmptyClipboard()
|
||||||
C.CloseClipboard()
|
C.CloseClipboard()
|
||||||
cb.foo = 0
|
cb.foo = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) free() {
|
fn (mut cb Clipboard) free() {
|
||||||
C.DestroyWindow(cb.hwnd)
|
C.DestroyWindow(cb.hwnd)
|
||||||
cb.foo = 0
|
cb.foo = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// the string.to_wide doesn't work with SetClipboardData, don't know why
|
// the string.to_wide doesn't work with SetClipboardData, don't know why
|
||||||
fn to_wide(text string) &C.HGLOBAL {
|
fn to_wide(text string) &C.HGLOBAL {
|
||||||
len_required := C.MultiByteToWideChar(C.CP_UTF8, C.MB_ERR_INVALID_CHARS, text.str, text.len +
|
len_required := C.MultiByteToWideChar(C.CP_UTF8, C.MB_ERR_INVALID_CHARS, text.str,
|
||||||
1, C.NULL, 0)
|
text.len + 1, C.NULL, 0)
|
||||||
buf := C.GlobalAlloc(C.GMEM_MOVEABLE, i64(sizeof(u16)) * len_required)
|
buf := C.GlobalAlloc(C.GMEM_MOVEABLE, i64(sizeof(u16)) * len_required)
|
||||||
if buf != C.HGLOBAL(C.NULL) {
|
if buf != C.HGLOBAL(C.NULL) {
|
||||||
mut locked := &u16(C.GlobalLock(buf))
|
mut locked := &u16(C.GlobalLock(buf))
|
||||||
C.MultiByteToWideChar(C.CP_UTF8, C.MB_ERR_INVALID_CHARS, text.str, text.len + 1, locked, len_required)
|
C.MultiByteToWideChar(C.CP_UTF8, C.MB_ERR_INVALID_CHARS, text.str, text.len + 1,
|
||||||
unsafe {
|
locked, len_required)
|
||||||
locked[len_required - 1] = u16(0)
|
unsafe {
|
||||||
}
|
locked[len_required - 1] = u16(0)
|
||||||
C.GlobalUnlock(buf)
|
}
|
||||||
}
|
C.GlobalUnlock(buf)
|
||||||
return buf
|
}
|
||||||
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) set_text(text string) bool {
|
fn (mut cb Clipboard) set_text(text string) bool {
|
||||||
cb.foo = 0
|
cb.foo = 0
|
||||||
buf := to_wide(text)
|
buf := to_wide(text)
|
||||||
if !cb.get_clipboard_lock() {
|
if !cb.get_clipboard_lock() {
|
||||||
C.GlobalFree(buf)
|
C.GlobalFree(buf)
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
// EmptyClipboard must be called to properly update clipboard ownership
|
// EmptyClipboard must be called to properly update clipboard ownership
|
||||||
C.EmptyClipboard()
|
C.EmptyClipboard()
|
||||||
if C.SetClipboardData(C.CF_UNICODETEXT, buf) == C.HANDLE(C.NULL) {
|
if C.SetClipboardData(C.CF_UNICODETEXT, buf) == C.HANDLE(C.NULL) {
|
||||||
println('SetClipboardData: Failed.')
|
println('SetClipboardData: Failed.')
|
||||||
C.CloseClipboard()
|
C.CloseClipboard()
|
||||||
C.GlobalFree(buf)
|
C.GlobalFree(buf)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// CloseClipboard appears to change the sequence number...
|
// CloseClipboard appears to change the sequence number...
|
||||||
C.CloseClipboard()
|
C.CloseClipboard()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut cb Clipboard) get_text() string {
|
fn (mut cb Clipboard) get_text() string {
|
||||||
cb.foo = 0
|
cb.foo = 0
|
||||||
if !cb.get_clipboard_lock() {
|
if !cb.get_clipboard_lock() {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
h_data := C.GetClipboardData(C.CF_UNICODETEXT)
|
h_data := C.GetClipboardData(C.CF_UNICODETEXT)
|
||||||
if h_data == C.HANDLE(C.NULL) {
|
if h_data == C.HANDLE(C.NULL) {
|
||||||
C.CloseClipboard()
|
C.CloseClipboard()
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
str := string_from_wide(&u16(C.GlobalLock(h_data)))
|
str := string_from_wide(&u16(C.GlobalLock(h_data)))
|
||||||
C.GlobalUnlock(h_data)
|
C.GlobalUnlock(h_data)
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_primary() &Clipboard {
|
pub fn new_primary() &Clipboard {
|
||||||
|
|
Loading…
Reference in New Issue