This commit was manufactured by cvs2svn to create tag
[python/dscho.git] / Mac / Modules / carbonevt / CarbonEvtsupport.py
blob0ce2af8b10fb2df2c11b33995183cec1279b9949
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 EventTime = double
38 EventTimeout = EventTime
39 EventTimerInterval = EventTime
40 EventAttributes = UInt32
41 EventParamName = OSType
42 EventParamType = OSType
43 EventPriority = SInt16
44 EventMask = UInt16
46 EventComparatorUPP = FakeType("(EventComparatorUPP)0")
47 EventLoopTimerUPP = FakeType("(EventLoopTimerUPP)0")
48 EventHandlerUPP = FakeType("(EventHandlerUPP)0")
49 EventHandlerUPP = FakeType("(EventHandlerUPP)0")
50 EventComparatorProcPtr = FakeType("(EventComparatorProcPtr)0")
51 EventLoopTimerProcPtr = FakeType("(EventLoopTimerProcPtr)0")
52 EventHandlerProcPtr = FakeType("(EventHandlerProcPtr)0")
54 CarbonEventsFunction = OSErrFunctionGenerator
55 CarbonEventsMethod = OSErrMethodGenerator
57 class EventHandlerRefMethod(OSErrMethodGenerator):
58 def precheck(self):
59 OutLbrace('if (_self->ob_itself == NULL)')
60 Output('PyErr_SetString(CarbonEvents_Error, "Handler has been removed");')
61 Output('return NULL;')
62 OutRbrace()
65 includestuff = r"""
66 #ifdef WITHOUT_FRAMEWORKS
67 #include <CarbonEvents.h>
68 #else
69 #include <Carbon/Carbon.h>
70 #endif
72 #include "macglue.h"
74 /* Macro to test whether a weak-loaded CFM function exists */
75 #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\
76 PyErr_SetString(PyExc_NotImplementedError, \
77 "Not available in this shared library/OS version"); \
78 return; \
79 }} while(0)
82 #define USE_MAC_MP_MULTITHREADING 0
84 #if USE_MAC_MP_MULTITHREADING
85 static PyThreadState *_save;
86 static MPCriticalRegionID reentrantLock;
87 #endif /* USE_MAC_MP_MULTITHREADING */
89 extern int CFStringRef_New(CFStringRef *);
91 extern int CFStringRef_Convert(PyObject *, CFStringRef *);
92 extern int CFBundleRef_Convert(PyObject *, CFBundleRef *);
94 int EventTargetRef_Convert(PyObject *, EventTargetRef *);
95 PyObject *EventHandlerCallRef_New(EventHandlerCallRef itself);
96 PyObject *EventRef_New(EventRef itself);
98 /********** EventTypeSpec *******/
99 static PyObject*
100 EventTypeSpec_New(EventTypeSpec *in)
102 return Py_BuildValue("ll", in->eventClass, in->eventKind);
105 static int
106 EventTypeSpec_Convert(PyObject *v, EventTypeSpec *out)
108 if (PyArg_Parse(v, "(O&l)",
109 PyMac_GetOSType, &(out->eventClass),
110 &(out->eventKind)))
111 return 1;
112 return NULL;
115 /********** end EventTypeSpec *******/
117 /********** HIPoint *******/
119 #if 0 /* XXX doesn't compile */
120 static PyObject*
121 HIPoint_New(HIPoint *in)
123 return Py_BuildValue("ff", in->x, in->y);
126 static int
127 HIPoint_Convert(PyObject *v, HIPoint *out)
129 if (PyArg_ParseTuple(v, "ff", &(out->x), &(out->y)))
130 return 1;
131 return NULL;
133 #endif
135 /********** end HIPoint *******/
137 /********** EventHotKeyID *******/
139 static PyObject*
140 EventHotKeyID_New(EventHotKeyID *in)
142 return Py_BuildValue("ll", in->signature, in->id);
145 static int
146 EventHotKeyID_Convert(PyObject *v, EventHotKeyID *out)
148 if (PyArg_ParseTuple(v, "ll", &out->signature, &out->id))
149 return 1;
150 return NULL;
153 /********** end EventHotKeyID *******/
155 /******** myEventHandler ***********/
157 static EventHandlerUPP myEventHandlerUPP;
159 static pascal OSStatus
160 myEventHandler(EventHandlerCallRef handlerRef, EventRef event, void *outPyObject) {
161 PyObject *retValue;
162 int status;
164 #if USE_MAC_MP_MULTITHREADING
165 MPEnterCriticalRegion(reentrantLock, kDurationForever);
166 PyEval_RestoreThread(_save);
167 #endif /* USE_MAC_MP_MULTITHREADING */
169 retValue = PyObject_CallFunction((PyObject *)outPyObject, "O&O&",
170 EventHandlerCallRef_New, handlerRef,
171 EventRef_New, event);
172 if (retValue == NULL) {
173 PySys_WriteStderr("Error in event handler callback:\n");
174 PyErr_Print(); /* this also clears the error */
175 status = noErr; /* complain? how? */
176 } else {
177 if (retValue == Py_None)
178 status = noErr;
179 else if (PyInt_Check(retValue)) {
180 status = PyInt_AsLong(retValue);
181 } else
182 status = noErr; /* wrong object type, complain? */
183 Py_DECREF(retValue);
186 #if USE_MAC_MP_MULTITHREADING
187 _save = PyEval_SaveThread();
188 MPExitCriticalRegion(reentrantLock);
189 #endif /* USE_MAC_MP_MULTITHREADING */
191 return status;
194 /******** end myEventHandler ***********/
198 initstuff = initstuff + """
199 PyMac_PRECHECK(NewEventHandlerUPP); /* This can fail if CarbonLib is too old */
200 myEventHandlerUPP = NewEventHandlerUPP(myEventHandler);
202 module = MacModule('_CarbonEvt', 'CarbonEvents', includestuff, finalstuff, initstuff)
207 class EventHandlerRefObjectDefinition(GlobalObjectDefinition):
208 def outputStructMembers(self):
209 Output("%s ob_itself;", self.itselftype)
210 Output("PyObject *ob_callback;")
211 def outputInitStructMembers(self):
212 Output("it->ob_itself = %sitself;", self.argref)
213 Output("it->ob_callback = NULL;")
214 def outputFreeIt(self, name):
215 OutLbrace("if (self->ob_itself != NULL)")
216 Output("RemoveEventHandler(self->ob_itself);")
217 Output("Py_DECREF(self->ob_callback);")
218 OutRbrace()
220 for typ in RefObjectTypes:
221 if typ == 'EventHandlerRef':
222 EventHandlerRefobject = EventHandlerRefObjectDefinition('EventHandlerRef')
223 else:
224 execstr = typ + 'object = GlobalObjectDefinition(typ)'
225 exec execstr
226 module.addobject(eval(typ + 'object'))
229 functions = []
230 for typ in RefObjectTypes: ## go thru all ObjectTypes as defined in CarbonEventsscan.py
231 # initialize the lists for carbongen to fill
232 execstr = typ + 'methods = []'
233 exec execstr
235 execfile('CarbonEventsgen.py')
239 for f in functions: module.add(f) # add all the functions carboneventsgen put in the list
241 for typ in RefObjectTypes: ## go thru all ObjectTypes as defined in CarbonEventsscan.py
242 methods = eval(typ + 'methods') ## get a reference to the method list from the main namespace
243 obj = eval(typ + 'object') ## get a reference to the object
244 for m in methods: obj.add(m) ## add each method in the list to the object
247 removeeventhandler = """
248 OSStatus _err;
249 if (_self->ob_itself == NULL) {
250 PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
251 return NULL;
253 if (!PyArg_ParseTuple(_args, ""))
254 return NULL;
255 _err = RemoveEventHandler(_self->ob_itself);
256 if (_err != noErr) return PyMac_Error(_err);
257 _self->ob_itself = NULL;
258 Py_DECREF(_self->ob_callback);
259 _self->ob_callback = NULL;
260 Py_INCREF(Py_None);
261 _res = Py_None;
262 return _res;"""
264 f = ManualGenerator("RemoveEventHandler", removeeventhandler);
265 f.docstring = lambda: "() -> None"
266 EventHandlerRefobject.add(f)
269 installeventhandler = """
270 EventTypeSpec inSpec;
271 PyObject *callback;
272 EventHandlerRef outRef;
273 OSStatus _err;
275 if (!PyArg_ParseTuple(_args, "O&O", EventTypeSpec_Convert, &inSpec, &callback))
276 return NULL;
278 _err = InstallEventHandler(_self->ob_itself, myEventHandlerUPP, 1, &inSpec, (void *)callback, &outRef);
279 if (_err != noErr) return PyMac_Error(_err);
281 _res = EventHandlerRef_New(outRef);
282 if (_res != NULL) {
283 ((EventHandlerRefObject*)_res)->ob_callback = callback;
284 Py_INCREF(callback);
286 return _res;"""
288 f = ManualGenerator("InstallEventHandler", installeventhandler);
289 f.docstring = lambda: "(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"
290 EventTargetRefobject.add(f)
292 # 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.
294 geteventparameter = """
295 UInt32 bufferSize;
296 EventParamName inName;
297 EventParamType inType;
298 OSErr _err;
299 void * buffer;
301 if (!PyArg_ParseTuple(_args, "O&O&", PyMac_GetOSType, &inName, PyMac_GetOSType, &inType))
302 return NULL;
304 /* Figure out the size by passing a null buffer to GetEventParameter */
305 _err = GetEventParameter(_self->ob_itself, inName, inType, NULL, 0, &bufferSize, NULL);
307 if (_err != noErr)
308 return PyMac_Error(_err);
309 buffer = PyMem_NEW(char, bufferSize);
310 if (buffer == NULL)
311 return PyErr_NoMemory();
313 _err = GetEventParameter(_self->ob_itself, inName, inType, NULL, bufferSize, NULL, buffer);
315 if (_err != noErr) {
316 PyMem_DEL(buffer);
317 return PyMac_Error(_err);
319 _res = Py_BuildValue("s#", buffer, bufferSize);
320 PyMem_DEL(buffer);
321 return _res;
324 f = ManualGenerator("GetEventParameter", geteventparameter);
325 f.docstring = lambda: "(EventParamName eventName, EventParamType eventType) -> (String eventParamData)"
326 EventRefobject.add(f)
328 runappeventloop = """
329 #if USE_MAC_MP_MULTITHREADING
330 if (MPCreateCriticalRegion(&reentrantLock) != noErr) {
331 PySys_WriteStderr("lock failure\\n");
332 return NULL;
334 _save = PyEval_SaveThread();
335 #endif /* USE_MAC_MP_MULTITHREADING */
337 RunApplicationEventLoop();
339 #if USE_MAC_MP_MULTITHREADING
340 PyEval_RestoreThread(_save);
342 MPDeleteCriticalRegion(reentrantLock);
343 #endif /* USE_MAC_MP_MULTITHREADING */
345 Py_INCREF(Py_None);
347 return Py_None;
348 """
350 f = ManualGenerator("RunApplicationEventLoop", runappeventloop);
351 f.docstring = lambda: "() -> ()"
352 module.add(f)
354 SetOutputFileName('_CarbonEvtmodule.c')
355 module.generate()
357 ##import os
358 ##os.system("python setup.py build")