| # 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() |
| |
| |
| RgnHandle = OpaqueByValueType("RgnHandle", "ResObj") |
| GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj") |
| MouseTrackingResult = UInt16 |
| |
| |
| includestuff = r""" |
| #ifdef WITHOUT_FRAMEWORKS |
| #include <CarbonEvents.h> |
| #else |
| #include <Carbon/Carbon.h> |
| #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(PEP253Mixin, 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() |
| |
| class MyGlobalObjectDefinition(PEP253Mixin, GlobalObjectDefinition): |
| pass |
| |
| for typ in RefObjectTypes: |
| if typ == 'EventHandlerRef': |
| EventHandlerRefobject = EventHandlerRefObjectDefinition('EventHandlerRef') |
| else: |
| execstr = typ + 'object = MyGlobalObjectDefinition(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") |