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).
9 addpack
.addpack(':Tools:bgen:bgen')
11 # Declarations that change for each manager
12 MACHEADERFILE
= 'QuickDraw.h' # The Apple header file
13 MODNAME
= 'Qd' # The name of the module
14 OBJECTNAME
= 'Graf' # The basic name of the objects used here
16 # The following is *usually* unchanged but may still require tuning
17 MODPREFIX
= MODNAME
# The prefix for module-wide routines
18 OBJECTTYPE
= OBJECTNAME
+ 'Ptr' # The C type used to represent them
19 OBJECTPREFIX
= MODPREFIX
+ 'Obj' # The prefix for object methods
20 INPUTFILE
= string
.lower(MODPREFIX
) + 'gen.py' # The file generated by the scanner
21 EXTRAFILE
= string
.lower(MODPREFIX
) + 'edit.py' # A similar file but hand-made
22 OUTPUTFILE
= MODNAME
+ "module.c" # The file generated by this program
24 from macsupport
import *
26 # Create the type objects
28 class TextThingieClass(FixedInputBufferType
):
29 def getargsCheck(self
, name
):
32 TextThingie
= TextThingieClass(None)
34 # These are temporary!
35 RgnHandle
= OpaqueByValueType("RgnHandle", "ResObj")
36 OptRgnHandle
= OpaqueByValueType("RgnHandle", "OptResObj")
37 PicHandle
= OpaqueByValueType("PicHandle", "ResObj")
38 PolyHandle
= OpaqueByValueType("PolyHandle", "ResObj")
39 PixMapHandle
= OpaqueByValueType("PixMapHandle", "ResObj")
40 PixPatHandle
= OpaqueByValueType("PixPatHandle", "ResObj")
41 PatHandle
= OpaqueByValueType("PatHandle", "ResObj")
42 CursHandle
= OpaqueByValueType("CursHandle", "ResObj")
43 CGrafPtr
= OpaqueByValueType("CGrafPtr", "GrafObj")
44 GrafPtr
= OpaqueByValueType("GrafPtr", "GrafObj")
45 BitMap_ptr
= OpaqueByValueType("BitMapPtr", "BMObj")
46 RGBColor
= OpaqueType('RGBColor', 'QdRGB')
47 RGBColor_ptr
= RGBColor
48 FontInfo
= OpaqueType('FontInfo', 'QdFI')
50 Cursor_ptr
= StructInputBufferType('Cursor')
51 Pattern
= StructOutputBufferType('Pattern')
52 Pattern_ptr
= StructInputBufferType('Pattern')
53 PenState
= StructOutputBufferType('PenState')
54 PenState_ptr
= StructInputBufferType('PenState')
56 includestuff
= includestuff
+ """
57 #include <%s>""" % MACHEADERFILE
+ """
60 #define resNotFound -192 /* Can't include <Errors.h> because of Python's "errors.h" */
63 ** Parse/generate RGB records
65 PyObject *QdRGB_New(itself)
69 return Py_BuildValue("lll", (long)itself->red, (long)itself->green, (long)itself->blue);
72 QdRGB_Convert(v, p_itself)
76 long red, green, blue;
78 if( !PyArg_ParseTuple(v, "lll", &red, &green, &blue) )
80 p_itself->red = (unsigned short)red;
81 p_itself->green = (unsigned short)green;
82 p_itself->blue = (unsigned short)blue;
87 ** Generate FontInfo records
90 PyObject *QdFI_New(itself)
94 return Py_BuildValue("hhhh", itself->ascent, itself->descent,
95 itself->widMax, itself->leading);
106 if (o == NULL || PyDict_SetItemString(d, "qd", o) != 0)
107 Py_FatalError("can't initialize Qd.qd");
113 ##class Region_ObjectDefinition(GlobalObjectDefinition):
114 ## def outputCheckNewArg(self):
115 ## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
116 ## def outputFreeIt(self, itselfname):
117 ## Output("DisposeRegion(%s);", itselfname)
119 ##class Polygon_ObjectDefinition(GlobalObjectDefinition):
120 ## def outputCheckNewArg(self):
121 ## Output("if (itself == NULL) return PyMac_Error(resNotFound);")
122 ## def outputFreeIt(self, itselfname):
123 ## Output("KillPoly(%s);", itselfname)
125 class MyGRObjectDefinition(GlobalObjectDefinition
):
126 def outputCheckNewArg(self
):
127 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
128 def outputCheckConvertArg(self
):
129 OutLbrace("if (DlgObj_Check(v) || WinObj_Check(v))")
130 Output("*p_itself = ((GrafPortObject *)v)->ob_itself;")
133 def outputGetattrHook(self
):
135 { CGrafPtr itself_color = (CGrafPtr)self->ob_itself;
137 if ( strcmp(name, "data") == 0 )
138 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(GrafPort));
140 if ( (itself_color->portVersion&0xc000) == 0xc000 ) {
141 /* Color-only attributes */
143 if ( strcmp(name, "portBits") == 0 )
144 /* XXXX Do we need HLock() stuff here?? */
145 return BMObj_New((BitMapPtr)*itself_color->portPixMap);
146 if ( strcmp(name, "grafVars") == 0 )
147 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->visRgn);
148 if ( strcmp(name, "chExtra") == 0 )
149 return Py_BuildValue("h", itself_color->chExtra);
150 if ( strcmp(name, "pnLocHFrac") == 0 )
151 return Py_BuildValue("h", itself_color->pnLocHFrac);
152 if ( strcmp(name, "bkPixPat") == 0 )
153 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->bkPixPat);
154 if ( strcmp(name, "rgbFgColor") == 0 )
155 return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbFgColor);
156 if ( strcmp(name, "rgbBkColor") == 0 )
157 return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbBkColor);
158 if ( strcmp(name, "pnPixPat") == 0 )
159 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->pnPixPat);
160 if ( strcmp(name, "fillPixPat") == 0 )
161 return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->fillPixPat);
163 /* Mono-only attributes */
164 if ( strcmp(name, "portBits") == 0 )
165 return BMObj_New(&self->ob_itself->portBits);
166 if ( strcmp(name, "bkPat") == 0 )
167 return Py_BuildValue("s#", (char *)&self->ob_itself->bkPat, sizeof(Pattern));
168 if ( strcmp(name, "fillPat") == 0 )
169 return Py_BuildValue("s#", (char *)&self->ob_itself->fillPat, sizeof(Pattern));
170 if ( strcmp(name, "pnPat") == 0 )
171 return Py_BuildValue("s#", (char *)&self->ob_itself->pnPat, sizeof(Pattern));
174 ** Accessible for both color/mono windows.
175 ** portVersion is really color-only, but we put it here
178 if ( strcmp(name, "portVersion") == 0 )
179 return Py_BuildValue("h", itself_color->portVersion);
180 if ( strcmp(name, "device") == 0 )
181 return PyInt_FromLong((long)self->ob_itself->device);
182 if ( strcmp(name, "portRect") == 0 )
183 return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->portRect);
184 if ( strcmp(name, "visRgn") == 0 )
185 return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->visRgn);
186 if ( strcmp(name, "clipRgn") == 0 )
187 return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->clipRgn);
188 if ( strcmp(name, "pnLoc") == 0 )
189 return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnLoc);
190 if ( strcmp(name, "pnSize") == 0 )
191 return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnSize);
192 if ( strcmp(name, "pnMode") == 0 )
193 return Py_BuildValue("h", self->ob_itself->pnMode);
194 if ( strcmp(name, "pnVis") == 0 )
195 return Py_BuildValue("h", self->ob_itself->pnVis);
196 if ( strcmp(name, "txFont") == 0 )
197 return Py_BuildValue("h", self->ob_itself->txFont);
198 if ( strcmp(name, "txFace") == 0 )
199 return Py_BuildValue("h", (short)self->ob_itself->txFace);
200 if ( strcmp(name, "txMode") == 0 )
201 return Py_BuildValue("h", self->ob_itself->txMode);
202 if ( strcmp(name, "txSize") == 0 )
203 return Py_BuildValue("h", self->ob_itself->txSize);
204 if ( strcmp(name, "spExtra") == 0 )
205 return Py_BuildValue("O&", PyMac_BuildFixed, self->ob_itself->spExtra);
206 /* XXXX Add more, as needed */
207 /* This one is so we can compare grafports: */
208 if ( strcmp(name, "_id") == 0 )
209 return Py_BuildValue("l", (long)self->ob_itself);
212 class MyBMObjectDefinition(GlobalObjectDefinition
):
213 def outputCheckNewArg(self
):
214 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
215 def outputStructMembers(self
):
216 # We need to more items: a pointer to privately allocated data
217 # and a python object we're referring to.
218 Output("%s ob_itself;", self
.itselftype
)
219 Output("PyObject *referred_object;")
220 Output("BitMap *referred_bitmap;")
221 def outputInitStructMembers(self
):
222 Output("it->ob_itself = %sitself;", self
.argref
)
223 Output("it->referred_object = NULL;")
224 Output("it->referred_bitmap = NULL;")
225 def outputCleanupStructMembers(self
):
226 Output("Py_XDECREF(self->referred_object);")
227 Output("if (self->referred_bitmap) free(self->referred_bitmap);")
228 def outputGetattrHook(self
):
229 Output("""if ( strcmp(name, "baseAddr") == 0 )
230 return PyInt_FromLong((long)self->ob_itself->baseAddr);
231 if ( strcmp(name, "rowBytes") == 0 )
232 return PyInt_FromLong((long)self->ob_itself->rowBytes);
233 if ( strcmp(name, "bounds") == 0 )
234 return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->bounds);
235 /* XXXX Add more, as needed */
236 if ( strcmp(name, "bitmap_data") == 0 )
237 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap));
238 if ( strcmp(name, "pixmap_data") == 0 )
239 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap));
242 # This object is instanciated once, and will access qd globals.
243 class QDGlobalsAccessObjectDefinition(ObjectDefinition
):
244 def outputStructMembers(self
):
248 Output("%sPyObject *%s_New()", self
.static
, self
.prefix
)
250 Output("%s *it;", self
.objecttype
)
251 Output("it = PyObject_NEW(%s, &%s);", self
.objecttype
, self
.typename
)
252 Output("if (it == NULL) return NULL;")
253 Output("return (PyObject *)it;")
255 def outputConvert(self
):
257 def outputCleanupStructMembers(self
):
260 def outputGetattrHook(self
):
262 if ( strcmp(name, "arrow") == 0 )
263 return PyString_FromStringAndSize((char *)&qd.arrow, sizeof(qd.arrow));
264 if ( strcmp(name, "black") == 0 )
265 return PyString_FromStringAndSize((char *)&qd.black, sizeof(qd.black));
266 if ( strcmp(name, "white") == 0 )
267 return PyString_FromStringAndSize((char *)&qd.white, sizeof(qd.white));
268 if ( strcmp(name, "gray") == 0 )
269 return PyString_FromStringAndSize((char *)&qd.gray, sizeof(qd.gray));
270 if ( strcmp(name, "ltGray") == 0 )
271 return PyString_FromStringAndSize((char *)&qd.ltGray, sizeof(qd.ltGray));
272 if ( strcmp(name, "dkGray") == 0 )
273 return PyString_FromStringAndSize((char *)&qd.dkGray, sizeof(qd.dkGray));
274 if ( strcmp(name, "screenBits") == 0 )
275 return BMObj_New(&qd.screenBits);
276 if ( strcmp(name, "thePort") == 0 )
277 return GrafObj_New(qd.thePort);
278 if ( strcmp(name, "randSeed") == 0 )
279 return Py_BuildValue("l", &qd.randSeed);
282 # Create the generator groups and link them
283 module
= MacModule(MODNAME
, MODPREFIX
, includestuff
, finalstuff
, initstuff
, variablestuff
)
284 ##r_object = Region_ObjectDefinition('Region', 'QdRgn', 'RgnHandle')
285 ##po_object = Polygon_ObjectDefinition('Polygon', 'QdPgn', 'PolyHandle')
286 ##module.addobject(r_object)
287 ##module.addobject(po_object)
288 gr_object
= MyGRObjectDefinition("GrafPort", "GrafObj", "GrafPtr")
289 module
.addobject(gr_object
)
290 bm_object
= MyBMObjectDefinition("BitMap", "BMObj", "BitMapPtr")
291 module
.addobject(bm_object
)
292 qd_object
= QDGlobalsAccessObjectDefinition("QDGlobalsAccess", "QDGA", "XXXX")
293 module
.addobject(qd_object
)
296 # Create the generator classes used to populate the lists
297 Function
= OSErrFunctionGenerator
298 Method
= OSErrMethodGenerator
300 # Create and populate the lists
306 # add the populated lists to the generator groups
307 # (in a different wordl the scan program would generate this)
308 for f
in functions
: module
.add(f
)
309 ##for f in r_methods: r_object.add(f)
310 ##for f in po_methods: po_object.add(f)
313 # We manually generate a routine to create a BitMap from python data.
322 if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect,
325 data = PyString_AsString(source);
326 if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL )
327 return PyErr_NoMemory();
328 ptr->baseAddr = (Ptr)data;
329 ptr->rowBytes = rowbytes;
330 ptr->bounds = bounds;
331 if ( (_res = BMObj_New(ptr)) == NULL ) {
335 ((BitMapObject *)_res)->referred_object = source;
337 ((BitMapObject *)_res)->referred_bitmap = ptr;
341 f
= ManualGenerator("BitMap", BitMap_body
)
342 f
.docstring
= lambda: """Take (string, int, Rect) argument and create BitMap"""
346 # And again, for turning a correctly-formatted structure into the object
352 if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) )
354 if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) {
358 ptr = (BitMapPtr)PyString_AsString(source);
359 if ( (_res = BMObj_New(ptr)) == NULL ) {
362 ((BitMapObject *)_res)->referred_object = source;
367 f
= ManualGenerator("RawBitMap", RawBitMap_body
)
368 f
.docstring
= lambda: """Take string BitMap and turn into BitMap object"""
371 # generate output (open the output file as late as possible)
372 SetOutputFileName(OUTPUTFILE
)
374 SetOutputFile() # Close it