clipboard: fix windows warnings and run vfmt (#6715)

pull/6719/head
Lukas Neubert 2020-11-02 23:00:29 +01:00 committed by GitHub
parent 788de9938a
commit 4ccb219079
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 111 additions and 113 deletions

View File

@ -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 {

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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 {