1 | # IBCarbonsupport.py
|
---|
2 |
|
---|
3 | from macsupport import *
|
---|
4 |
|
---|
5 | from CarbonEvtscan import RefObjectTypes
|
---|
6 |
|
---|
7 | # where should this go? macsupport.py?
|
---|
8 | CFStringRef = OpaqueByValueType('CFStringRef')
|
---|
9 |
|
---|
10 | for typ in RefObjectTypes:
|
---|
11 | execstr = "%(name)s = OpaqueByValueType('%(name)s')" % {"name": typ}
|
---|
12 | exec execstr
|
---|
13 |
|
---|
14 |
|
---|
15 | if 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 |
|
---|
29 | EventHotKeyID = OpaqueByValueType("EventHotKeyID", "EventHotKeyID")
|
---|
30 | EventTypeSpec_ptr = OpaqueType("EventTypeSpec", "EventTypeSpec")
|
---|
31 |
|
---|
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
|
---|
36 |
|
---|
37 | class MyVarInputBufferType(VarInputBufferType):
|
---|
38 | def passInput(self, name):
|
---|
39 | return "%s__len__, %s__in__" % (name, name)
|
---|
40 |
|
---|
41 | MyInBuffer = MyVarInputBufferType('char', 'long', 'l') # (buf, len)
|
---|
42 |
|
---|
43 | EventTime = double
|
---|
44 | EventTimeout = EventTime
|
---|
45 | EventTimerInterval = EventTime
|
---|
46 | EventAttributes = UInt32
|
---|
47 | EventParamName = OSType
|
---|
48 | EventParamType = OSType
|
---|
49 | EventPriority = SInt16
|
---|
50 | EventMask = UInt16
|
---|
51 |
|
---|
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")
|
---|
59 |
|
---|
60 | CarbonEventsFunction = OSErrFunctionGenerator
|
---|
61 | CarbonEventsMethod = OSErrMethodGenerator
|
---|
62 |
|
---|
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()
|
---|
69 |
|
---|
70 |
|
---|
71 | RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
|
---|
72 | GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
|
---|
73 | MouseTrackingResult = UInt16
|
---|
74 |
|
---|
75 |
|
---|
76 | includestuff = includestuff + r"""
|
---|
77 | #include <Carbon/Carbon.h>
|
---|
78 |
|
---|
79 | extern int CFStringRef_New(CFStringRef *);
|
---|
80 |
|
---|
81 | extern int CFStringRef_Convert(PyObject *, CFStringRef *);
|
---|
82 | extern int CFBundleRef_Convert(PyObject *, CFBundleRef *);
|
---|
83 |
|
---|
84 | int EventTargetRef_Convert(PyObject *, EventTargetRef *);
|
---|
85 | PyObject *EventHandlerCallRef_New(EventHandlerCallRef itself);
|
---|
86 | PyObject *EventRef_New(EventRef itself);
|
---|
87 |
|
---|
88 | /********** EventTypeSpec *******/
|
---|
89 | static PyObject*
|
---|
90 | EventTypeSpec_New(EventTypeSpec *in)
|
---|
91 | {
|
---|
92 | return Py_BuildValue("ll", in->eventClass, in->eventKind);
|
---|
93 | }
|
---|
94 |
|
---|
95 | static int
|
---|
96 | EventTypeSpec_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 */
|
---|
110 | static PyObject*
|
---|
111 | HIPoint_New(HIPoint *in)
|
---|
112 | {
|
---|
113 | return Py_BuildValue("ff", in->x, in->y);
|
---|
114 | }
|
---|
115 |
|
---|
116 | static int
|
---|
117 | HIPoint_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 |
|
---|
129 | static PyObject*
|
---|
130 | EventHotKeyID_New(EventHotKeyID *in)
|
---|
131 | {
|
---|
132 | return Py_BuildValue("ll", in->signature, in->id);
|
---|
133 | }
|
---|
134 |
|
---|
135 | static int
|
---|
136 | EventHotKeyID_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 |
|
---|
147 | static EventHandlerUPP myEventHandlerUPP;
|
---|
148 |
|
---|
149 | static pascal OSStatus
|
---|
150 | myEventHandler(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 |
|
---|
178 | initstuff = initstuff + """
|
---|
179 | myEventHandlerUPP = NewEventHandlerUPP(myEventHandler);
|
---|
180 | """
|
---|
181 | module = MacModule('_CarbonEvt', 'CarbonEvents', includestuff, finalstuff, initstuff)
|
---|
182 |
|
---|
183 |
|
---|
184 |
|
---|
185 |
|
---|
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()
|
---|
198 |
|
---|
199 | class MyGlobalObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
|
---|
200 | pass
|
---|
201 |
|
---|
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'))
|
---|
209 |
|
---|
210 |
|
---|
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
|
---|
216 |
|
---|
217 | execfile('CarbonEventsgen.py')
|
---|
218 |
|
---|
219 |
|
---|
220 |
|
---|
221 | for f in functions: module.add(f) # add all the functions carboneventsgen put in the list
|
---|
222 |
|
---|
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
|
---|
227 |
|
---|
228 |
|
---|
229 | removeeventhandler = """
|
---|
230 | OSStatus _err;
|
---|
231 | if (_self->ob_itself == NULL) {
|
---|
232 | PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
|
---|
233 | return NULL;
|
---|
234 | }
|
---|
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;"""
|
---|
245 |
|
---|
246 | f = ManualGenerator("RemoveEventHandler", removeeventhandler);
|
---|
247 | f.docstring = lambda: "() -> None"
|
---|
248 | EventHandlerRefobject.add(f)
|
---|
249 |
|
---|
250 |
|
---|
251 | installeventhandler = """
|
---|
252 | EventTypeSpec inSpec;
|
---|
253 | PyObject *callback;
|
---|
254 | EventHandlerRef outRef;
|
---|
255 | OSStatus _err;
|
---|
256 |
|
---|
257 | if (!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);
|
---|
261 | if (_err != noErr) return PyMac_Error(_err);
|
---|
262 |
|
---|
263 | _res = EventHandlerRef_New(outRef);
|
---|
264 | if (_res != NULL) {
|
---|
265 | ((EventHandlerRefObject*)_res)->ob_callback = callback;
|
---|
266 | Py_INCREF(callback);
|
---|
267 | }
|
---|
268 | return _res;"""
|
---|
269 |
|
---|
270 | f = ManualGenerator("InstallEventHandler", installeventhandler);
|
---|
271 | f.docstring = lambda: "(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"
|
---|
272 | EventTargetRefobject.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 |
|
---|
276 | geteventparameter = """
|
---|
277 | UInt32 bufferSize;
|
---|
278 | EventParamName inName;
|
---|
279 | EventParamType inType;
|
---|
280 | OSErr _err;
|
---|
281 | void * buffer;
|
---|
282 |
|
---|
283 | if (!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 |
|
---|
289 | if (_err != noErr)
|
---|
290 | return PyMac_Error(_err);
|
---|
291 | buffer = PyMem_NEW(char, bufferSize);
|
---|
292 | if (buffer == NULL)
|
---|
293 | return PyErr_NoMemory();
|
---|
294 |
|
---|
295 | _err = GetEventParameter(_self->ob_itself, inName, inType, NULL, bufferSize, NULL, buffer);
|
---|
296 |
|
---|
297 | if (_err != noErr) {
|
---|
298 | PyMem_DEL(buffer);
|
---|
299 | return PyMac_Error(_err);
|
---|
300 | }
|
---|
301 | _res = Py_BuildValue("s#", buffer, bufferSize);
|
---|
302 | PyMem_DEL(buffer);
|
---|
303 | return _res;
|
---|
304 | """
|
---|
305 |
|
---|
306 | f = ManualGenerator("GetEventParameter", geteventparameter);
|
---|
307 | f.docstring = lambda: "(EventParamName eventName, EventParamType eventType) -> (String eventParamData)"
|
---|
308 | EventRefobject.add(f)
|
---|
309 |
|
---|
310 | SetOutputFileName('_CarbonEvtmodule.c')
|
---|
311 | module.generate()
|
---|
312 |
|
---|
313 | ##import os
|
---|
314 | ##os.system("python setup.py build")
|
---|