Moved all selector and class initialization for bleh_darwin.m into its own function.

This commit is contained in:
Pietro Gagliardi 2014-04-05 13:30:56 -04:00
parent 338cbc0540
commit 98ae4cb3b8
3 changed files with 41 additions and 56 deletions

View File

@ -24,6 +24,43 @@ though this is not always the case.
/* used by listbox_darwin.go; requires NSString */ /* used by listbox_darwin.go; requires NSString */
id *_NSObservedObjectKey = (id *) (&NSObservedObjectKey); id *_NSObservedObjectKey = (id *) (&NSObservedObjectKey);
/*
These are all the selectors and class IDs used by the functions below.
*/
static SEL s_getIndexes; /* NSIndexSetEntries() */
static id c_NSEvent; /* makeDummyEvent() */
static SEL s_newEvent;
static id c_NSBitmapImageRep; /* drawImage() */
static SEL s_alloc;
static SEL s_initWithBitmapDataPlanes;
static SEL s_drawInRect;
static SEL s_release;
static SEL s_locationInWindow; /* getTranslatedEventPoint() */
static SEL s_convertPointFromView;
static id c_NSFont;
static SEL s_setFont; /* objc_setFont() */
static SEL s_systemFontOfSize;
static SEL s_systemFontSizeForControlSize;
void initBleh()
{
s_getIndexes = sel_getUid("getIndexes:maxCount:inIndexRange:");
c_NSEvent = objc_getClass("NSEvent");
s_newEvent = sel_getUid("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:");
c_NSBitmapImageRep = objc_getClass("NSBitmapImageRep");
s_alloc = sel_getUid("alloc");
s_initWithBitmapDataPlanes = sel_getUid("initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:");
s_drawInRect = sel_getUid("drawInRect:fromRect:operation:fraction:respectFlipped:hints:");
s_release = sel_getUid("release");
s_locationInWindow = sel_getUid("locationInWindow");
s_convertPointFromView = sel_getUid("convertPoint:fromView:");
c_NSFont = objc_getClass("NSFont");
s_setFont = sel_getUid("setFont:");
s_systemFontOfSize = sel_getUid("systemFontOfSize:");
s_systemFontSizeForControlSize = sel_getUid("systemFontSizeForControlSize:");
}
/* /*
NSUInteger is listed as being in <objc/NSObjCRuntime.h>... 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. NSUInteger is listed as being in <objc/NSObjCRuntime.h>... 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.
*/ */
@ -147,9 +184,6 @@ id objc_msgSend_point(id obj, SEL sel, int64_t x, int64_t y)
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. 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;
static BOOL getIndexes_init = NO; /* because we can't initialize it out here */
uintptr_t *NSIndexSetEntries(id indexset, uintptr_t count) uintptr_t *NSIndexSetEntries(id indexset, uintptr_t count)
{ {
NSUInteger *nsuints; NSUInteger *nsuints;
@ -157,14 +191,10 @@ uintptr_t *NSIndexSetEntries(id indexset, uintptr_t count)
uintptr_t i; uintptr_t i;
size_t countsize; size_t countsize;
if (getIndexes_init == NO) {
getIndexes = sel_getUid("getIndexes:maxCount:inIndexRange:");
getIndexes_init = YES;
}
countsize = (size_t) count; countsize = (size_t) count;
nsuints = (NSUInteger *) malloc(countsize * sizeof (NSUInteger)); nsuints = (NSUInteger *) malloc(countsize * sizeof (NSUInteger));
/* TODO check return value */ /* TODO check return value */
objc_msgSend(indexset, getIndexes, objc_msgSend(indexset, s_getIndexes,
nsuints, (NSUInteger) count, nil); nsuints, (NSUInteger) count, nil);
ret = (uintptr_t *) malloc(countsize * sizeof (uintptr_t)); ret = (uintptr_t *) malloc(countsize * sizeof (uintptr_t));
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
@ -178,17 +208,8 @@ uintptr_t *NSIndexSetEntries(id indexset, uintptr_t count)
See uitask_darwin.go: we need to synthesize a NSEvent so -[NSApplication stop:] will work. We cannot simply init the default NSEvent though (it throws an exception) so we must do it "the right way". This involves a very convoluted initializer; we'll just do it here to keep things clean on the Go side (this will only be run once anyway, on program exit). See uitask_darwin.go: we need to synthesize a NSEvent so -[NSApplication stop:] will work. We cannot simply init the default NSEvent though (it throws an exception) so we must do it "the right way". This involves a very convoluted initializer; we'll just do it here to keep things clean on the Go side (this will only be run once anyway, on program exit).
*/ */
static id c_NSEvent;
static SEL s_newEvent;
static BOOL newEvent_init = NO;
id makeDummyEvent() id makeDummyEvent()
{ {
if (newEvent_init == NO) {
c_NSEvent = objc_getClass("NSEvent");
s_newEvent = sel_getUid("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:");
newEvent_init = YES;
}
return objc_msgSend(c_NSEvent, s_newEvent, return objc_msgSend(c_NSEvent, s_newEvent,
(NSUInteger) NSApplicationDefined, /* otherEventWithType: */ (NSUInteger) NSApplicationDefined, /* otherEventWithType: */
NSMakePoint(0, 0), /* location: */ NSMakePoint(0, 0), /* location: */
@ -233,13 +254,6 @@ the NSBitmapImageRep constructor is complex; put it here
the only way to draw a NSBitmapImageRep in a flipped NSView is to use the most complex drawing method; put it here too the only way to draw a NSBitmapImageRep in a flipped NSView is to use the most complex drawing method; put it here too
*/ */
static id c_NSBitmapImageRep;
static SEL s_alloc;
static SEL s_initWithBitmapDataPlanes;
static SEL s_drawInRect;
static SEL s_release;
static BOOL drawImage_init = NO;
/* /*
hey guys you know what's fun? 32-bit ABI changes! hey guys you know what's fun? 32-bit ABI changes!
*/ */
@ -251,14 +265,6 @@ void drawImage(void *pixels, int64_t width, int64_t height, int64_t stride, int6
unsigned char *planes[1]; /* NSBitmapImageRep wants an array of planes; we have one plane */ unsigned char *planes[1]; /* NSBitmapImageRep wants an array of planes; we have one plane */
id bitmap; id bitmap;
if (drawImage_init == NO) {
c_NSBitmapImageRep = objc_getClass("NSBitmapImageRep");
s_alloc = sel_getUid("alloc");
s_initWithBitmapDataPlanes = sel_getUid("initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:");
s_drawInRect = sel_getUid("drawInRect:fromRect:operation:fraction:respectFlipped:hints:");
s_release = sel_getUid("release");
drawImage_init = YES;
}
bitmap = objc_msgSend(c_NSBitmapImageRep, s_alloc); bitmap = objc_msgSend(c_NSBitmapImageRep, s_alloc);
planes[0] = (unsigned char *) pixels; planes[0] = (unsigned char *) pixels;
bitmap = objc_msgSend(bitmap, s_initWithBitmapDataPlanes, bitmap = objc_msgSend(bitmap, s_initWithBitmapDataPlanes,
@ -289,10 +295,6 @@ void drawImage(void *pixels, int64_t width, int64_t height, int64_t stride, int6
more NSPoint fumbling more NSPoint fumbling
*/ */
static SEL s_locationInWindow;
static SEL s_convertPointFromView;
static BOOL getTranslatedEventPoint_init = NO;
static NSPoint (*objc_msgSend_stret_point)(id, SEL, ...) = static NSPoint (*objc_msgSend_stret_point)(id, SEL, ...) =
(NSPoint (*)(id, SEL, ...)) objc_msgSend; (NSPoint (*)(id, SEL, ...)) objc_msgSend;
@ -301,11 +303,6 @@ struct xpoint getTranslatedEventPoint(id self, id event)
NSPoint p; NSPoint p;
struct xpoint ret; struct xpoint ret;
if (getTranslatedEventPoint_init == NO) {
s_locationInWindow = sel_getUid("locationInWindow");
s_convertPointFromView = sel_getUid("convertPoint:fromView:");
getTranslatedEventPoint_init = YES;
}
p = objc_msgSend_stret_point(event, s_locationInWindow); p = objc_msgSend_stret_point(event, s_locationInWindow);
p = objc_msgSend_stret_point(self, s_convertPointFromView, p = objc_msgSend_stret_point(self, s_convertPointFromView,
p, /* convertPoint: */ p, /* convertPoint: */
@ -319,12 +316,6 @@ struct xpoint getTranslatedEventPoint(id self, id event)
we don't need this here technically it can be done in Go just fine but it's easier here we don't need this here technically it can be done in Go just fine but it's easier here
*/ */
static id c_NSFont;
static SEL s_setFont;
static SEL s_systemFontOfSize;
static SEL s_systemFontSizeForControlSize;
static BOOL setFont_init = NO;
static CGFloat (*objc_msgSend_cgfloatret)(id, SEL, ...) = static CGFloat (*objc_msgSend_cgfloatret)(id, SEL, ...) =
(CGFloat (*)(id, SEL, ...)) objc_msgSend_fpret; (CGFloat (*)(id, SEL, ...)) objc_msgSend_fpret;
@ -332,14 +323,6 @@ void objc_setFont(id what, unsigned int csize)
{ {
CGFloat size; CGFloat size;
if (setFont_init == NO) {
c_NSFont = objc_getClass("NSFont");
s_setFont = sel_getUid("setFont:");
s_systemFontOfSize = sel_getUid("systemFontOfSize:");
s_systemFontSizeForControlSize = sel_getUid("systemFontSizeForControlSize:");
setFont_init = YES;
}
size = objc_msgSend_cgfloatret(c_NSFont, s_systemFontSizeForControlSize, (NSControlSize) csize); size = objc_msgSend_cgfloatret(c_NSFont, s_systemFontSizeForControlSize, (NSControlSize) csize);
objc_msgSend(what, s_setFont, objc_msgSend(what, s_setFont,
objc_msgSend(c_NSFont, s_systemFontOfSize, size)); objc_msgSend(c_NSFont, s_systemFontOfSize, size));

View File

@ -107,6 +107,7 @@ m4(id_id_id_id, id, id, id, id)
extern uintptr_t *NSIndexSetEntries(id, uintptr_t); extern uintptr_t *NSIndexSetEntries(id, uintptr_t);
/* for uitask_darwin.go */ /* for uitask_darwin.go */
extern void initBleh();
extern id makeDummyEvent(); extern id makeDummyEvent();
/* for area_darwin.go */ /* for area_darwin.go */

View File

@ -84,9 +84,10 @@ var (
) )
func initCocoa() (NSApp C.id, err error) { func initCocoa() (NSApp C.id, err error) {
C.initBleh() // initialize bleh_darwin.m functions
NSApp = C.objc_msgSend_noargs(_NSApplication, _sharedApplication) NSApp = C.objc_msgSend_noargs(_NSApplication, _sharedApplication)
r := C.objc_msgSend_int(NSApp, _setActivationPolicy, r := C.objc_msgSend_int(NSApp, _setActivationPolicy,
0) // NSApplicationActivationPolicyRegular 0) // NSApplicationActivationPolicyRegular
if C.BOOL(uintptr(unsafe.Pointer(r))) != C.BOOL(C.YES) { if C.BOOL(uintptr(unsafe.Pointer(r))) != C.BOOL(C.YES) {
err = fmt.Errorf("error setting NSApplication activation policy (basically identifies our program as a separate program; needed for several things, such as Dock icon, application menu, window resizing, etc.) (unknown reason)") err = fmt.Errorf("error setting NSApplication activation policy (basically identifies our program as a separate program; needed for several things, such as Dock icon, application menu, window resizing, etc.) (unknown reason)")
return return