# IBCarbonsupport.py from macsupport import * from CarbonEvtscan import RefObjectTypes # where should this go? macsupport.py? CFStringRef = OpaqueByValueType('CFStringRef') for typ in RefObjectTypes: execstr = "%(name)s = OpaqueByValueType('%(name)s')" % {"name": typ} exec execstr if 0: # these types will have no methods and will merely be opaque blobs # should write getattr and setattr for them? StructObjectTypes = ["EventTypeSpec", "HIPoint", "HICommand", "EventHotKeyID", ] for typ in StructObjectTypes: execstr = "%(name)s = OpaqueType('%(name)s')" % {"name": typ} exec execstr EventHotKeyID = OpaqueByValueType("EventHotKeyID", "EventHotKeyID") EventTypeSpec_ptr = OpaqueType("EventTypeSpec", "EventTypeSpec") # is this the right type for the void * in GetEventParameter #void_ptr = FixedInputBufferType(1024) void_ptr = stringptr # here are some types that are really other types class MyVarInputBufferType(VarInputBufferType): def passInput(self, name): return "%s__len__, %s__in__" % (name, name) MyInBuffer = MyVarInputBufferType('char', 'long', 'l') # (buf, len) EventTime = double EventTimeout = EventTime EventTimerInterval = EventTime EventAttributes = UInt32 EventParamName = OSType EventParamType = OSType EventPriority = SInt16 EventMask = UInt16 EventComparatorUPP = FakeType("(EventComparatorUPP)0") EventLoopTimerUPP = FakeType("(EventLoopTimerUPP)0") EventHandlerUPP = FakeType("(EventHandlerUPP)0") EventHandlerUPP = FakeType("(EventHandlerUPP)0") EventComparatorProcPtr = FakeType("(EventComparatorProcPtr)0") EventLoopTimerProcPtr = FakeType("(EventLoopTimerProcPtr)0") EventHandlerProcPtr = FakeType("(EventHandlerProcPtr)0") CarbonEventsFunction = OSErrFunctionGenerator CarbonEventsMethod = OSErrMethodGenerator class EventHandlerRefMethod(OSErrMethodGenerator): def precheck(self): OutLbrace('if (_self->ob_itself == NULL)') Output('PyErr_SetString(CarbonEvents_Error, "Handler has been removed");') Output('return NULL;') OutRbrace() includestuff = r""" #ifdef WITHOUT_FRAMEWORKS #include #else #include #endif #include "macglue.h" /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\ PyErr_SetString(PyExc_NotImplementedError, \ "Not available in this shared library/OS version"); \ return; \ }} while(0) #define USE_MAC_MP_MULTITHREADING 0 #if USE_MAC_MP_MULTITHREADING static PyThreadState *_save; static MPCriticalRegionID reentrantLock; #endif /* USE_MAC_MP_MULTITHREADING */ extern int CFStringRef_New(CFStringRef *); extern int CFStringRef_Convert(PyObject *, CFStringRef *); extern int CFBundleRef_Convert(PyObject *, CFBundleRef *); int EventTargetRef_Convert(PyObject *, EventTargetRef *); PyObject *EventHandlerCallRef_New(EventHandlerCallRef itself); PyObject *EventRef_New(EventRef itself); /********** EventTypeSpec *******/ static PyObject* EventTypeSpec_New(EventTypeSpec *in) { return Py_BuildValue("ll", in->eventClass, in->eventKind); } static int EventTypeSpec_Convert(PyObject *v, EventTypeSpec *out) { if (PyArg_Parse(v, "(O&l)", PyMac_GetOSType, &(out->eventClass), &(out->eventKind))) return 1; return NULL; } /********** end EventTypeSpec *******/ /********** HIPoint *******/ #if 0 /* XXX doesn't compile */ static PyObject* HIPoint_New(HIPoint *in) { return Py_BuildValue("ff", in->x, in->y); } static int HIPoint_Convert(PyObject *v, HIPoint *out) { if (PyArg_ParseTuple(v, "ff", &(out->x), &(out->y))) return 1; return NULL; } #endif /********** end HIPoint *******/ /********** EventHotKeyID *******/ static PyObject* EventHotKeyID_New(EventHotKeyID *in) { return Py_BuildValue("ll", in->signature, in->id); } static int EventHotKeyID_Convert(PyObject *v, EventHotKeyID *out) { if (PyArg_ParseTuple(v, "ll", &out->signature, &out->id)) return 1; return NULL; } /********** end EventHotKeyID *******/ /******** myEventHandler ***********/ static EventHandlerUPP myEventHandlerUPP; static pascal OSStatus myEventHandler(EventHandlerCallRef handlerRef, EventRef event, void *outPyObject) { PyObject *retValue; int status; #if USE_MAC_MP_MULTITHREADING MPEnterCriticalRegion(reentrantLock, kDurationForever); PyEval_RestoreThread(_save); #endif /* USE_MAC_MP_MULTITHREADING */ retValue = PyObject_CallFunction((PyObject *)outPyObject, "O&O&", EventHandlerCallRef_New, handlerRef, EventRef_New, event); if (retValue == NULL) { PySys_WriteStderr("Error in event handler callback:\n"); PyErr_Print(); /* this also clears the error */ status = noErr; /* complain? how? */ } else { if (retValue == Py_None) status = noErr; else if (PyInt_Check(retValue)) { status = PyInt_AsLong(retValue); } else status = noErr; /* wrong object type, complain? */ Py_DECREF(retValue); } #if USE_MAC_MP_MULTITHREADING _save = PyEval_SaveThread(); MPExitCriticalRegion(reentrantLock); #endif /* USE_MAC_MP_MULTITHREADING */ return status; } /******** end myEventHandler ***********/ """ initstuff = initstuff + """ PyMac_PRECHECK(NewEventHandlerUPP); /* This can fail if CarbonLib is too old */ myEventHandlerUPP = NewEventHandlerUPP(myEventHandler); """ module = MacModule('_CarbonEvt', 'CarbonEvents', includestuff, finalstuff, initstuff) class EventHandlerRefObjectDefinition(GlobalObjectDefinition): def outputStructMembers(self): Output("%s ob_itself;", self.itselftype) Output("PyObject *ob_callback;") def outputInitStructMembers(self): Output("it->ob_itself = %sitself;", self.argref) Output("it->ob_callback = NULL;") def outputFreeIt(self, name): OutLbrace("if (self->ob_itself != NULL)") Output("RemoveEventHandler(self->ob_itself);") Output("Py_DECREF(self->ob_callback);") OutRbrace() for typ in RefObjectTypes: if typ == 'EventHandlerRef': EventHandlerRefobject = EventHandlerRefObjectDefinition('EventHandlerRef') else: execstr = typ + 'object = GlobalObjectDefinition(typ)' exec execstr module.addobject(eval(typ + 'object')) functions = [] for typ in RefObjectTypes: ## go thru all ObjectTypes as defined in CarbonEventsscan.py # initialize the lists for carbongen to fill execstr = typ + 'methods = []' exec execstr execfile('CarbonEventsgen.py') for f in functions: module.add(f) # add all the functions carboneventsgen put in the list for typ in RefObjectTypes: ## go thru all ObjectTypes as defined in CarbonEventsscan.py methods = eval(typ + 'methods') ## get a reference to the method list from the main namespace obj = eval(typ + 'object') ## get a reference to the object for m in methods: obj.add(m) ## add each method in the list to the object removeeventhandler = """ OSStatus _err; if (_self->ob_itself == NULL) { PyErr_SetString(CarbonEvents_Error, "Handler has been removed"); return NULL; } if (!PyArg_ParseTuple(_args, "")) return NULL; _err = RemoveEventHandler(_self->ob_itself); if (_err != noErr) return PyMac_Error(_err); _self->ob_itself = NULL; Py_DECREF(_self->ob_callback); _self->ob_callback = NULL; Py_INCREF(Py_None); _res = Py_None; return _res;""" f = ManualGenerator("RemoveEventHandler", removeeventhandler); f.docstring = lambda: "() -> None" EventHandlerRefobject.add(f) installeventhandler = """ EventTypeSpec inSpec; PyObject *callback; EventHandlerRef outRef; OSStatus _err; if (!PyArg_ParseTuple(_args, "O&O", EventTypeSpec_Convert, &inSpec, &callback)) return NULL; _err = InstallEventHandler(_self->ob_itself, myEventHandlerUPP, 1, &inSpec, (void *)callback, &outRef); if (_err != noErr) return PyMac_Error(_err); _res = EventHandlerRef_New(outRef); if (_res != NULL) { ((EventHandlerRefObject*)_res)->ob_callback = callback; Py_INCREF(callback); } return _res;""" f = ManualGenerator("InstallEventHandler", installeventhandler); f.docstring = lambda: "(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)" EventTargetRefobject.add(f) # This may not be the best, but at least it lets you get the raw data back into python as a string. You'll have to cut it up yourself and parse the result. geteventparameter = """ UInt32 bufferSize; EventParamName inName; EventParamType inType; OSErr _err; void * buffer; if (!PyArg_ParseTuple(_args, "O&O&", PyMac_GetOSType, &inName, PyMac_GetOSType, &inType)) return NULL; /* Figure out the size by passing a null buffer to GetEventParameter */ _err = GetEventParameter(_self->ob_itself, inName, inType, NULL, 0, &bufferSize, NULL); if (_err != noErr) return PyMac_Error(_err); buffer = PyMem_NEW(char, bufferSize); if (buffer == NULL) return PyErr_NoMemory(); _err = GetEventParameter(_self->ob_itself, inName, inType, NULL, bufferSize, NULL, buffer); if (_err != noErr) { PyMem_DEL(buffer); return PyMac_Error(_err); } _res = Py_BuildValue("s#", buffer, bufferSize); PyMem_DEL(buffer); return _res; """ f = ManualGenerator("GetEventParameter", geteventparameter); f.docstring = lambda: "(EventParamName eventName, EventParamType eventType) -> (String eventParamData)" EventRefobject.add(f) runappeventloop = """ #if USE_MAC_MP_MULTITHREADING if (MPCreateCriticalRegion(&reentrantLock) != noErr) { PySys_WriteStderr("lock failure\\n"); return NULL; } _save = PyEval_SaveThread(); #endif /* USE_MAC_MP_MULTITHREADING */ RunApplicationEventLoop(); #if USE_MAC_MP_MULTITHREADING PyEval_RestoreThread(_save); MPDeleteCriticalRegion(reentrantLock); #endif /* USE_MAC_MP_MULTITHREADING */ Py_INCREF(Py_None); return Py_None; """ f = ManualGenerator("RunApplicationEventLoop", runappeventloop); f.docstring = lambda: "() -> ()" module.add(f) SetOutputFileName('_CarbonEvtmodule.c') module.generate() ##import os ##os.system("python setup.py build")