/* indexing description: "C features for OBJC_CALLBACK_MARSHAL" date: "$Date$" revision: "$Revision$" copyright: "Copyright (c) 2009, Daniel Furrer" */ #include "objc_callback_marshal.h" #include #if EIF_OS==EIF_OS_IPHONE /* There is no NSRect in iOS, only CGRect, defined in UIKit.h. */ #include #define NSRect CGRect #endif EIF_OBJECT callback_object; boolCallbackTYPE callback_bool; voidCallbackTYPE callback_void; voidPtrCallbackTYPE callback_void_ptr; voidPtrPtrCallbackTYPE callback_void_ptr_ptr; voidGeneralCallbackTYPE callback_void_general; void bridge_void (id self, SEL name) { callback_void ( eif_access (callback_object), self, name ); } void bridge_void_ptr (id self, SEL name, void* arg1) { callback_void_ptr ( eif_access (callback_object), self, name, arg1 ); } void bridge_void_ptr_ptr (id self, SEL name, void* arg1, void* arg2) { callback_void_ptr_ptr ( eif_access (callback_object), self, name, arg1, arg2); } BOOL bridge_bool (id self, SEL name) { return callback_bool ( eif_access (callback_object), self, name ); } void bridge_void_general (id self, SEL selector, ...) { int i, nargs; va_list args; va_start (args, selector); Class currentClass = object_getClass (self); Method currentMethod = class_getInstanceMethod (currentClass, selector); NSMethodSignature* sig = [NSMethodSignature signatureWithObjCTypes: method_getTypeEncoding (currentMethod)]; nargs = [sig numberOfArguments]; //printf("\t%s %s (%i Arguments, %s)\n", //class_getName (currentClass), //method_getName (currentMethod), //nargs, //method_getTypeEncoding (currentMethod)); void** arguments = (void**) malloc(sizeof(void*) * nargs); //printf(" Extracting arguments\n"); for (i = 2; i < nargs; i++) { const char* argType = [sig getArgumentTypeAtIndex: i]; if ((!strcmp("@", argType) || !strcmp("*", argType)) && i != 0) { void* arg = va_arg (args, void*); //printf(" %i: %s -> %x\n", i-2, argType, arg); arguments[i-2] = arg; } else if (!strcmp("i", argType)) { int arg = va_arg (args, int); //printf(" %i: %s -> %i\n", i-2, argType, arg); arguments[i-2] = (void*)arg; } else if (!strcmp(@encode(NSRect), argType) || !strcmp("{_NSRect={_NSPoint=ff}{_NSSize=ff}}", argType)) { NSRect arg = va_arg (args, NSRect); // printf(" %i: %s -> (%f x %f)\n", i-2, argType, arg.size.width, arg.size.height); NSRect* argCopy = malloc(sizeof(NSRect)); memcpy (argCopy, &arg, sizeof(NSRect)); arguments[i-2] = (void*)argCopy; } else { NSLog(@"Failed to convert argument of type '%s' \n", argType); arguments[i-2] = (void*)0; } } callback_void_general (eif_access (callback_object), self, selector, arguments, nargs); va_end(args); } void connect_callbacks (EIF_OBJECT a_callback_object, voidCallbackTYPE a_callback_void, boolCallbackTYPE a_callback_bool, voidPtrCallbackTYPE a_callback_void_ptr, voidPtrPtrCallbackTYPE a_callback_void_ptr_ptr, voidGeneralCallbackTYPE a_callback_void_general) { callback_object = eif_adopt (a_callback_object); callback_bool = a_callback_bool; callback_void = a_callback_void; callback_void_ptr = a_callback_void_ptr; callback_void_ptr_ptr = a_callback_void_ptr_ptr; callback_void_general = a_callback_void_general; }