Add better error reporting for MemoryErrors caused by str->float conversions.
[python.git] / Mac / Modules / carbonevt / CarbonEvtsupport.py
blob77d12b62990b0a616db78e643f9feb5e8d9f853f
1 # IBCarbonsupport.py
3 from macsupport import *
5 from CarbonEvtscan import RefObjectTypes
7 # where should this go? macsupport.py?
8 CFStringRef = OpaqueByValueType('CFStringRef')
10 for typ in RefObjectTypes:
11 execstr = "%(name)s = OpaqueByValueType('%(name)s')" % {"name": typ}
12 exec execstr
15 if 0:
16 # these types will have no methods and will merely be opaque blobs
17 # should write getattr and setattr for them?
19 StructObjectTypes = ["EventTypeSpec",
20 "HIPoint",
21 "HICommand",
22 "EventHotKeyID",
25 for typ in StructObjectTypes:
26 execstr = "%(name)s = OpaqueType('%(name)s')" % {"name": typ}
27 exec execstr
29 EventHotKeyID = OpaqueByValueType("EventHotKeyID", "EventHotKeyID")
30 EventTypeSpec_ptr = OpaqueType("EventTypeSpec", "EventTypeSpec")
32 # is this the right type for the void * in GetEventParameter
33 #void_ptr = FixedInputBufferType(1024)
34 void_ptr = stringptr
35 # here are some types that are really other types
37 class MyVarInputBufferType(VarInputBufferType):
38 def passInput(self, name):
39 return "%s__len__, %s__in__" % (name, name)
41 MyInBuffer = MyVarInputBufferType('char', 'long', 'l') # (buf, len)
43 EventTime = double
44 EventTimeout = EventTime
45 EventTimerInterval = EventTime
46 EventAttributes = UInt32
47 EventParamName = OSType
48 EventParamType = OSType
49 EventPriority = SInt16
50 EventMask = UInt16
52 EventComparatorUPP = FakeType("(EventComparatorUPP)0")
53 EventLoopTimerUPP = FakeType("(EventLoopTimerUPP)0")
54 EventHandlerUPP = FakeType("(EventHandlerUPP)0")
55 EventHandlerUPP = FakeType("(EventHandlerUPP)0")
56 EventComparatorProcPtr = FakeType("(EventComparatorProcPtr)0")
57 EventLoopTimerProcPtr = FakeType("(EventLoopTimerProcPtr)0")
58 EventHandlerProcPtr = FakeType("(EventHandlerProcPtr)0")
60 CarbonEventsFunction = OSErrFunctionGenerator
61 CarbonEventsMethod = OSErrMethodGenerator
63 class 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()
71 RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
72 GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
73 MouseTrackingResult = UInt16
76 includestuff = includestuff + r"""
77 #include <Carbon/Carbon.h>
79 extern int CFStringRef_New(CFStringRef *);
81 extern int CFStringRef_Convert(PyObject *, CFStringRef *);
82 extern int CFBundleRef_Convert(PyObject *, CFBundleRef *);
84 int EventTargetRef_Convert(PyObject *, EventTargetRef *);
85 PyObject *EventHandlerCallRef_New(EventHandlerCallRef itself);
86 PyObject *EventRef_New(EventRef itself);
88 /********** EventTypeSpec *******/
89 static PyObject*
90 EventTypeSpec_New(EventTypeSpec *in)
92 return Py_BuildValue("ll", in->eventClass, in->eventKind);
95 static int
96 EventTypeSpec_Convert(PyObject *v, EventTypeSpec *out)
98 if (PyArg_Parse(v, "(O&l)",
99 PyMac_GetOSType, &(out->eventClass),
100 &(out->eventKind)))
101 return 1;
102 return NULL;
105 /********** end EventTypeSpec *******/
107 /********** HIPoint *******/
109 #if 0 /* XXX doesn't compile */
110 static PyObject*
111 HIPoint_New(HIPoint *in)
113 return Py_BuildValue("ff", in->x, in->y);
116 static int
117 HIPoint_Convert(PyObject *v, HIPoint *out)
119 if (PyArg_ParseTuple(v, "ff", &(out->x), &(out->y)))
120 return 1;
121 return NULL;
123 #endif
125 /********** end HIPoint *******/
127 /********** EventHotKeyID *******/
129 static PyObject*
130 EventHotKeyID_New(EventHotKeyID *in)
132 return Py_BuildValue("ll", in->signature, in->id);
135 static int
136 EventHotKeyID_Convert(PyObject *v, EventHotKeyID *out)
138 if (PyArg_ParseTuple(v, "ll", &out->signature, &out->id))
139 return 1;
140 return NULL;
143 /********** end EventHotKeyID *******/
145 /******** myEventHandler ***********/
147 static EventHandlerUPP myEventHandlerUPP;
149 static pascal OSStatus
150 myEventHandler(EventHandlerCallRef handlerRef, EventRef event, void *outPyObject) {
151 PyObject *retValue;
152 int status;
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);
171 return status;
174 /******** end myEventHandler ***********/
178 initstuff = initstuff + """
179 myEventHandlerUPP = NewEventHandlerUPP(myEventHandler);
181 module = MacModule('_CarbonEvt', 'CarbonEvents', includestuff, finalstuff, initstuff)
186 class 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()
199 class MyGlobalObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
200 pass
202 for 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'))
211 functions = []
212 for 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
217 execfile('CarbonEventsgen.py')
221 for f in functions: module.add(f) # add all the functions carboneventsgen put in the list
223 for 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
229 removeeventhandler = """
230 OSStatus _err;
231 if (_self->ob_itself == NULL) {
232 PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
233 return NULL;
235 if (!PyArg_ParseTuple(_args, ""))
236 return NULL;
237 _err = RemoveEventHandler(_self->ob_itself);
238 if (_err != noErr) return PyMac_Error(_err);
239 _self->ob_itself = NULL;
240 Py_DECREF(_self->ob_callback);
241 _self->ob_callback = NULL;
242 Py_INCREF(Py_None);
243 _res = Py_None;
244 return _res;"""
246 f = ManualGenerator("RemoveEventHandler", removeeventhandler);
247 f.docstring = lambda: "() -> None"
248 EventHandlerRefobject.add(f)
251 installeventhandler = """
252 EventTypeSpec inSpec;
253 PyObject *callback;
254 EventHandlerRef outRef;
255 OSStatus _err;
257 if (!PyArg_ParseTuple(_args, "O&O", EventTypeSpec_Convert, &inSpec, &callback))
258 return NULL;
260 _err = InstallEventHandler(_self->ob_itself, myEventHandlerUPP, 1, &inSpec, (void *)callback, &outRef);
261 if (_err != noErr) return PyMac_Error(_err);
263 _res = EventHandlerRef_New(outRef);
264 if (_res != NULL) {
265 ((EventHandlerRefObject*)_res)->ob_callback = callback;
266 Py_INCREF(callback);
268 return _res;"""
270 f = ManualGenerator("InstallEventHandler", installeventhandler);
271 f.docstring = lambda: "(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"
272 EventTargetRefobject.add(f)
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.
276 geteventparameter = """
277 UInt32 bufferSize;
278 EventParamName inName;
279 EventParamType inType;
280 OSErr _err;
281 void * buffer;
283 if (!PyArg_ParseTuple(_args, "O&O&", PyMac_GetOSType, &inName, PyMac_GetOSType, &inType))
284 return NULL;
286 /* Figure out the size by passing a null buffer to GetEventParameter */
287 _err = GetEventParameter(_self->ob_itself, inName, inType, NULL, 0, &bufferSize, NULL);
289 if (_err != noErr)
290 return PyMac_Error(_err);
291 buffer = PyMem_NEW(char, bufferSize);
292 if (buffer == NULL)
293 return PyErr_NoMemory();
295 _err = GetEventParameter(_self->ob_itself, inName, inType, NULL, bufferSize, NULL, buffer);
297 if (_err != noErr) {
298 PyMem_DEL(buffer);
299 return PyMac_Error(_err);
301 _res = Py_BuildValue("s#", buffer, bufferSize);
302 PyMem_DEL(buffer);
303 return _res;
306 f = ManualGenerator("GetEventParameter", geteventparameter);
307 f.docstring = lambda: "(EventParamName eventName, EventParamType eventType) -> (String eventParamData)"
308 EventRefobject.add(f)
310 SetOutputFileName('_CarbonEvtmodule.c')
311 module.generate()
313 ##import os
314 ##os.system("python setup.py build")