clipboard: make the Linux version compile
							parent
							
								
									9d107007a1
								
							
						
					
					
						commit
						4471314291
					
				| 
						 | 
				
			
			@ -12,25 +12,25 @@ import (
 | 
			
		|||
#include <X11/Xlib.h>
 | 
			
		||||
 | 
			
		||||
// X11
 | 
			
		||||
struct C.Display
 | 
			
		||||
struct C.Atom
 | 
			
		||||
struct C.Window
 | 
			
		||||
struct C.Display{}
 | 
			
		||||
struct C.Atom{}
 | 
			
		||||
struct C.Window{}
 | 
			
		||||
fn C.XInitThreads() int
 | 
			
		||||
fn C.XCloseDisplay(d &Display)
 | 
			
		||||
fn C.XFlush(d &Display)
 | 
			
		||||
fn C.XDestroyWindow(d &Display, w Window)
 | 
			
		||||
fn C.XNextEvent(d Display, e &XEvent)
 | 
			
		||||
fn C.XSetSelectionOwner(d &Display, a Atom, w Window, time int)
 | 
			
		||||
fn C.XGetSelectionOwner(d &Display, a Atom) Window
 | 
			
		||||
fn C.XChangeProperty(d &Display, requestor Window, property Atom, typ Atom, format int, mode int, data voidptr, nelements int) int
 | 
			
		||||
fn C.XSetSelectionOwner(d &Display, a C.Atom, w Window, time int)
 | 
			
		||||
fn C.XGetSelectionOwner(d &Display, a C.Atom) Window
 | 
			
		||||
fn C.XChangeProperty(d &Display, requestor Window, property C.Atom, typ C.Atom, format int, mode int, data voidptr, nelements int) int
 | 
			
		||||
fn C.XSendEvent(d &Display, requestor Window, propogate int, mask i64, event &XEvent)
 | 
			
		||||
fn C.XInternAtom(d &Display, typ byteptr, only_if_exists int) Atom
 | 
			
		||||
fn C.XInternAtom(d &Display, typ byteptr, only_if_exists int) C.Atom
 | 
			
		||||
fn C.XCreateSimpleWindow(d &Display, root Window, x int, y int, width u32, height u32, border_width u32, border u64, background u64) Window
 | 
			
		||||
fn C.XOpenDisplay(name byteptr) &Display
 | 
			
		||||
fn C.XConvertSelection(d &Display, selection Atom, target Atom, property Atom, requestor Window, time int) int
 | 
			
		||||
fn C.XConvertSelection(d &Display, selection C.Atom, target C.Atom, property C.Atom, requestor Window, time int) int
 | 
			
		||||
fn C.XSync(d &Display, discard int) int
 | 
			
		||||
fn C.XGetWindowProperty(d &Display, w Window, property Atom, offset i64, length i64, delete int, req_type Atom, actual_type_return &Atom, actual_format_return &int, nitems &i64, bytes_after_return &i64, prop_return &byteptr) int
 | 
			
		||||
fn C.XDeleteProperty(d &Display, w Window, property Atom) int
 | 
			
		||||
fn C.XGetWindowProperty(d &Display, w Window, property C.Atom, offset i64, length i64, delete int, req_type C.Atom, actual_type_return &C.Atom, actual_format_return &int, nitems &i64, bytes_after_return &i64, prop_return &byteptr) int
 | 
			
		||||
fn C.XDeleteProperty(d &Display, w Window, property C.Atom) int
 | 
			
		||||
fn C.DefaultScreen() int
 | 
			
		||||
fn C.RootWindow() voidptr
 | 
			
		||||
fn C.BlackPixel() voidptr
 | 
			
		||||
| 
						 | 
				
			
			@ -39,28 +39,28 @@ fn C.XFree()
 | 
			
		|||
 | 
			
		||||
struct C.XSelectionRequestEvent{
 | 
			
		||||
	mut:
 | 
			
		||||
	selection Atom
 | 
			
		||||
	selection C.Atom
 | 
			
		||||
	display &Display	/* Display the event was read from */
 | 
			
		||||
	owner Window
 | 
			
		||||
	requestor Window
 | 
			
		||||
	target Atom
 | 
			
		||||
	property Atom
 | 
			
		||||
	target C.Atom
 | 
			
		||||
	property C.Atom
 | 
			
		||||
	time int
 | 
			
		||||
}
 | 
			
		||||
struct C.XSelectionEvent{
 | 
			
		||||
	mut:
 | 
			
		||||
	@type int
 | 
			
		||||
	selection Atom
 | 
			
		||||
	selection C.Atom
 | 
			
		||||
	display &Display	/* Display the event was read from */
 | 
			
		||||
	requestor Window
 | 
			
		||||
	target Atom
 | 
			
		||||
	property Atom
 | 
			
		||||
	target C.Atom
 | 
			
		||||
	property C.Atom
 | 
			
		||||
	time int
 | 
			
		||||
}
 | 
			
		||||
struct C.XSelectionClearEvent{
 | 
			
		||||
	mut:
 | 
			
		||||
	window Window
 | 
			
		||||
	selection Atom
 | 
			
		||||
	selection C.Atom
 | 
			
		||||
}
 | 
			
		||||
struct C.XDestroyWindowEvent {
 | 
			
		||||
	mut:
 | 
			
		||||
| 
						 | 
				
			
			@ -69,10 +69,10 @@ struct C.XDestroyWindowEvent {
 | 
			
		|||
struct C.XEvent{
 | 
			
		||||
	mut:
 | 
			
		||||
	@type int
 | 
			
		||||
	xselectionrequest XSelectionRequestEvent
 | 
			
		||||
	xselection XSelectionEvent
 | 
			
		||||
	xselectionclear XSelectionClearEvent
 | 
			
		||||
	xdestroywindow XDestroyWindowEvent
 | 
			
		||||
	xselectionrequest C.XSelectionRequestEvent
 | 
			
		||||
	xselection C.XSelectionEvent
 | 
			
		||||
	xselectionclear C.XSelectionClearEvent
 | 
			
		||||
	xdestroywindow C.XDestroyWindowEvent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ const (
 | 
			
		|||
// currently we only support text
 | 
			
		||||
// in the future, maybe we can extend this
 | 
			
		||||
// to support other mime types
 | 
			
		||||
enum atom_type {
 | 
			
		||||
enum AtomType {
 | 
			
		||||
	xa_atom = 0, //value 4
 | 
			
		||||
	xa_string = 1, //value 31
 | 
			
		||||
	targets = 2,
 | 
			
		||||
| 
						 | 
				
			
			@ -100,9 +100,9 @@ enum atom_type {
 | 
			
		|||
pub struct Clipboard {
 | 
			
		||||
	display &Display
 | 
			
		||||
	mut:
 | 
			
		||||
	selection Atom //the selection atom
 | 
			
		||||
	selection C.Atom //the selection atom
 | 
			
		||||
	window Window
 | 
			
		||||
	atoms []Atom
 | 
			
		||||
	atoms []C.Atom
 | 
			
		||||
	mutex &sync.Mutex
 | 
			
		||||
	text string // text data sent or received
 | 
			
		||||
	got_text bool // used to confirm that we have got the text
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +110,7 @@ pub struct Clipboard {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
struct Property{
 | 
			
		||||
	actual_type Atom
 | 
			
		||||
	actual_type C.Atom
 | 
			
		||||
	actual_format int
 | 
			
		||||
	nitems int
 | 
			
		||||
	data byteptr
 | 
			
		||||
| 
						 | 
				
			
			@ -122,13 +122,13 @@ fn new_clipboard() &Clipboard {
 | 
			
		|||
 | 
			
		||||
// Initialize a new clipboard of the given selection type.
 | 
			
		||||
// We can initialize multiple clipboard instances and use them separately
 | 
			
		||||
fn new_x11_clipboard(selection atom_type) &Clipboard {
 | 
			
		||||
fn new_x11_clipboard(selection AtomType) &Clipboard {
 | 
			
		||||
	if !(selection in [.clipboard, .primary, .secondary]) {
 | 
			
		||||
		panic("Wrong atom_type. Must be one of .primary, .secondary or .clipboard.")
 | 
			
		||||
		panic("Wrong AtomType. Must be one of .primary, .secondary or .clipboard.")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//init x11 thread support
 | 
			
		||||
	status := XInitThreads()
 | 
			
		||||
	status := C.XInitThreads()
 | 
			
		||||
	if status == 0 {
 | 
			
		||||
		println("WARN: this system does not support threads; clipboard will cause the program to lock.")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +158,7 @@ fn (cb &Clipboard) check_availability() bool {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn (cb mut Clipboard) free() {
 | 
			
		||||
	XDestroyWindow(cb.display, cb.window)
 | 
			
		||||
	C.XDestroyWindow(cb.display, cb.window)
 | 
			
		||||
	cb.window = Window(C.None)
 | 
			
		||||
	//FIX ME: program hangs when closing display
 | 
			
		||||
	//XCloseDisplay(cb.display)
 | 
			
		||||
| 
						 | 
				
			
			@ -166,8 +166,8 @@ fn (cb mut Clipboard) free() {
 | 
			
		|||
 | 
			
		||||
fn (cb mut Clipboard) clear(){
 | 
			
		||||
	cb.mutex.lock()
 | 
			
		||||
	XSetSelectionOwner(cb.display, cb.selection, Window(C.None), C.CurrentTime)
 | 
			
		||||
	XFlush(cb.display)
 | 
			
		||||
	C.XSetSelectionOwner(cb.display, cb.selection, Window(C.None), C.CurrentTime)
 | 
			
		||||
	C.XFlush(cb.display)
 | 
			
		||||
	cb.is_owner = false
 | 
			
		||||
	cb.text = ""
 | 
			
		||||
	cb.mutex.unlock()
 | 
			
		||||
| 
						 | 
				
			
			@ -178,8 +178,8 @@ fn (cb &Clipboard) has_ownership() bool {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn (cb &Clipboard) take_ownership(){
 | 
			
		||||
	XSetSelectionOwner(cb.display, cb.selection, cb.window, C.CurrentTime)
 | 
			
		||||
	XFlush(cb.display)
 | 
			
		||||
	C.XSetSelectionOwner(cb.display, cb.selection, cb.window, C.CurrentTime)
 | 
			
		||||
	C.XFlush(cb.display)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (cb mut Clipboard) set_text(text string) bool {
 | 
			
		||||
| 
						 | 
				
			
			@ -188,7 +188,7 @@ fn (cb mut Clipboard) set_text(text string) bool {
 | 
			
		|||
	cb.text = text
 | 
			
		||||
	cb.is_owner = true
 | 
			
		||||
	cb.take_ownership()
 | 
			
		||||
	XFlush(cb.display)
 | 
			
		||||
	C.XFlush(cb.display)
 | 
			
		||||
	cb.mutex.unlock()
 | 
			
		||||
	// sleep a little bit
 | 
			
		||||
	time.sleep(1)
 | 
			
		||||
| 
						 | 
				
			
			@ -203,7 +203,7 @@ fn (cb mut Clipboard) get_text() string {
 | 
			
		|||
	cb.got_text = false
 | 
			
		||||
 | 
			
		||||
	//Request a list of possible conversions, if we're pasting.
 | 
			
		||||
	XConvertSelection(cb.display, cb.selection, cb.get_atom(.targets), cb.selection, cb.window, C.CurrentTime)
 | 
			
		||||
	C.XConvertSelection(cb.display, cb.selection, cb.get_atom(.targets), cb.selection, cb.window, C.CurrentTime)
 | 
			
		||||
 | 
			
		||||
	//wait for the text to arrive
 | 
			
		||||
	mut retries := 5
 | 
			
		||||
| 
						 | 
				
			
			@ -217,13 +217,13 @@ fn (cb mut Clipboard) get_text() string {
 | 
			
		|||
 | 
			
		||||
// this function is crucial to handling all the different data types
 | 
			
		||||
// if we ever support other mimetypes they should be handled here
 | 
			
		||||
fn (cb mut Clipboard) transmit_selection(xse &XSelectionEvent) bool {
 | 
			
		||||
fn (cb mut Clipboard) transmit_selection(xse &C.XSelectionEvent) bool {
 | 
			
		||||
	if xse.target == cb.get_atom(.targets) {
 | 
			
		||||
		targets := cb.get_supported_targets()
 | 
			
		||||
		XChangeProperty(xse.display, xse.requestor, xse.property, cb.get_atom(.xa_atom), 32, C.PropModeReplace, targets.data, targets.len)
 | 
			
		||||
		C.XChangeProperty(xse.display, xse.requestor, xse.property, cb.get_atom(.xa_atom), 32, C.PropModeReplace, targets.data, targets.len)
 | 
			
		||||
	} else if cb.is_supported_target(xse.target) && cb.is_owner && cb.text != "" {
 | 
			
		||||
		cb.mutex.lock()
 | 
			
		||||
		XChangeProperty(xse.display, xse.requestor, xse.property, xse.target, 8, C.PropModeReplace, cb.text.str, cb.text.len)
 | 
			
		||||
		C.XChangeProperty(xse.display, xse.requestor, xse.property, xse.target, 8, C.PropModeReplace, cb.text.str, cb.text.len)
 | 
			
		||||
		cb.mutex.unlock()
 | 
			
		||||
	} else {
 | 
			
		||||
		return false
 | 
			
		||||
| 
						 | 
				
			
			@ -232,11 +232,11 @@ fn (cb mut Clipboard) transmit_selection(xse &XSelectionEvent) bool {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn (cb mut Clipboard) start_listener(){
 | 
			
		||||
	event := XEvent{}
 | 
			
		||||
	event := C.XEvent{}
 | 
			
		||||
	mut sent_request := false
 | 
			
		||||
	mut to_be_requested := Atom(0)
 | 
			
		||||
	mut to_be_requested := C.Atom(0)
 | 
			
		||||
	for {
 | 
			
		||||
		XNextEvent(cb.display, &event)
 | 
			
		||||
		C.XNextEvent(cb.display, &event)
 | 
			
		||||
		if event.@type == 0 {
 | 
			
		||||
			println("error")
 | 
			
		||||
           	continue
 | 
			
		||||
| 
						 | 
				
			
			@ -257,10 +257,10 @@ fn (cb mut Clipboard) start_listener(){
 | 
			
		|||
			}
 | 
			
		||||
			C.SelectionRequest {
 | 
			
		||||
				if event.xselectionrequest.selection == cb.selection {
 | 
			
		||||
					mut xsre := &XSelectionRequestEvent{ display: 0 }
 | 
			
		||||
					mut xsre := &C.XSelectionRequestEvent{ display: 0 }
 | 
			
		||||
					xsre = &event.xselectionrequest
 | 
			
		||||
 | 
			
		||||
					mut xse := XSelectionEvent{
 | 
			
		||||
					mut xse := C.XSelectionEvent{
 | 
			
		||||
						@type: C.SelectionNotify // 31
 | 
			
		||||
						display: xsre.display
 | 
			
		||||
						requestor: xsre.requestor
 | 
			
		||||
| 
						 | 
				
			
			@ -272,25 +272,25 @@ fn (cb mut Clipboard) start_listener(){
 | 
			
		|||
					if !cb.transmit_selection(&xse) {
 | 
			
		||||
						xse.property = new_atom(C.None)
 | 
			
		||||
					}
 | 
			
		||||
					XSendEvent(cb.display, xse.requestor, 0, C.PropertyChangeMask, &xse)
 | 
			
		||||
					XFlush(cb.display)
 | 
			
		||||
					C.XSendEvent(cb.display, xse.requestor, 0, C.PropertyChangeMask, &xse)
 | 
			
		||||
					C.XFlush(cb.display)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			C.SelectionNotify {
 | 
			
		||||
				if event.xselection.selection == cb.selection && event.xselection.property != Atom(C.None) {
 | 
			
		||||
				if event.xselection.selection == cb.selection && event.xselection.property != C.Atom(C.None) {
 | 
			
		||||
					if event.xselection.target == cb.get_atom(.targets) && !sent_request {
 | 
			
		||||
						sent_request = true
 | 
			
		||||
						prop := read_property(cb.display, cb.window, cb.selection)
 | 
			
		||||
						to_be_requested = cb.pick_target(prop)
 | 
			
		||||
						if to_be_requested != Atom(0) {
 | 
			
		||||
							XConvertSelection(cb.display, cb.selection, to_be_requested, cb.selection, cb.window, C.CurrentTime)
 | 
			
		||||
						if to_be_requested != C.Atom(0) {
 | 
			
		||||
							C.XConvertSelection(cb.display, cb.selection, to_be_requested, cb.selection, cb.window, C.CurrentTime)
 | 
			
		||||
						}
 | 
			
		||||
					} else if event.xselection.target == to_be_requested {
 | 
			
		||||
						sent_request = false
 | 
			
		||||
						to_be_requested = Atom(0)
 | 
			
		||||
						to_be_requested = C.Atom(0)
 | 
			
		||||
						cb.mutex.lock()
 | 
			
		||||
						prop := read_property(event.xselection.display, event.xselection.requestor, event.xselection.property)
 | 
			
		||||
						XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property)
 | 
			
		||||
						C.XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property)
 | 
			
		||||
						if cb.is_supported_target(prop.actual_type) {
 | 
			
		||||
							cb.got_text = true
 | 
			
		||||
							cb.text = string(prop.data) //TODO: return byteptr to support other mimetypes
 | 
			
		||||
| 
						 | 
				
			
			@ -311,19 +311,19 @@ fn (cb mut Clipboard) start_listener(){
 | 
			
		|||
 | 
			
		||||
// Initialize all the atoms we need
 | 
			
		||||
fn (cb mut Clipboard) intern_atoms(){
 | 
			
		||||
	cb.atoms << Atom(4) //XA_ATOM
 | 
			
		||||
	cb.atoms << Atom(31) //XA_STRING
 | 
			
		||||
	cb.atoms << C.Atom(4) //XA_ATOM
 | 
			
		||||
	cb.atoms << C.Atom(31) //XA_STRING
 | 
			
		||||
	for i, name in atom_names{
 | 
			
		||||
		only_if_exists := if i == int(atom_type.utf8_string) {1} else {0}
 | 
			
		||||
		cb.atoms << XInternAtom(cb.display, name.str, only_if_exists)
 | 
			
		||||
		if i == int(atom_type.utf8_string) && cb.atoms[i] == Atom(C.None) {
 | 
			
		||||
		only_if_exists := if i == int(AtomType.utf8_string) {1} else {0}
 | 
			
		||||
		cb.atoms << C.XInternAtom(cb.display, name.str, only_if_exists)
 | 
			
		||||
		if i == int(AtomType.utf8_string) && cb.atoms[i] == C.Atom(C.None) {
 | 
			
		||||
			cb.atoms[i] = cb.get_atom(.xa_string)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn read_property(d &Display, w Window, p Atom) Property {
 | 
			
		||||
	actual_type := Atom(0)
 | 
			
		||||
fn read_property(d &Display, w Window, p C.Atom) Property {
 | 
			
		||||
	actual_type := C.Atom(0)
 | 
			
		||||
	actual_format := 0
 | 
			
		||||
	nitems := 0
 | 
			
		||||
	bytes_after := 0
 | 
			
		||||
| 
						 | 
				
			
			@ -333,7 +333,7 @@ fn read_property(d &Display, w Window, p Atom) Property {
 | 
			
		|||
		if ret != 0 {
 | 
			
		||||
			C.XFree(ret)
 | 
			
		||||
		}
 | 
			
		||||
		XGetWindowProperty(d, w, p, 0, read_bytes, 0, C.AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &ret)
 | 
			
		||||
		C.XGetWindowProperty(d, w, p, 0, read_bytes, 0, C.AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &ret)
 | 
			
		||||
		read_bytes *= 2
 | 
			
		||||
		if bytes_after == 0 {break}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -341,10 +341,10 @@ fn read_property(d &Display, w Window, p Atom) Property {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// Finds the best target given a local copy of a property.
 | 
			
		||||
fn (cb &Clipboard) pick_target(prop Property) Atom {
 | 
			
		||||
fn (cb &Clipboard) pick_target(prop Property) C.Atom {
 | 
			
		||||
	//The list of targets is a list of atoms, so it should have type XA_ATOM
 | 
			
		||||
	//but it may have the type TARGETS instead.
 | 
			
		||||
	if((prop.actual_type != cb.get_atom(.xa_atom) && prop.actual_type != cb.get_atom(.targets)) || prop.actual_format != 32)
 | 
			
		||||
	if (prop.actual_type != cb.get_atom(.xa_atom) && prop.actual_type != cb.get_atom(.targets)) || prop.actual_format != 32
 | 
			
		||||
	{
 | 
			
		||||
		//This would be really broken. Targets have to be an atom list
 | 
			
		||||
		//and applications should support this. Nevertheless, some
 | 
			
		||||
| 
						 | 
				
			
			@ -354,9 +354,9 @@ fn (cb &Clipboard) pick_target(prop Property) Atom {
 | 
			
		|||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		atom_list := &Atom(prop.data)
 | 
			
		||||
		atom_list := &C.Atom(prop.data)
 | 
			
		||||
 | 
			
		||||
		mut to_be_requested := Atom(0)
 | 
			
		||||
		mut to_be_requested := C.Atom(0)
 | 
			
		||||
 | 
			
		||||
		//This is higher than the maximum priority.
 | 
			
		||||
		mut priority := math.max_i32
 | 
			
		||||
| 
						 | 
				
			
			@ -367,7 +367,7 @@ fn (cb &Clipboard) pick_target(prop Property) Atom {
 | 
			
		|||
 | 
			
		||||
			if cb.is_supported_target(atom_list[i]) {
 | 
			
		||||
				index := cb.get_target_index(atom_list[i])
 | 
			
		||||
				if(priority > index && index >= 0)
 | 
			
		||||
				if priority > index && index >= 0
 | 
			
		||||
				{
 | 
			
		||||
					priority = index
 | 
			
		||||
					to_be_requested = atom_list[i]
 | 
			
		||||
| 
						 | 
				
			
			@ -378,47 +378,47 @@ fn (cb &Clipboard) pick_target(prop Property) Atom {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (cb &Clipboard) get_atoms(types ...atom_type) []Atom {
 | 
			
		||||
	mut atoms := []Atom
 | 
			
		||||
fn (cb &Clipboard) get_atoms(types ...AtomType) []C.Atom {
 | 
			
		||||
	mut atoms := []C.Atom
 | 
			
		||||
	for typ in types {
 | 
			
		||||
		atoms << cb.atoms[typ]
 | 
			
		||||
	}
 | 
			
		||||
	return atoms
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (cb &Clipboard) get_atom(typ atom_type) Atom {
 | 
			
		||||
fn (cb &Clipboard) get_atom(typ AtomType) C.Atom {
 | 
			
		||||
	return cb.atoms[typ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (cb &Clipboard) is_supported_target(target Atom) bool {
 | 
			
		||||
fn (cb &Clipboard) is_supported_target(target C.Atom) bool {
 | 
			
		||||
	return cb.get_target_index(target) >= 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (cb &Clipboard) get_target_index(target Atom) int {
 | 
			
		||||
fn (cb &Clipboard) get_target_index(target C.Atom) int {
 | 
			
		||||
	for i, atom in cb.get_supported_targets() {
 | 
			
		||||
		if atom == target {return i}
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (cb &Clipboard) get_supported_targets() []Atom {
 | 
			
		||||
	return cb.get_atoms(atom_type.utf8_string, .xa_string, .text, .text_plain, .text_html)
 | 
			
		||||
fn (cb &Clipboard) get_supported_targets() []C.Atom {
 | 
			
		||||
	return cb.get_atoms(AtomType.utf8_string, .xa_string, .text, .text_plain, .text_html)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn new_atom(value int) &Atom {
 | 
			
		||||
	mut atom := &Atom{}
 | 
			
		||||
fn new_atom(value int) &C.Atom {
 | 
			
		||||
	mut atom := &C.Atom{}
 | 
			
		||||
	atom = value
 | 
			
		||||
	return atom
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn create_xwindow(display &Display) Window {
 | 
			
		||||
	N := C.DefaultScreen(display)
 | 
			
		||||
	return XCreateSimpleWindow(display, C.RootWindow(display, N), 0, 0, 1, 1,
 | 
			
		||||
		0, C.BlackPixel(display, N), C.WhitePixel(display, N))
 | 
			
		||||
	n := C.DefaultScreen(display)
 | 
			
		||||
	return C.XCreateSimpleWindow(display, C.RootWindow(display, n), 0, 0, 1, 1,
 | 
			
		||||
		0, C.BlackPixel(display, n), C.WhitePixel(display, n))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn new_display() &Display {
 | 
			
		||||
	return XOpenDisplay(C.NULL)
 | 
			
		||||
	return C.XOpenDisplay(C.NULL)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create a new PRIMARY clipboard (only supported on Linux)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue