diff --git a/area_darwin.go b/area_darwin.go index c3f7c85..8fc83a2 100644 --- a/area_darwin.go +++ b/area_darwin.go @@ -3,7 +3,6 @@ package ui import ( - "fmt" "unsafe" "image" ) @@ -12,7 +11,6 @@ import ( // #include //// #include // #include "objc_darwin.h" -// extern void areaView_drawRect(id, struct xrect); // extern BOOL areaView_isFlipped_acceptsFirstResponder(id, SEL); // extern void areaView_mouseMoved(id, SEL, id); // extern void areaView_mouseDown_mouseDragged(id, SEL, id); @@ -29,11 +27,11 @@ const ( var ( _goArea C.id _NSView = objc_getClass("NSView") - - _drawRect = sel_getUid("drawRect:") ) var goAreaSels = []selector{ + selector{"drawRect:", uintptr(C._areaView_drawRect), sel_void_rect, + "actually drawing Areas"}, selector{"isFlipped", uintptr(C.areaView_isFlipped_acceptsFirstResponder), sel_bool, "ensuring that an Area's coordinate system has (0,0) at the top-left corner"}, selector{"acceptsFirstResponder", uintptr(C.areaView_isFlipped_acceptsFirstResponder), sel_bool, @@ -67,16 +65,11 @@ var goAreaSels = []selector{ } func mkAreaClass() error { - id, class, err := makeClass(__goArea, _NSView, goAreaSels, + id, err := makeClass(__goArea, _NSView, goAreaSels, "the implementation of Area on Mac OS X") if err != nil { return err } - // addAreaViewDrawMethod() is in bleh_darwin.m - ok := C.addAreaViewDrawMethod(class) - if ok != C.BOOL(C.YES) { - return fmt.Errorf("unable to add selector drawRect: to class %s (needed for actually drawing Areas; reason unknown)", __goArea) - } _goArea = id return nil } diff --git a/bleh_darwin.m b/bleh_darwin.m index f366379..b8f7d93 100644 --- a/bleh_darwin.m +++ b/bleh_darwin.m @@ -210,7 +210,7 @@ id makeDummyEvent() extern void areaView_drawRect(id, struct xrect); -static void _areaView_drawRect(id self, SEL sel, NSRect r) +static void __areaView_drawRect(id self, SEL sel, NSRect r) { struct xrect t; @@ -221,21 +221,15 @@ static void _areaView_drawRect(id self, SEL sel, NSRect r) areaView_drawRect(self, t); } -/* the only objective-c feature you'll see here */ -/* TODO correct? "v@:" @encode(NSRect) complained about missing ; */ -static char *avdrType = @encode(void(id, SEL, NSRect)); +void *_areaView_drawRect = (void *) __areaView_drawRect; -static SEL drawRect; -static BOOL drawRect_init = NO; +/* the only objective-c feature you'll see here -BOOL addAreaViewDrawMethod(Class what) -{ - if (drawRect_init == NO) { - drawRect = sel_getUid("drawRect:"); - drawRect_init = YES; - } - return class_addMethod(what, drawRect, (IMP) _areaView_drawRect, avdrType); -} +unfortunately NSRect both varies across architectures and is passed as just a structure, so its encoding has to be computed at compile time +because @encode() is NOT A LITERAL, we're going to just stick it all the way back in objc_darwin.go +see also: http://stackoverflow.com/questions/6812035/adding-methods-dynamically +*/ +char *encodedNSRect = @encode(NSRect); /* the NSBitmapImageRep constructor is complex; put it here diff --git a/delegate_darwin.go b/delegate_darwin.go index 87cf4d8..00bdf6e 100644 --- a/delegate_darwin.go +++ b/delegate_darwin.go @@ -48,7 +48,7 @@ var appDelegateSels = []selector{ } func mkAppDelegate() error { - id, _, err := makeClass(_goAppDelegate, _NSObject, appDelegateSels, + id, err := makeClass(_goAppDelegate, _NSObject, appDelegateSels, "application delegate (handles events)") if err != nil { return err diff --git a/objc_darwin.go b/objc_darwin.go index b72dcdd..70406f5 100644 --- a/objc_darwin.go +++ b/objc_darwin.go @@ -68,6 +68,7 @@ const ( sel_void_id itype = iota sel_bool_id sel_bool + sel_void_rect nitypes ) @@ -75,9 +76,22 @@ var itypes = [nitypes][]C.char{ sel_void_id: []C.char{'v', '@', ':', '@', 0}, sel_bool_id: []C.char{'c', '@', ':', '@', 0}, sel_bool: []C.char{'c', '@', ':', 0}, + sel_void_rect: nil, // see init() below } -func makeClass(name string, super C.id, sels []selector, desc string) (id C.id, class C.Class, err error) { +func init() { + // see encodedNSRect in bleh_darwin.m + x := make([]C.char, 0, 256) // more than enough + x = append(x, 'v', '@', ':') + y := C.GoString(C.encodedNSRect) + for _, b := range y { + x = append(x, C.char(b)) + } + x = append(x, 0) + itypes[sel_void_rect] = x +} + +func makeClass(name string, super C.id, sels []selector, desc string) (id C.id, err error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) @@ -97,5 +111,5 @@ func makeClass(name string, super C.id, sels []selector, desc string) (id C.id, return } } - return objc_getClass(name), c, nil + return objc_getClass(name), nil } diff --git a/objc_darwin.h b/objc_darwin.h index b8fc2d6..4c1b77a 100644 --- a/objc_darwin.h +++ b/objc_darwin.h @@ -113,10 +113,13 @@ extern uintptr_t *NSIndexSetEntries(id, uintptr_t); extern id makeDummyEvent(); /* for area_darwin.go */ -extern BOOL addAreaViewDrawMethod(Class); +extern void *_areaView_drawRect; extern void drawImage(void *, int64_t, int64_t, int64_t, int64_t, int64_t); extern struct xpoint getTranslatedEventPoint(id, id); +/* for objc_darwin.go */ +extern char *encodedNSRect; + /* for sysdata_darwin.go */ extern void objc_setFont(id, unsigned int);