PageRenderTime 34ms CodeModel.GetById 19ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Mac/Modules/carbonevt/CarbonEvtsupport.py

http://unladen-swallow.googlecode.com/
Python | 314 lines | 285 code | 20 blank | 9 comment | 5 complexity | fa1c6beb09bdd6d645c54a6c9d544f28 MD5 | raw file
  1# IBCarbonsupport.py
  2
  3from macsupport import *
  4
  5from CarbonEvtscan import RefObjectTypes
  6
  7# where should this go? macsupport.py?
  8CFStringRef = OpaqueByValueType('CFStringRef')
  9
 10for typ in RefObjectTypes:
 11    execstr = "%(name)s = OpaqueByValueType('%(name)s')" % {"name": typ}
 12    exec execstr
 13
 14
 15if 0:
 16    # these types will have no methods and will merely be opaque blobs
 17    # should write getattr and setattr for them?
 18
 19    StructObjectTypes = ["EventTypeSpec",
 20                                            "HIPoint",
 21                                            "HICommand",
 22                                            "EventHotKeyID",
 23                                            ]
 24
 25    for typ in StructObjectTypes:
 26        execstr = "%(name)s = OpaqueType('%(name)s')" % {"name": typ}
 27        exec execstr
 28
 29EventHotKeyID = OpaqueByValueType("EventHotKeyID", "EventHotKeyID")
 30EventTypeSpec_ptr = OpaqueType("EventTypeSpec", "EventTypeSpec")
 31
 32# is this the right type for the void * in GetEventParameter
 33#void_ptr = FixedInputBufferType(1024)
 34void_ptr = stringptr
 35# here are some types that are really other types
 36
 37class MyVarInputBufferType(VarInputBufferType):
 38    def passInput(self, name):
 39        return "%s__len__, %s__in__" % (name, name)
 40
 41MyInBuffer = MyVarInputBufferType('char', 'long', 'l')          # (buf, len)
 42
 43EventTime = double
 44EventTimeout = EventTime
 45EventTimerInterval = EventTime
 46EventAttributes = UInt32
 47EventParamName = OSType
 48EventParamType = OSType
 49EventPriority = SInt16
 50EventMask = UInt16
 51
 52EventComparatorUPP = FakeType("(EventComparatorUPP)0")
 53EventLoopTimerUPP = FakeType("(EventLoopTimerUPP)0")
 54EventHandlerUPP = FakeType("(EventHandlerUPP)0")
 55EventHandlerUPP = FakeType("(EventHandlerUPP)0")
 56EventComparatorProcPtr = FakeType("(EventComparatorProcPtr)0")
 57EventLoopTimerProcPtr = FakeType("(EventLoopTimerProcPtr)0")
 58EventHandlerProcPtr = FakeType("(EventHandlerProcPtr)0")
 59
 60CarbonEventsFunction = OSErrFunctionGenerator
 61CarbonEventsMethod = OSErrMethodGenerator
 62
 63class EventHandlerRefMethod(OSErrMethodGenerator):
 64    def precheck(self):
 65        OutLbrace('if (_self->ob_itself == NULL)')
 66        Output('PyErr_SetString(CarbonEvents_Error, "Handler has been removed");')
 67        Output('return NULL;')
 68        OutRbrace()
 69
 70
 71RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
 72GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
 73MouseTrackingResult = UInt16
 74
 75
 76includestuff = includestuff + r"""
 77#include <Carbon/Carbon.h>
 78
 79extern int CFStringRef_New(CFStringRef *);
 80
 81extern int CFStringRef_Convert(PyObject *, CFStringRef *);
 82extern int CFBundleRef_Convert(PyObject *, CFBundleRef *);
 83
 84int EventTargetRef_Convert(PyObject *, EventTargetRef *);
 85PyObject *EventHandlerCallRef_New(EventHandlerCallRef itself);
 86PyObject *EventRef_New(EventRef itself);
 87
 88/********** EventTypeSpec *******/
 89static PyObject*
 90EventTypeSpec_New(EventTypeSpec *in)
 91{
 92        return Py_BuildValue("ll", in->eventClass, in->eventKind);
 93}
 94
 95static int
 96EventTypeSpec_Convert(PyObject *v, EventTypeSpec *out)
 97{
 98        if (PyArg_Parse(v, "(O&l)",
 99                        PyMac_GetOSType, &(out->eventClass),
100                        &(out->eventKind)))
101                return 1;
102        return NULL;
103}
104
105/********** end EventTypeSpec *******/
106
107/********** HIPoint *******/
108
109#if 0  /* XXX doesn't compile */
110static PyObject*
111HIPoint_New(HIPoint *in)
112{
113        return Py_BuildValue("ff", in->x, in->y);
114}
115
116static int
117HIPoint_Convert(PyObject *v, HIPoint *out)
118{
119        if (PyArg_ParseTuple(v, "ff", &(out->x), &(out->y)))
120                return 1;
121        return NULL;
122}
123#endif
124
125/********** end HIPoint *******/
126
127/********** EventHotKeyID *******/
128
129static PyObject*
130EventHotKeyID_New(EventHotKeyID *in)
131{
132        return Py_BuildValue("ll", in->signature, in->id);
133}
134
135static int
136EventHotKeyID_Convert(PyObject *v, EventHotKeyID *out)
137{
138        if (PyArg_ParseTuple(v, "ll", &out->signature, &out->id))
139                return 1;
140        return NULL;
141}
142
143/********** end EventHotKeyID *******/
144
145/******** myEventHandler ***********/
146
147static EventHandlerUPP myEventHandlerUPP;
148
149static pascal OSStatus
150myEventHandler(EventHandlerCallRef handlerRef, EventRef event, void *outPyObject) {
151        PyObject *retValue;
152        int status;
153
154        retValue = PyObject_CallFunction((PyObject *)outPyObject, "O&O&",
155                                         EventHandlerCallRef_New, handlerRef,
156                                         EventRef_New, event);
157        if (retValue == NULL) {
158                PySys_WriteStderr("Error in event handler callback:\n");
159                PyErr_Print();  /* this also clears the error */
160                status = noErr; /* complain? how? */
161        } else {
162                if (retValue == Py_None)
163                        status = noErr;
164                else if (PyInt_Check(retValue)) {
165                        status = PyInt_AsLong(retValue);
166                } else
167                        status = noErr; /* wrong object type, complain? */
168                Py_DECREF(retValue);
169        }
170
171        return status;
172}
173
174/******** end myEventHandler ***********/
175
176"""
177
178initstuff = initstuff + """
179myEventHandlerUPP = NewEventHandlerUPP(myEventHandler);
180"""
181module = MacModule('_CarbonEvt', 'CarbonEvents', includestuff, finalstuff, initstuff)
182
183
184
185
186class EventHandlerRefObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
187    def outputStructMembers(self):
188        Output("%s ob_itself;", self.itselftype)
189        Output("PyObject *ob_callback;")
190    def outputInitStructMembers(self):
191        Output("it->ob_itself = %sitself;", self.argref)
192        Output("it->ob_callback = NULL;")
193    def outputFreeIt(self, name):
194        OutLbrace("if (self->ob_itself != NULL)")
195        Output("RemoveEventHandler(self->ob_itself);")
196        Output("Py_DECREF(self->ob_callback);")
197        OutRbrace()
198
199class MyGlobalObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
200    pass
201
202for typ in RefObjectTypes:
203    if typ == 'EventHandlerRef':
204        EventHandlerRefobject = EventHandlerRefObjectDefinition('EventHandlerRef')
205    else:
206        execstr = typ + 'object = MyGlobalObjectDefinition(typ)'
207        exec execstr
208    module.addobject(eval(typ + 'object'))
209
210
211functions = []
212for typ in RefObjectTypes: ## go thru all ObjectTypes as defined in CarbonEventsscan.py
213    # initialize the lists for carbongen to fill
214    execstr = typ + 'methods = []'
215    exec execstr
216
217execfile('CarbonEventsgen.py')
218
219
220
221for f in functions: module.add(f)       # add all the functions carboneventsgen put in the list
222
223for typ in RefObjectTypes:                               ## go thru all ObjectTypes as defined in CarbonEventsscan.py
224    methods = eval(typ + 'methods')  ## get a reference to the method list from the main namespace
225    obj = eval(typ + 'object')                ## get a reference to the object
226    for m in methods: obj.add(m)    ## add each method in the list to the object
227
228
229removeeventhandler = """
230OSStatus _err;
231if (_self->ob_itself == NULL) {
232        PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
233        return NULL;
234}
235if (!PyArg_ParseTuple(_args, ""))
236        return NULL;
237_err = RemoveEventHandler(_self->ob_itself);
238if (_err != noErr) return PyMac_Error(_err);
239_self->ob_itself = NULL;
240Py_DECREF(_self->ob_callback);
241_self->ob_callback = NULL;
242Py_INCREF(Py_None);
243_res = Py_None;
244return _res;"""
245
246f = ManualGenerator("RemoveEventHandler", removeeventhandler);
247f.docstring = lambda: "() -> None"
248EventHandlerRefobject.add(f)
249
250
251installeventhandler = """
252EventTypeSpec inSpec;
253PyObject *callback;
254EventHandlerRef outRef;
255OSStatus _err;
256
257if (!PyArg_ParseTuple(_args, "O&O", EventTypeSpec_Convert, &inSpec, &callback))
258        return NULL;
259
260_err = InstallEventHandler(_self->ob_itself, myEventHandlerUPP, 1, &inSpec, (void *)callback, &outRef);
261if (_err != noErr) return PyMac_Error(_err);
262
263_res = EventHandlerRef_New(outRef);
264if (_res != NULL) {
265        ((EventHandlerRefObject*)_res)->ob_callback = callback;
266        Py_INCREF(callback);
267}
268return _res;"""
269
270f = ManualGenerator("InstallEventHandler", installeventhandler);
271f.docstring = lambda: "(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"
272EventTargetRefobject.add(f)
273
274# 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.
275
276geteventparameter = """
277UInt32 bufferSize;
278EventParamName inName;
279EventParamType inType;
280OSErr _err;
281void * buffer;
282
283if (!PyArg_ParseTuple(_args, "O&O&", PyMac_GetOSType, &inName, PyMac_GetOSType, &inType))
284      return NULL;
285
286/* Figure out the size by passing a null buffer to GetEventParameter */
287_err = GetEventParameter(_self->ob_itself, inName, inType, NULL, 0, &bufferSize, NULL);
288
289if (_err != noErr)
290      return PyMac_Error(_err);
291buffer = PyMem_NEW(char, bufferSize);
292if (buffer == NULL)
293      return PyErr_NoMemory();
294
295_err = GetEventParameter(_self->ob_itself, inName, inType, NULL, bufferSize, NULL, buffer);
296
297if (_err != noErr) {
298      PyMem_DEL(buffer);
299      return PyMac_Error(_err);
300}
301_res = Py_BuildValue("s#", buffer, bufferSize);
302PyMem_DEL(buffer);
303return _res;
304"""
305
306f = ManualGenerator("GetEventParameter", geteventparameter);
307f.docstring = lambda: "(EventParamName eventName, EventParamType eventType) -> (String eventParamData)"
308EventRefobject.add(f)
309
310SetOutputFileName('_CarbonEvtmodule.c')
311module.generate()
312
313##import os
314##os.system("python setup.py build")