1 | # This script generates a Python interface for an Apple Macintosh Manager.
|
---|
2 | # It uses the "bgen" package to generate C code.
|
---|
3 | # The function specifications are generated by scanning the mamager's header file,
|
---|
4 | # using the "scantools" package (customized for this particular manager).
|
---|
5 |
|
---|
6 | import string
|
---|
7 |
|
---|
8 | # Declarations that change for each manager
|
---|
9 | MACHEADERFILE = 'QuickDraw.h' # The Apple header file
|
---|
10 | MODNAME = '_Qd' # The name of the module
|
---|
11 | OBJECTNAME = 'Graf' # The basic name of the objects used here
|
---|
12 |
|
---|
13 | # The following is *usually* unchanged but may still require tuning
|
---|
14 | MODPREFIX = 'Qd' # The prefix for module-wide routines
|
---|
15 | OBJECTTYPE = OBJECTNAME + 'Ptr' # The C type used to represent them
|
---|
16 | OBJECTPREFIX = MODPREFIX + 'Obj' # The prefix for object methods
|
---|
17 | INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
|
---|
18 | EXTRAFILE = string.lower(MODPREFIX) + 'edit.py' # A similar file but hand-made
|
---|
19 | OUTPUTFILE = MODNAME + "module.c" # The file generated by this program
|
---|
20 |
|
---|
21 | from macsupport import *
|
---|
22 |
|
---|
23 | # Create the type objects
|
---|
24 |
|
---|
25 | class TextThingieClass(FixedInputBufferType):
|
---|
26 | def getargsCheck(self, name):
|
---|
27 | Output("/* Fool compiler warnings */")
|
---|
28 | Output("%s__in_len__ = %s__in_len__;", name, name)
|
---|
29 |
|
---|
30 | def declareSize(self, name):
|
---|
31 | Output("int %s__in_len__;", name)
|
---|
32 |
|
---|
33 | TextThingie = TextThingieClass(None)
|
---|
34 |
|
---|
35 | # These are temporary!
|
---|
36 | RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
|
---|
37 | OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
|
---|
38 | PicHandle = OpaqueByValueType("PicHandle", "ResObj")
|
---|
39 | PolyHandle = OpaqueByValueType("PolyHandle", "ResObj")
|
---|
40 | PixMapHandle = OpaqueByValueType("PixMapHandle", "ResObj")
|
---|
41 | PixPatHandle = OpaqueByValueType("PixPatHandle", "ResObj")
|
---|
42 | PatHandle = OpaqueByValueType("PatHandle", "ResObj")
|
---|
43 | CursHandle = OpaqueByValueType("CursHandle", "ResObj")
|
---|
44 | CCrsrHandle = OpaqueByValueType("CCrsrHandle", "ResObj")
|
---|
45 | CIconHandle = OpaqueByValueType("CIconHandle", "ResObj")
|
---|
46 | CTabHandle = OpaqueByValueType("CTabHandle", "ResObj")
|
---|
47 | ITabHandle = OpaqueByValueType("ITabHandle", "ResObj")
|
---|
48 | GDHandle = OpaqueByValueType("GDHandle", "ResObj")
|
---|
49 | CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
|
---|
50 | GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
|
---|
51 | BitMap_ptr = OpaqueByValueType("BitMapPtr", "BMObj")
|
---|
52 | const_BitMap_ptr = OpaqueByValueType("const BitMap *", "BMObj")
|
---|
53 | BitMap = OpaqueType("BitMap", "BMObj_NewCopied", "BUG")
|
---|
54 | RGBColor = OpaqueType('RGBColor', 'QdRGB')
|
---|
55 | RGBColor_ptr = RGBColor
|
---|
56 | FontInfo = OpaqueType('FontInfo', 'QdFI')
|
---|
57 | Component = OpaqueByValueType('Component', 'CmpObj')
|
---|
58 | ComponentInstance = OpaqueByValueType('ComponentInstance', 'CmpInstObj')
|
---|
59 |
|
---|
60 | Cursor = StructOutputBufferType('Cursor')
|
---|
61 | Cursor_ptr = StructInputBufferType('Cursor')
|
---|
62 | Pattern = StructOutputBufferType('Pattern')
|
---|
63 | Pattern_ptr = StructInputBufferType('Pattern')
|
---|
64 | PenState = StructOutputBufferType('PenState')
|
---|
65 | PenState_ptr = StructInputBufferType('PenState')
|
---|
66 | TruncCode = Type("TruncCode", "h")
|
---|
67 |
|
---|
68 | includestuff = includestuff + """
|
---|
69 | #include <Carbon/Carbon.h>
|
---|
70 |
|
---|
71 | #ifdef USE_TOOLBOX_OBJECT_GLUE
|
---|
72 | extern PyObject *_GrafObj_New(GrafPtr);
|
---|
73 | extern int _GrafObj_Convert(PyObject *, GrafPtr *);
|
---|
74 | extern PyObject *_BMObj_New(BitMapPtr);
|
---|
75 | extern int _BMObj_Convert(PyObject *, BitMapPtr *);
|
---|
76 | extern PyObject *_QdRGB_New(RGBColorPtr);
|
---|
77 | extern int _QdRGB_Convert(PyObject *, RGBColorPtr);
|
---|
78 |
|
---|
79 | #define GrafObj_New _GrafObj_New
|
---|
80 | #define GrafObj_Convert _GrafObj_Convert
|
---|
81 | #define BMObj_New _BMObj_New
|
---|
82 | #define BMObj_Convert _BMObj_Convert
|
---|
83 | #define QdRGB_New _QdRGB_New
|
---|
84 | #define QdRGB_Convert _QdRGB_Convert
|
---|
85 | #endif
|
---|
86 |
|
---|
87 | static PyObject *BMObj_NewCopied(BitMapPtr);
|
---|
88 |
|
---|
89 | /*
|
---|
90 | ** Parse/generate RGB records
|
---|
91 | */
|
---|
92 | PyObject *QdRGB_New(RGBColorPtr itself)
|
---|
93 | {
|
---|
94 |
|
---|
95 | return Py_BuildValue("lll", (long)itself->red, (long)itself->green, (long)itself->blue);
|
---|
96 | }
|
---|
97 |
|
---|
98 | int QdRGB_Convert(PyObject *v, RGBColorPtr p_itself)
|
---|
99 | {
|
---|
100 | long red, green, blue;
|
---|
101 |
|
---|
102 | if( !PyArg_ParseTuple(v, "lll", &red, &green, &blue) )
|
---|
103 | return 0;
|
---|
104 | p_itself->red = (unsigned short)red;
|
---|
105 | p_itself->green = (unsigned short)green;
|
---|
106 | p_itself->blue = (unsigned short)blue;
|
---|
107 | return 1;
|
---|
108 | }
|
---|
109 |
|
---|
110 | /*
|
---|
111 | ** Generate FontInfo records
|
---|
112 | */
|
---|
113 | static
|
---|
114 | PyObject *QdFI_New(FontInfo *itself)
|
---|
115 | {
|
---|
116 |
|
---|
117 | return Py_BuildValue("hhhh", itself->ascent, itself->descent,
|
---|
118 | itself->widMax, itself->leading);
|
---|
119 | }
|
---|
120 | """
|
---|
121 |
|
---|
122 | finalstuff = finalstuff + """
|
---|
123 | /* Like BMObj_New, but the original bitmap data structure is copied (and
|
---|
124 | ** released when the object is released)
|
---|
125 | */
|
---|
126 | PyObject *BMObj_NewCopied(BitMapPtr itself)
|
---|
127 | {
|
---|
128 | BitMapObject *it;
|
---|
129 | BitMapPtr itself_copy;
|
---|
130 |
|
---|
131 | if ((itself_copy=(BitMapPtr)malloc(sizeof(BitMap))) == NULL)
|
---|
132 | return PyErr_NoMemory();
|
---|
133 | *itself_copy = *itself;
|
---|
134 | it = (BitMapObject *)BMObj_New(itself_copy);
|
---|
135 | it->referred_bitmap = itself_copy;
|
---|
136 | return (PyObject *)it;
|
---|
137 | }
|
---|
138 |
|
---|
139 | """
|
---|
140 |
|
---|
141 | variablestuff = ""
|
---|
142 |
|
---|
143 | initstuff = initstuff + """
|
---|
144 | PyMac_INIT_TOOLBOX_OBJECT_NEW(BitMapPtr, BMObj_New);
|
---|
145 | PyMac_INIT_TOOLBOX_OBJECT_CONVERT(BitMapPtr, BMObj_Convert);
|
---|
146 | PyMac_INIT_TOOLBOX_OBJECT_NEW(GrafPtr, GrafObj_New);
|
---|
147 | PyMac_INIT_TOOLBOX_OBJECT_CONVERT(GrafPtr, GrafObj_Convert);
|
---|
148 | PyMac_INIT_TOOLBOX_OBJECT_NEW(RGBColorPtr, QdRGB_New);
|
---|
149 | PyMac_INIT_TOOLBOX_OBJECT_CONVERT(RGBColor, QdRGB_Convert);
|
---|
150 | """
|
---|
151 |
|
---|
152 | ## not yet...
|
---|
153 | ##
|
---|
154 | ##class Region_ObjectDefinition(GlobalObjectDefinition):
|
---|
155 | ## def outputCheckNewArg(self):
|
---|
156 | ## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
|
---|
157 | ## def outputFreeIt(self, itselfname):
|
---|
158 | ## Output("DisposeRegion(%s);", itselfname)
|
---|
159 | ##
|
---|
160 | ##class Polygon_ObjectDefinition(GlobalObjectDefinition):
|
---|
161 | ## def outputCheckNewArg(self):
|
---|
162 | ## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
|
---|
163 | ## def outputFreeIt(self, itselfname):
|
---|
164 | ## Output("KillPoly(%s);", itselfname)
|
---|
165 |
|
---|
166 | class MyGRObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
|
---|
167 | getsetlist = [
|
---|
168 | ('visRgn',
|
---|
169 | """RgnHandle h=NewRgn(); /* XXXX wrong dispose routine */
|
---|
170 | return Py_BuildValue("O&", ResObj_New, (Handle)GetPortVisibleRegion(self->ob_itself, h));
|
---|
171 | """,
|
---|
172 | None,
|
---|
173 | "Convenience attribute: return a copy of the visible region"
|
---|
174 | ), (
|
---|
175 | 'clipRgn',
|
---|
176 | """RgnHandle h=NewRgn(); /* XXXX wrong dispose routine */
|
---|
177 | return Py_BuildValue("O&", ResObj_New, (Handle)GetPortClipRegion(self->ob_itself, h));
|
---|
178 | """,
|
---|
179 | None,
|
---|
180 | "Convenience attribute: return a copy of the clipping region"
|
---|
181 | )]
|
---|
182 | def outputCheckNewArg(self):
|
---|
183 | Output("if (itself == NULL) return PyMac_Error(resNotFound);")
|
---|
184 | def outputCheckConvertArg(self):
|
---|
185 | Output("#if 1")
|
---|
186 | OutLbrace()
|
---|
187 | Output("WindowRef win;")
|
---|
188 | OutLbrace("if (WinObj_Convert(v, &win) && v)")
|
---|
189 | Output("*p_itself = (GrafPtr)GetWindowPort(win);")
|
---|
190 | Output("return 1;")
|
---|
191 | OutRbrace()
|
---|
192 | Output("PyErr_Clear();")
|
---|
193 | OutRbrace()
|
---|
194 | Output("#else")
|
---|
195 | OutLbrace("if (DlgObj_Check(v))")
|
---|
196 | Output("DialogRef dlg = (DialogRef)((GrafPortObject *)v)->ob_itself;")
|
---|
197 | Output("*p_itself = (GrafPtr)GetWindowPort(GetDialogWindow(dlg));")
|
---|
198 | Output("return 1;")
|
---|
199 | OutRbrace()
|
---|
200 | OutLbrace("if (WinObj_Check(v))")
|
---|
201 | Output("WindowRef win = (WindowRef)((GrafPortObject *)v)->ob_itself;")
|
---|
202 | Output("*p_itself = (GrafPtr)GetWindowPort(win);")
|
---|
203 | Output("return 1;")
|
---|
204 | OutRbrace()
|
---|
205 | Output("#endif")
|
---|
206 |
|
---|
207 | class MyBMObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
|
---|
208 | getsetlist = [
|
---|
209 | (
|
---|
210 | 'baseAddr',
|
---|
211 | 'return PyInt_FromLong((long)self->ob_itself->baseAddr);',
|
---|
212 | None,
|
---|
213 | None
|
---|
214 | ), (
|
---|
215 | 'rowBytes',
|
---|
216 | 'return PyInt_FromLong((long)self->ob_itself->rowBytes);',
|
---|
217 | None,
|
---|
218 | None
|
---|
219 | ), (
|
---|
220 | 'bounds',
|
---|
221 | 'return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->bounds);',
|
---|
222 | None,
|
---|
223 | None
|
---|
224 | ), (
|
---|
225 | 'bitmap_data',
|
---|
226 | 'return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap));',
|
---|
227 | None,
|
---|
228 | None
|
---|
229 | ), (
|
---|
230 | 'pixmap_data',
|
---|
231 | 'return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap));',
|
---|
232 | None,
|
---|
233 | None
|
---|
234 | )]
|
---|
235 | def outputCheckNewArg(self):
|
---|
236 | Output("if (itself == NULL) return PyMac_Error(resNotFound);")
|
---|
237 | def outputStructMembers(self):
|
---|
238 | # We need to more items: a pointer to privately allocated data
|
---|
239 | # and a python object we're referring to.
|
---|
240 | Output("%s ob_itself;", self.itselftype)
|
---|
241 | Output("PyObject *referred_object;")
|
---|
242 | Output("BitMap *referred_bitmap;")
|
---|
243 | def outputInitStructMembers(self):
|
---|
244 | Output("it->ob_itself = %sitself;", self.argref)
|
---|
245 | Output("it->referred_object = NULL;")
|
---|
246 | Output("it->referred_bitmap = NULL;")
|
---|
247 | def outputCleanupStructMembers(self):
|
---|
248 | Output("Py_XDECREF(self->referred_object);")
|
---|
249 | Output("if (self->referred_bitmap) free(self->referred_bitmap);")
|
---|
250 |
|
---|
251 | # Create the generator groups and link them
|
---|
252 | module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
|
---|
253 | ##r_object = Region_ObjectDefinition('Region', 'QdRgn', 'RgnHandle')
|
---|
254 | ##po_object = Polygon_ObjectDefinition('Polygon', 'QdPgn', 'PolyHandle')
|
---|
255 | ##module.addobject(r_object)
|
---|
256 | ##module.addobject(po_object)
|
---|
257 | gr_object = MyGRObjectDefinition("GrafPort", "GrafObj", "GrafPtr")
|
---|
258 | module.addobject(gr_object)
|
---|
259 | bm_object = MyBMObjectDefinition("BitMap", "BMObj", "BitMapPtr")
|
---|
260 | module.addobject(bm_object)
|
---|
261 |
|
---|
262 |
|
---|
263 | # Create the generator classes used to populate the lists
|
---|
264 | Function = OSErrWeakLinkFunctionGenerator
|
---|
265 | Method = OSErrWeakLinkMethodGenerator
|
---|
266 |
|
---|
267 | # Create and populate the lists
|
---|
268 | functions = []
|
---|
269 | gr_methods = []
|
---|
270 | bm_methods = []
|
---|
271 | #methods = []
|
---|
272 | execfile(INPUTFILE)
|
---|
273 | execfile(EXTRAFILE)
|
---|
274 |
|
---|
275 | # add the populated lists to the generator groups
|
---|
276 | # (in a different wordl the scan program would generate this)
|
---|
277 | for f in functions: module.add(f)
|
---|
278 | for f in gr_methods: gr_object.add(f)
|
---|
279 | for f in bm_methods: bm_object.add(f)
|
---|
280 |
|
---|
281 | # Manual generator: get data out of a bitmap
|
---|
282 | getdata_body = """
|
---|
283 | int from, length;
|
---|
284 | char *cp;
|
---|
285 |
|
---|
286 | if ( !PyArg_ParseTuple(_args, "ii", &from, &length) )
|
---|
287 | return NULL;
|
---|
288 | cp = _self->ob_itself->baseAddr+from;
|
---|
289 | _res = PyString_FromStringAndSize(cp, length);
|
---|
290 | return _res;
|
---|
291 | """
|
---|
292 | f = ManualGenerator("getdata", getdata_body)
|
---|
293 | f.docstring = lambda: """(int start, int size) -> string. Return bytes from the bitmap"""
|
---|
294 | bm_object.add(f)
|
---|
295 |
|
---|
296 | # Manual generator: store data in a bitmap
|
---|
297 | putdata_body = """
|
---|
298 | int from, length;
|
---|
299 | char *cp, *icp;
|
---|
300 |
|
---|
301 | if ( !PyArg_ParseTuple(_args, "is#", &from, &icp, &length) )
|
---|
302 | return NULL;
|
---|
303 | cp = _self->ob_itself->baseAddr+from;
|
---|
304 | memcpy(cp, icp, length);
|
---|
305 | Py_INCREF(Py_None);
|
---|
306 | _res = Py_None;
|
---|
307 | return _res;
|
---|
308 | """
|
---|
309 | f = ManualGenerator("putdata", putdata_body)
|
---|
310 | f.docstring = lambda: """(int start, string data). Store bytes into the bitmap"""
|
---|
311 | bm_object.add(f)
|
---|
312 |
|
---|
313 | #
|
---|
314 | # We manually generate a routine to create a BitMap from python data.
|
---|
315 | #
|
---|
316 | BitMap_body = """
|
---|
317 | BitMap *ptr;
|
---|
318 | PyObject *source;
|
---|
319 | Rect bounds;
|
---|
320 | int rowbytes;
|
---|
321 | char *data;
|
---|
322 |
|
---|
323 | if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect,
|
---|
324 | &bounds) )
|
---|
325 | return NULL;
|
---|
326 | data = PyString_AsString(source);
|
---|
327 | if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL )
|
---|
328 | return PyErr_NoMemory();
|
---|
329 | ptr->baseAddr = (Ptr)data;
|
---|
330 | ptr->rowBytes = rowbytes;
|
---|
331 | ptr->bounds = bounds;
|
---|
332 | if ( (_res = BMObj_New(ptr)) == NULL ) {
|
---|
333 | free(ptr);
|
---|
334 | return NULL;
|
---|
335 | }
|
---|
336 | ((BitMapObject *)_res)->referred_object = source;
|
---|
337 | Py_INCREF(source);
|
---|
338 | ((BitMapObject *)_res)->referred_bitmap = ptr;
|
---|
339 | return _res;
|
---|
340 | """
|
---|
341 |
|
---|
342 | f = ManualGenerator("BitMap", BitMap_body)
|
---|
343 | f.docstring = lambda: """Take (string, int, Rect) argument and create BitMap"""
|
---|
344 | module.add(f)
|
---|
345 |
|
---|
346 | #
|
---|
347 | # And again, for turning a correctly-formatted structure into the object
|
---|
348 | #
|
---|
349 | RawBitMap_body = """
|
---|
350 | BitMap *ptr;
|
---|
351 | PyObject *source;
|
---|
352 |
|
---|
353 | if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) )
|
---|
354 | return NULL;
|
---|
355 | if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) {
|
---|
356 | PyErr_Format(PyExc_TypeError,
|
---|
357 | "Argument size was %d, should be %d (sizeof BitMap) or %d (sizeof PixMap)",
|
---|
358 | PyString_Size(source), sizeof(BitMap), sizeof(PixMap));
|
---|
359 | return NULL;
|
---|
360 | }
|
---|
361 | ptr = (BitMapPtr)PyString_AsString(source);
|
---|
362 | if ( (_res = BMObj_New(ptr)) == NULL ) {
|
---|
363 | return NULL;
|
---|
364 | }
|
---|
365 | ((BitMapObject *)_res)->referred_object = source;
|
---|
366 | Py_INCREF(source);
|
---|
367 | return _res;
|
---|
368 | """
|
---|
369 |
|
---|
370 | f = ManualGenerator("RawBitMap", RawBitMap_body)
|
---|
371 | f.docstring = lambda: """Take string BitMap and turn into BitMap object"""
|
---|
372 | module.add(f)
|
---|
373 |
|
---|
374 | # generate output (open the output file as late as possible)
|
---|
375 | SetOutputFileName(OUTPUTFILE)
|
---|
376 | module.generate()
|
---|
377 | SetOutputFile() # Close it
|
---|