diff --git a/bleh_darwin.m b/bleh_darwin.m index 9e5c309..06e2d75 100644 --- a/bleh_darwin.m +++ b/bleh_darwin.m @@ -28,11 +28,21 @@ id *_NSObservedObjectKey = (id *) (&NSObservedObjectKey); NSUInteger is listed as being in ... which doesn't exist. Rather than relying on undocumented header file locations or explicitly typedef-ing NSUInteger to the (documented) unsigned long, I'll just place things here for maximum safety. I use uintptr_t as that should encompass every possible unsigned long. */ +uintptr_t objc_msgSend_uintret_noargs(id obj, SEL sel) +{ + return (uintptr_t) ((NSUInteger) objc_msgSend(obj, sel)); +} + id _objc_msgSend_uint(id obj, SEL sel, uintptr_t a) { return objc_msgSend(obj, sel, (NSUInteger) a); } +id objc_msgSend_id_uint(id obj, SEL sel, id a, uintptr_t b) +{ + return objc_msgSend(obj, sel, a, (NSUInteger) b); +} + /* same as above, but for NSInteger */ @@ -119,7 +129,8 @@ struct xsize objc_msgSend_stret_size_noargs(id obj, SEL sel) This is a doozy: it deals with a NSUInteger array needed for this one selector, and converts them all into a uintptr_t array so we can use it from Go. The two arrays are created at runtime with malloc(); only the NSUInteger one is freed here, while Go frees the returned one. It's not optimal. */ -static SEL getIndexes = sel_getUid("getIndexes:maxCount:inRange:"); +static SEL getIndexes; +static BOOL getIndexes_init = NO; /* because we can't initialize it out here */ uintptr_t *NSIndexSetEntries(id indexset, uintptr_t count) { @@ -128,6 +139,10 @@ uintptr_t *NSIndexSetEntries(id indexset, uintptr_t count) uintptr_t i; size_t countsize; + if (getIndexes_init == NO) { + getIndexes = sel_getUid("getIndexes:maxCount:inRange:"); + getIndexes_init = YES; + } countsize = (size_t) count; nsuints = (NSUInteger *) malloc(countsize * sizeof (NSUInteger)); /* TODO check return value */ diff --git a/listbox_darwin.go b/listbox_darwin.go index 7569736..74176f5 100644 --- a/listbox_darwin.go +++ b/listbox_darwin.go @@ -2,7 +2,7 @@ package ui import ( - "runtime" + "reflect" "unsafe" ) @@ -15,7 +15,10 @@ PERSONAL TODO - make a post somewhere that does all this in Objective-C itself, */ // #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit +// #include // #include "objc_darwin.h" +// /* cgo doesn't like nil */ +// id nilid = nil; import "C" /* @@ -89,12 +92,12 @@ func appendListboxArray(array C.id, what string) { } func insertListboxArrayBefore(array C.id, what string, before int) { - objc_msgSend_id_uint(array, _insertObjectAtArrangedObjectsIndex, - toListboxItem(what), uintptr(before)) + C.objc_msgSend_id_uint(array, _insertObjectAtArrangedObjectsIndex, + toListboxItem(what), C.uintptr_t(before)) } func deleteListboxArray(array C.id, index int) { - objc_msgSend_id(array, _removeObjectAtArrangedObjectsIndex, uintptr(index)) + objc_msgSend_uint(array, _removeObjectAtArrangedObjectsIndex, uintptr(index)) } func indexListboxArray(array C.id, index int) string { @@ -133,7 +136,7 @@ func bindListboxArray(tableColumn C.id, array C.id) { C.objc_msgSend_id_id_id_id(tableColumn, _bindToObjectWithKeyPathOptions, tableColumnBinding, array, listboxItemKeyPath, - C.id(C.nil)) // no options + C.nilid) // no options } func listboxArray(tableColumn C.id) C.id { @@ -194,19 +197,19 @@ func makeListbox(parentWindow C.id, alternate bool) C.id { } C.objc_msgSend_bool(listbox, _setAllowsMultipleSelection, multi) C.objc_msgSend_bool(listbox, _setAllowsEmptySelection, C.BOOL(C.YES)) - C.objc_msgSend_id(listbox, _setHeaderView, C.id(C.nil)) + C.objc_msgSend_id(listbox, _setHeaderView, C.nilid) // TODO others? windowView := C.objc_msgSend_noargs(parentWindow, _contentView) C.objc_msgSend_id(windowView, _addSubview, listbox) return listbox } -func appendListbox(listbox C.id, what string) { +func appendListbox(listbox C.id, what string, alternate bool) { array := listboxArray(listboxTableColumn(listbox)) appendListboxArray(array, what) } -func insertListboxBefore(listbox C.id, what string, before int) { +func insertListboxBefore(listbox C.id, what string, before int, alternate bool) { array := listboxArray(listboxTableColumn(listbox)) insertListboxArrayBefore(array, what, before) } @@ -215,24 +218,24 @@ func insertListboxBefore(listbox C.id, what string, before int) { // C.NSIndexSetEntries() makes two arrays of size count: one NSUInteger array and one C.uintptr_t array for returning; this makes a third of type []int for using // if only NSUInteger was usable (see bleh_darwin.m) func selectedListboxIndices(listbox C.id) (list []int) { - var cindices []C.uintptr + var cindices []C.uintptr_t indices := C.objc_msgSend_noargs(listbox, _selectedRowIndexes) - count := int(C.objc_msgSend_uintret(indices, _count)) + count := int(C.objc_msgSend_uintret_noargs(indices, _count)) if count == 0 { - ret + return nil } list = make([]int, count) cidx := C.NSIndexSetEntries(indices, C.uintptr_t(count)) - defer C.free(cidx) + defer C.free(unsafe.Pointer(cidx)) pcindices := (*reflect.SliceHeader)(unsafe.Pointer(&cindices)) pcindices.Cap = count pcindices.Len = count - pcindices.Data = uintptr(cidx) + pcindices.Data = uintptr(unsafe.Pointer(cidx)) for i := 0; i < count; i++ { - indices[i] = int(cidx[i]) + list[i] = int(cindices[i]) } - return indices + return list } func selectedListboxTexts(listbox C.id) (texts []string) { diff --git a/objc_darwin.h b/objc_darwin.h index db0ace5..a1ee381 100644 --- a/objc_darwin.h +++ b/objc_darwin.h @@ -47,6 +47,8 @@ struct xsize { extern struct xsize objc_msgSend_stret_size_noargs(id obj, SEL sel); +extern uintptr_t objc_msgSend_uintret_noargs(id objc, SEL sel); + extern intptr_t objc_msgSend_intret_noargs(id obj, SEL sel); #define m1(name, type1) \ @@ -85,12 +87,14 @@ extern id objc_msgSend_int(id obj, SEL sel, intptr_t a); m2(id_id, id, id) extern id _objc_msgSend_rect_bool(id obj, SEL sel, int64_t x, int64_t y, int64_t w, int64_t h, BOOL b); extern id objc_msgSend_id_int(id obj, SEL sel, id a, intptr_t b); +extern id objc_msgSend_id_uint(id obj, SEL sel, id a, uintptr_t b); m3(id_id_id, id, id, id) m3(sel_id_bool, SEL, id, BOOL) extern id _objc_msgSend_rect_uint_uint_bool(id obj, SEL sel, int64_t x, int64_t y, int64_t w, int64_t h, uintptr_t b, uintptr_t c, BOOL d); m4(id_sel_id_id, id, SEL, id, id) +m4(id_id_id_id, id, id, id, id) /* for listbox_darwin.go */ extern uintptr_t *NSIndexSetEntries(id, uintptr_t);